blob: 9c35631625f648ec3ea60f0520f2a770e524fd4e [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}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001959void OMPClauseEnqueue::VisitOMPLastprivateClause(
1960 const OMPLastprivateClause *C) {
1961 VisitOMPClauseList(C);
1962}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001963void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001964 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001965}
Alexander Musman8dba6642014-04-22 13:09:42 +00001966void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1967 VisitOMPClauseList(C);
1968 Visitor->AddStmt(C->getStep());
1969}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001970void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1971 VisitOMPClauseList(C);
1972 Visitor->AddStmt(C->getAlignment());
1973}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001974void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1975 VisitOMPClauseList(C);
1976}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001977}
Alexey Bataev756c1962013-09-24 03:17:45 +00001978
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001979void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1980 unsigned size = WL.size();
1981 OMPClauseEnqueue Visitor(this);
1982 Visitor.Visit(S);
1983 if (size == WL.size())
1984 return;
1985 // Now reverse the entries we just added. This will match the DFS
1986 // ordering performed by the worklist.
1987 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1988 std::reverse(I, E);
1989}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001990void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001991 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1992}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 AddDecl(B->getBlockDecl());
1995}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001996void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001997 EnqueueChildren(E);
1998 AddTypeLoc(E->getTypeSourceInfo());
1999}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002000void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2001 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002002 E = S->body_rend(); I != E; ++I) {
2003 AddStmt(*I);
2004 }
2005}
2006void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002007VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002008 AddStmt(S->getSubStmt());
2009 AddDeclarationNameInfo(S);
2010 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2011 AddNestedNameSpecifierLoc(QualifierLoc);
2012}
2013
2014void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002015VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002016 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2017 AddDeclarationNameInfo(E);
2018 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2019 AddNestedNameSpecifierLoc(QualifierLoc);
2020 if (!E->isImplicitAccess())
2021 AddStmt(E->getBase());
2022}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002023void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002024 // Enqueue the initializer , if any.
2025 AddStmt(E->getInitializer());
2026 // Enqueue the array size, if any.
2027 AddStmt(E->getArraySize());
2028 // Enqueue the allocated type.
2029 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2030 // Enqueue the placement arguments.
2031 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2032 AddStmt(E->getPlacementArg(I-1));
2033}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002035 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2036 AddStmt(CE->getArg(I-1));
2037 AddStmt(CE->getCallee());
2038 AddStmt(CE->getArg(0));
2039}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002040void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2041 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002042 // Visit the name of the type being destroyed.
2043 AddTypeLoc(E->getDestroyedTypeInfo());
2044 // Visit the scope type that looks disturbingly like the nested-name-specifier
2045 // but isn't.
2046 AddTypeLoc(E->getScopeTypeInfo());
2047 // Visit the nested-name-specifier.
2048 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2049 AddNestedNameSpecifierLoc(QualifierLoc);
2050 // Visit base expression.
2051 AddStmt(E->getBase());
2052}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2054 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 AddTypeLoc(E->getTypeSourceInfo());
2056}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002057void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2058 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002059 EnqueueChildren(E);
2060 AddTypeLoc(E->getTypeSourceInfo());
2061}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002063 EnqueueChildren(E);
2064 if (E->isTypeOperand())
2065 AddTypeLoc(E->getTypeOperandSourceInfo());
2066}
2067
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2069 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 EnqueueChildren(E);
2071 AddTypeLoc(E->getTypeSourceInfo());
2072}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 EnqueueChildren(E);
2075 if (E->isTypeOperand())
2076 AddTypeLoc(E->getTypeOperandSourceInfo());
2077}
2078
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 EnqueueChildren(S);
2081 AddDecl(S->getExceptionDecl());
2082}
2083
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002084void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002085 if (DR->hasExplicitTemplateArgs()) {
2086 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2087 }
2088 WL.push_back(DeclRefExprParts(DR, Parent));
2089}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002090void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2091 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002092 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2093 AddDeclarationNameInfo(E);
2094 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 unsigned size = WL.size();
2098 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002099 for (const auto *D : S->decls()) {
2100 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 isFirst = false;
2102 }
2103 if (size == WL.size())
2104 return;
2105 // Now reverse the entries we just added. This will match the DFS
2106 // ordering performed by the worklist.
2107 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2108 std::reverse(I, E);
2109}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 D = E->designators_rbegin(), DEnd = E->designators_rend();
2114 D != DEnd; ++D) {
2115 if (D->isFieldDesignator()) {
2116 if (FieldDecl *Field = D->getField())
2117 AddMemberRef(Field, D->getFieldLoc());
2118 continue;
2119 }
2120 if (D->isArrayDesignator()) {
2121 AddStmt(E->getArrayIndex(*D));
2122 continue;
2123 }
2124 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2125 AddStmt(E->getArrayRangeEnd(*D));
2126 AddStmt(E->getArrayRangeStart(*D));
2127 }
2128}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 EnqueueChildren(E);
2131 AddTypeLoc(E->getTypeInfoAsWritten());
2132}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002133void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002134 AddStmt(FS->getBody());
2135 AddStmt(FS->getInc());
2136 AddStmt(FS->getCond());
2137 AddDecl(FS->getConditionVariable());
2138 AddStmt(FS->getInit());
2139}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002141 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2142}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002143void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002144 AddStmt(If->getElse());
2145 AddStmt(If->getThen());
2146 AddStmt(If->getCond());
2147 AddDecl(If->getConditionVariable());
2148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 // We care about the syntactic form of the initializer list, only.
2151 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2152 IE = Syntactic;
2153 EnqueueChildren(IE);
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 WL.push_back(MemberExprParts(M, Parent));
2157
2158 // If the base of the member access expression is an implicit 'this', don't
2159 // visit it.
2160 // FIXME: If we ever want to show these implicit accesses, this will be
2161 // unfortunate. However, clang_getCursor() relies on this behavior.
2162 if (!M->isImplicitAccess())
2163 AddStmt(M->getBase());
2164}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002165void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002166 AddTypeLoc(E->getEncodedTypeSourceInfo());
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 EnqueueChildren(M);
2170 AddTypeLoc(M->getClassReceiverTypeInfo());
2171}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002172void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002173 // Visit the components of the offsetof expression.
2174 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2175 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2176 const OffsetOfNode &Node = E->getComponent(I-1);
2177 switch (Node.getKind()) {
2178 case OffsetOfNode::Array:
2179 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2180 break;
2181 case OffsetOfNode::Field:
2182 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2183 break;
2184 case OffsetOfNode::Identifier:
2185 case OffsetOfNode::Base:
2186 continue;
2187 }
2188 }
2189 // Visit the type into which we're computing the offset.
2190 AddTypeLoc(E->getTypeSourceInfo());
2191}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2194 WL.push_back(OverloadExprParts(E, Parent));
2195}
2196void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 EnqueueChildren(E);
2199 if (E->isArgumentType())
2200 AddTypeLoc(E->getArgumentTypeInfo());
2201}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 EnqueueChildren(S);
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddStmt(S->getBody());
2207 AddStmt(S->getCond());
2208 AddDecl(S->getConditionVariable());
2209}
2210
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 AddStmt(W->getBody());
2213 AddStmt(W->getCond());
2214 AddDecl(W->getConditionVariable());
2215}
2216
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 for (unsigned I = E->getNumArgs(); I > 0; --I)
2219 AddTypeLoc(E->getArg(I-1));
2220}
2221
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 AddTypeLoc(E->getQueriedTypeSourceInfo());
2224}
2225
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 EnqueueChildren(E);
2228}
2229
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 VisitOverloadExpr(U);
2232 if (!U->isImplicitAccess())
2233 AddStmt(U->getBase());
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 AddStmt(E->getSubExpr());
2237 AddTypeLoc(E->getWrittenTypeInfo());
2238}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 WL.push_back(SizeOfPackExprParts(E, Parent));
2241}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 // If the opaque value has a source expression, just transparently
2244 // visit that. This is useful for (e.g.) pseudo-object expressions.
2245 if (Expr *SourceExpr = E->getSourceExpr())
2246 return Visit(SourceExpr);
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 AddStmt(E->getBody());
2250 WL.push_back(LambdaExprParts(E, Parent));
2251}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 // Treat the expression like its syntactic form.
2254 Visit(E->getSyntacticForm());
2255}
2256
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002257void EnqueueVisitor::VisitOMPExecutableDirective(
2258 const OMPExecutableDirective *D) {
2259 EnqueueChildren(D);
2260 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2261 E = D->clauses().end();
2262 I != E; ++I)
2263 EnqueueChildren(*I);
2264}
2265
2266void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2267 VisitOMPExecutableDirective(D);
2268}
2269
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002270void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2271 VisitOMPExecutableDirective(D);
2272}
2273
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2276}
2277
2278bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2279 if (RegionOfInterest.isValid()) {
2280 SourceRange Range = getRawCursorExtent(C);
2281 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2282 return false;
2283 }
2284 return true;
2285}
2286
2287bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2288 while (!WL.empty()) {
2289 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002290 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002291
2292 // Set the Parent field, then back to its old value once we're done.
2293 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2294
2295 switch (LI.getKind()) {
2296 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002298 if (!D)
2299 continue;
2300
2301 // For now, perform default visitation for Decls.
2302 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2303 cast<DeclVisit>(&LI)->isFirst())))
2304 return true;
2305
2306 continue;
2307 }
2308 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2309 const ASTTemplateArgumentListInfo *ArgList =
2310 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2311 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2312 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2313 Arg != ArgEnd; ++Arg) {
2314 if (VisitTemplateArgumentLoc(*Arg))
2315 return true;
2316 }
2317 continue;
2318 }
2319 case VisitorJob::TypeLocVisitKind: {
2320 // Perform default visitation for TypeLocs.
2321 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2322 return true;
2323 continue;
2324 }
2325 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002326 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002327 if (LabelStmt *stmt = LS->getStmt()) {
2328 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2329 TU))) {
2330 return true;
2331 }
2332 }
2333 continue;
2334 }
2335
2336 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2337 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2338 if (VisitNestedNameSpecifierLoc(V->get()))
2339 return true;
2340 continue;
2341 }
2342
2343 case VisitorJob::DeclarationNameInfoVisitKind: {
2344 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2345 ->get()))
2346 return true;
2347 continue;
2348 }
2349 case VisitorJob::MemberRefVisitKind: {
2350 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2351 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2352 return true;
2353 continue;
2354 }
2355 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002356 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002357 if (!S)
2358 continue;
2359
2360 // Update the current cursor.
2361 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2362 if (!IsInRegionOfInterest(Cursor))
2363 continue;
2364 switch (Visitor(Cursor, Parent, ClientData)) {
2365 case CXChildVisit_Break: return true;
2366 case CXChildVisit_Continue: break;
2367 case CXChildVisit_Recurse:
2368 if (PostChildrenVisitor)
2369 WL.push_back(PostChildrenVisit(0, Cursor));
2370 EnqueueWorkList(WL, S);
2371 break;
2372 }
2373 continue;
2374 }
2375 case VisitorJob::MemberExprPartsKind: {
2376 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002377 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002378
2379 // Visit the nested-name-specifier
2380 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2381 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2382 return true;
2383
2384 // Visit the declaration name.
2385 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2386 return true;
2387
2388 // Visit the explicitly-specified template arguments, if any.
2389 if (M->hasExplicitTemplateArgs()) {
2390 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2391 *ArgEnd = Arg + M->getNumTemplateArgs();
2392 Arg != ArgEnd; ++Arg) {
2393 if (VisitTemplateArgumentLoc(*Arg))
2394 return true;
2395 }
2396 }
2397 continue;
2398 }
2399 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002400 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002401 // Visit nested-name-specifier, if present.
2402 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2403 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2404 return true;
2405 // Visit declaration name.
2406 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2407 return true;
2408 continue;
2409 }
2410 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002411 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002412 // Visit the nested-name-specifier.
2413 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2414 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2415 return true;
2416 // Visit the declaration name.
2417 if (VisitDeclarationNameInfo(O->getNameInfo()))
2418 return true;
2419 // Visit the overloaded declaration reference.
2420 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2421 return true;
2422 continue;
2423 }
2424 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 NamedDecl *Pack = E->getPack();
2427 if (isa<TemplateTypeParmDecl>(Pack)) {
2428 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2429 E->getPackLoc(), TU)))
2430 return true;
2431
2432 continue;
2433 }
2434
2435 if (isa<TemplateTemplateParmDecl>(Pack)) {
2436 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2437 E->getPackLoc(), TU)))
2438 return true;
2439
2440 continue;
2441 }
2442
2443 // Non-type template parameter packs and function parameter packs are
2444 // treated like DeclRefExpr cursors.
2445 continue;
2446 }
2447
2448 case VisitorJob::LambdaExprPartsKind: {
2449 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002450 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002451 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2452 CEnd = E->explicit_capture_end();
2453 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002454 // FIXME: Lambda init-captures.
2455 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002457
Guy Benyei11169dd2012-12-18 14:30:41 +00002458 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2459 C->getLocation(),
2460 TU)))
2461 return true;
2462 }
2463
2464 // Visit parameters and return type, if present.
2465 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2466 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2467 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2468 // Visit the whole type.
2469 if (Visit(TL))
2470 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002471 } else if (FunctionProtoTypeLoc Proto =
2472 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002473 if (E->hasExplicitParameters()) {
2474 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002475 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2476 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002477 return true;
2478 } else {
2479 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002480 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002481 return true;
2482 }
2483 }
2484 }
2485 break;
2486 }
2487
2488 case VisitorJob::PostChildrenVisitKind:
2489 if (PostChildrenVisitor(Parent, ClientData))
2490 return true;
2491 break;
2492 }
2493 }
2494 return false;
2495}
2496
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002497bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002498 VisitorWorkList *WL = 0;
2499 if (!WorkListFreeList.empty()) {
2500 WL = WorkListFreeList.back();
2501 WL->clear();
2502 WorkListFreeList.pop_back();
2503 }
2504 else {
2505 WL = new VisitorWorkList();
2506 WorkListCache.push_back(WL);
2507 }
2508 EnqueueWorkList(*WL, S);
2509 bool result = RunVisitorWorkList(*WL);
2510 WorkListFreeList.push_back(WL);
2511 return result;
2512}
2513
2514namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002515typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002516RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2517 const DeclarationNameInfo &NI,
2518 const SourceRange &QLoc,
2519 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2520 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2521 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2522 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2523
2524 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2525
2526 RefNamePieces Pieces;
2527
2528 if (WantQualifier && QLoc.isValid())
2529 Pieces.push_back(QLoc);
2530
2531 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2532 Pieces.push_back(NI.getLoc());
2533
2534 if (WantTemplateArgs && TemplateArgs)
2535 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2536 TemplateArgs->RAngleLoc));
2537
2538 if (Kind == DeclarationName::CXXOperatorName) {
2539 Pieces.push_back(SourceLocation::getFromRawEncoding(
2540 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2541 Pieces.push_back(SourceLocation::getFromRawEncoding(
2542 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2543 }
2544
2545 if (WantSinglePiece) {
2546 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2547 Pieces.clear();
2548 Pieces.push_back(R);
2549 }
2550
2551 return Pieces;
2552}
2553}
2554
2555//===----------------------------------------------------------------------===//
2556// Misc. API hooks.
2557//===----------------------------------------------------------------------===//
2558
2559static llvm::sys::Mutex EnableMultithreadingMutex;
2560static bool EnabledMultithreading;
2561
Chad Rosier05c71aa2013-03-27 18:28:23 +00002562static void fatal_error_handler(void *user_data, const std::string& reason,
2563 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002564 // Write the result out to stderr avoiding errs() because raw_ostreams can
2565 // call report_fatal_error.
2566 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2567 ::abort();
2568}
2569
2570extern "C" {
2571CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2572 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002573 // We use crash recovery to make some of our APIs more reliable, implicitly
2574 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002575 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2576 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002577
2578 // Enable support for multithreading in LLVM.
2579 {
2580 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2581 if (!EnabledMultithreading) {
2582 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2583 llvm::llvm_start_multithreaded();
2584 EnabledMultithreading = true;
2585 }
2586 }
2587
2588 CIndexer *CIdxr = new CIndexer();
2589 if (excludeDeclarationsFromPCH)
2590 CIdxr->setOnlyLocalDecls();
2591 if (displayDiagnostics)
2592 CIdxr->setDisplayDiagnostics();
2593
2594 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2595 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2596 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2597 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2598 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2599 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2600
2601 return CIdxr;
2602}
2603
2604void clang_disposeIndex(CXIndex CIdx) {
2605 if (CIdx)
2606 delete static_cast<CIndexer *>(CIdx);
2607}
2608
2609void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2610 if (CIdx)
2611 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2612}
2613
2614unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2615 if (CIdx)
2616 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2617 return 0;
2618}
2619
2620void clang_toggleCrashRecovery(unsigned isEnabled) {
2621 if (isEnabled)
2622 llvm::CrashRecoveryContext::Enable();
2623 else
2624 llvm::CrashRecoveryContext::Disable();
2625}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002626
Guy Benyei11169dd2012-12-18 14:30:41 +00002627CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2628 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002629 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002630 enum CXErrorCode Result =
2631 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002632 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002633 assert((TU && Result == CXError_Success) ||
2634 (!TU && Result != CXError_Success));
2635 return TU;
2636}
2637
2638enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2639 const char *ast_filename,
2640 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002641 if (out_TU)
2642 *out_TU = NULL;
2643
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002644 if (!CIdx || !ast_filename || !out_TU)
2645 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002646
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002647 LOG_FUNC_SECTION {
2648 *Log << ast_filename;
2649 }
2650
Guy Benyei11169dd2012-12-18 14:30:41 +00002651 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2652 FileSystemOptions FileSystemOpts;
2653
2654 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002655 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002656 CXXIdx->getOnlyLocalDecls(), None,
2657 /*CaptureDiagnostics=*/true,
2658 /*AllowPCHWithCompilerErrors=*/true,
2659 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002660 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2661 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002662}
2663
2664unsigned clang_defaultEditingTranslationUnitOptions() {
2665 return CXTranslationUnit_PrecompiledPreamble |
2666 CXTranslationUnit_CacheCompletionResults;
2667}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002668
Guy Benyei11169dd2012-12-18 14:30:41 +00002669CXTranslationUnit
2670clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2671 const char *source_filename,
2672 int num_command_line_args,
2673 const char * const *command_line_args,
2674 unsigned num_unsaved_files,
2675 struct CXUnsavedFile *unsaved_files) {
2676 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2677 return clang_parseTranslationUnit(CIdx, source_filename,
2678 command_line_args, num_command_line_args,
2679 unsaved_files, num_unsaved_files,
2680 Options);
2681}
2682
2683struct ParseTranslationUnitInfo {
2684 CXIndex CIdx;
2685 const char *source_filename;
2686 const char *const *command_line_args;
2687 int num_command_line_args;
2688 struct CXUnsavedFile *unsaved_files;
2689 unsigned num_unsaved_files;
2690 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002691 CXTranslationUnit *out_TU;
2692 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002693};
2694static void clang_parseTranslationUnit_Impl(void *UserData) {
2695 ParseTranslationUnitInfo *PTUI =
2696 static_cast<ParseTranslationUnitInfo*>(UserData);
2697 CXIndex CIdx = PTUI->CIdx;
2698 const char *source_filename = PTUI->source_filename;
2699 const char * const *command_line_args = PTUI->command_line_args;
2700 int num_command_line_args = PTUI->num_command_line_args;
2701 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2702 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2703 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002704 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002705
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002706 // Set up the initial return values.
2707 if (out_TU)
2708 *out_TU = NULL;
2709 PTUI->result = CXError_Failure;
2710
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002711 // Check arguments.
2712 if (!CIdx || !out_TU ||
2713 (unsaved_files == NULL && num_unsaved_files != 0)) {
2714 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002715 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002716 }
2717
Guy Benyei11169dd2012-12-18 14:30:41 +00002718 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2719
2720 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2721 setThreadBackgroundPriority();
2722
2723 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2724 // FIXME: Add a flag for modules.
2725 TranslationUnitKind TUKind
2726 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002727 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002728 = options & CXTranslationUnit_CacheCompletionResults;
2729 bool IncludeBriefCommentsInCodeCompletion
2730 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2731 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2732 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2733
2734 // Configure the diagnostics.
2735 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002736 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002737
2738 // Recover resources if we crash before exiting this function.
2739 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2740 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2741 DiagCleanup(Diags.getPtr());
2742
Ahmed Charlesb8984322014-03-07 20:03:18 +00002743 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2744 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002745
2746 // Recover resources if we crash before exiting this function.
2747 llvm::CrashRecoveryContextCleanupRegistrar<
2748 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2749
2750 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2751 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2752 const llvm::MemoryBuffer *Buffer
2753 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2754 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2755 Buffer));
2756 }
2757
Ahmed Charlesb8984322014-03-07 20:03:18 +00002758 std::unique_ptr<std::vector<const char *>> Args(
2759 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002760
2761 // Recover resources if we crash before exiting this method.
2762 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2763 ArgsCleanup(Args.get());
2764
2765 // Since the Clang C library is primarily used by batch tools dealing with
2766 // (often very broken) source code, where spell-checking can have a
2767 // significant negative impact on performance (particularly when
2768 // precompiled headers are involved), we disable it by default.
2769 // Only do this if we haven't found a spell-checking-related argument.
2770 bool FoundSpellCheckingArgument = false;
2771 for (int I = 0; I != num_command_line_args; ++I) {
2772 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2773 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2774 FoundSpellCheckingArgument = true;
2775 break;
2776 }
2777 }
2778 if (!FoundSpellCheckingArgument)
2779 Args->push_back("-fno-spell-checking");
2780
2781 Args->insert(Args->end(), command_line_args,
2782 command_line_args + num_command_line_args);
2783
2784 // The 'source_filename' argument is optional. If the caller does not
2785 // specify it then it is assumed that the source file is specified
2786 // in the actual argument list.
2787 // Put the source file after command_line_args otherwise if '-x' flag is
2788 // present it will be unused.
2789 if (source_filename)
2790 Args->push_back(source_filename);
2791
2792 // Do we need the detailed preprocessing record?
2793 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2794 Args->push_back("-Xclang");
2795 Args->push_back("-detailed-preprocessing-record");
2796 }
2797
2798 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002799 std::unique_ptr<ASTUnit> ErrUnit;
2800 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002801 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002802 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2803 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2804 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2805 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2806 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2807 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002808
2809 if (NumErrors != Diags->getClient()->getNumErrors()) {
2810 // Make sure to check that 'Unit' is non-NULL.
2811 if (CXXIdx->getDisplayDiagnostics())
2812 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2813 }
2814
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002815 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2816 PTUI->result = CXError_ASTReadError;
2817 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002818 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002819 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2820 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002821}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002822
2823CXTranslationUnit
2824clang_parseTranslationUnit(CXIndex CIdx,
2825 const char *source_filename,
2826 const char *const *command_line_args,
2827 int num_command_line_args,
2828 struct CXUnsavedFile *unsaved_files,
2829 unsigned num_unsaved_files,
2830 unsigned options) {
2831 CXTranslationUnit TU;
2832 enum CXErrorCode Result = clang_parseTranslationUnit2(
2833 CIdx, source_filename, command_line_args, num_command_line_args,
2834 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002835 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002836 assert((TU && Result == CXError_Success) ||
2837 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002838 return TU;
2839}
2840
2841enum CXErrorCode clang_parseTranslationUnit2(
2842 CXIndex CIdx,
2843 const char *source_filename,
2844 const char *const *command_line_args,
2845 int num_command_line_args,
2846 struct CXUnsavedFile *unsaved_files,
2847 unsigned num_unsaved_files,
2848 unsigned options,
2849 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002850 LOG_FUNC_SECTION {
2851 *Log << source_filename << ": ";
2852 for (int i = 0; i != num_command_line_args; ++i)
2853 *Log << command_line_args[i] << " ";
2854 }
2855
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2857 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002858 num_unsaved_files, options, out_TU,
2859 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002860 llvm::CrashRecoveryContext CRC;
2861
2862 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2863 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2864 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2865 fprintf(stderr, " 'command_line_args' : [");
2866 for (int i = 0; i != num_command_line_args; ++i) {
2867 if (i)
2868 fprintf(stderr, ", ");
2869 fprintf(stderr, "'%s'", command_line_args[i]);
2870 }
2871 fprintf(stderr, "],\n");
2872 fprintf(stderr, " 'unsaved_files' : [");
2873 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2874 if (i)
2875 fprintf(stderr, ", ");
2876 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2877 unsaved_files[i].Length);
2878 }
2879 fprintf(stderr, "],\n");
2880 fprintf(stderr, " 'options' : %d,\n", options);
2881 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002882
2883 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002884 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002885 if (CXTranslationUnit *TU = PTUI.out_TU)
2886 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002887 }
2888
2889 return PTUI.result;
2890}
2891
2892unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2893 return CXSaveTranslationUnit_None;
2894}
2895
2896namespace {
2897
2898struct SaveTranslationUnitInfo {
2899 CXTranslationUnit TU;
2900 const char *FileName;
2901 unsigned options;
2902 CXSaveError result;
2903};
2904
2905}
2906
2907static void clang_saveTranslationUnit_Impl(void *UserData) {
2908 SaveTranslationUnitInfo *STUI =
2909 static_cast<SaveTranslationUnitInfo*>(UserData);
2910
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002911 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002912 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2913 setThreadBackgroundPriority();
2914
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002915 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002916 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2917}
2918
2919int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2920 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002921 LOG_FUNC_SECTION {
2922 *Log << TU << ' ' << FileName;
2923 }
2924
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002925 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002926 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002927 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002928 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002929
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002930 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002931 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2932 if (!CXXUnit->hasSema())
2933 return CXSaveError_InvalidTU;
2934
2935 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2936
2937 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2938 getenv("LIBCLANG_NOTHREADS")) {
2939 clang_saveTranslationUnit_Impl(&STUI);
2940
2941 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2942 PrintLibclangResourceUsage(TU);
2943
2944 return STUI.result;
2945 }
2946
2947 // We have an AST that has invalid nodes due to compiler errors.
2948 // Use a crash recovery thread for protection.
2949
2950 llvm::CrashRecoveryContext CRC;
2951
2952 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2953 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2954 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2955 fprintf(stderr, " 'options' : %d,\n", options);
2956 fprintf(stderr, "}\n");
2957
2958 return CXSaveError_Unknown;
2959
2960 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2961 PrintLibclangResourceUsage(TU);
2962 }
2963
2964 return STUI.result;
2965}
2966
2967void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2968 if (CTUnit) {
2969 // If the translation unit has been marked as unsafe to free, just discard
2970 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002971 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2972 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002973 return;
2974
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002975 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002976 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002977 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2978 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002979 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002980 delete CTUnit;
2981 }
2982}
2983
2984unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2985 return CXReparse_None;
2986}
2987
2988struct ReparseTranslationUnitInfo {
2989 CXTranslationUnit TU;
2990 unsigned num_unsaved_files;
2991 struct CXUnsavedFile *unsaved_files;
2992 unsigned options;
2993 int result;
2994};
2995
2996static void clang_reparseTranslationUnit_Impl(void *UserData) {
2997 ReparseTranslationUnitInfo *RTUI =
2998 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002999 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003000
Guy Benyei11169dd2012-12-18 14:30:41 +00003001 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003002 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3003 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3004 unsigned options = RTUI->options;
3005 (void) options;
3006
3007 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003008 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003009 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003010 RTUI->result = CXError_InvalidArguments;
3011 return;
3012 }
3013 if (unsaved_files == NULL && num_unsaved_files != 0) {
3014 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003015 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003016 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003017
3018 // Reset the associated diagnostics.
3019 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3020 TU->Diagnostics = 0;
3021
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003022 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003023 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3024 setThreadBackgroundPriority();
3025
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003026 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003027 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003028
3029 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3030 new std::vector<ASTUnit::RemappedFile>());
3031
Guy Benyei11169dd2012-12-18 14:30:41 +00003032 // Recover resources if we crash before exiting this function.
3033 llvm::CrashRecoveryContextCleanupRegistrar<
3034 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3035
3036 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3037 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3038 const llvm::MemoryBuffer *Buffer
3039 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3040 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3041 Buffer));
3042 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003043
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003044 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003045 RTUI->result = CXError_Success;
3046 else if (isASTReadError(CXXUnit))
3047 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003048}
3049
3050int clang_reparseTranslationUnit(CXTranslationUnit TU,
3051 unsigned num_unsaved_files,
3052 struct CXUnsavedFile *unsaved_files,
3053 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003054 LOG_FUNC_SECTION {
3055 *Log << TU;
3056 }
3057
Guy Benyei11169dd2012-12-18 14:30:41 +00003058 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003059 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003060
3061 if (getenv("LIBCLANG_NOTHREADS")) {
3062 clang_reparseTranslationUnit_Impl(&RTUI);
3063 return RTUI.result;
3064 }
3065
3066 llvm::CrashRecoveryContext CRC;
3067
3068 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3069 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003070 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003071 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003072 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3073 PrintLibclangResourceUsage(TU);
3074
3075 return RTUI.result;
3076}
3077
3078
3079CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003080 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003081 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003082 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003083 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003084
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003085 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003086 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003087}
3088
3089CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003090 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003091 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003092 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003093 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003094
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003095 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003096 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3097}
3098
3099} // end: extern "C"
3100
3101//===----------------------------------------------------------------------===//
3102// CXFile Operations.
3103//===----------------------------------------------------------------------===//
3104
3105extern "C" {
3106CXString clang_getFileName(CXFile SFile) {
3107 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003108 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003109
3110 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003111 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003112}
3113
3114time_t clang_getFileTime(CXFile SFile) {
3115 if (!SFile)
3116 return 0;
3117
3118 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3119 return FEnt->getModificationTime();
3120}
3121
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003122CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003123 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003124 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003125 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003126 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003127
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003128 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003129
3130 FileManager &FMgr = CXXUnit->getFileManager();
3131 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3132}
3133
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003134unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3135 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003136 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003137 LOG_BAD_TU(TU);
3138 return 0;
3139 }
3140
3141 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003142 return 0;
3143
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003144 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003145 FileEntry *FEnt = static_cast<FileEntry *>(file);
3146 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3147 .isFileMultipleIncludeGuarded(FEnt);
3148}
3149
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003150int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3151 if (!file || !outID)
3152 return 1;
3153
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003154 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003155 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3156 outID->data[0] = ID.getDevice();
3157 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003158 outID->data[2] = FEnt->getModificationTime();
3159 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003160}
3161
Guy Benyei11169dd2012-12-18 14:30:41 +00003162} // end: extern "C"
3163
3164//===----------------------------------------------------------------------===//
3165// CXCursor Operations.
3166//===----------------------------------------------------------------------===//
3167
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003168static const Decl *getDeclFromExpr(const Stmt *E) {
3169 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003170 return getDeclFromExpr(CE->getSubExpr());
3171
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003172 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003174 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003175 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003176 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003178 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 if (PRE->isExplicitProperty())
3180 return PRE->getExplicitProperty();
3181 // It could be messaging both getter and setter as in:
3182 // ++myobj.myprop;
3183 // in which case prefer to associate the setter since it is less obvious
3184 // from inspecting the source that the setter is going to get called.
3185 if (PRE->isMessagingSetter())
3186 return PRE->getImplicitPropertySetter();
3187 return PRE->getImplicitPropertyGetter();
3188 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 if (Expr *Src = OVE->getSourceExpr())
3193 return getDeclFromExpr(Src);
3194
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003195 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 if (!CE->isElidable())
3199 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003200 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 return OME->getMethodDecl();
3202
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003203 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003205 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3207 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003208 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3210 isa<ParmVarDecl>(SizeOfPack->getPack()))
3211 return SizeOfPack->getPack();
3212
3213 return 0;
3214}
3215
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003216static SourceLocation getLocationFromExpr(const Expr *E) {
3217 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 return getLocationFromExpr(CE->getSubExpr());
3219
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003220 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003222 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003224 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003226 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003228 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003230 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003231 return PropRef->getLocation();
3232
3233 return E->getLocStart();
3234}
3235
3236extern "C" {
3237
3238unsigned clang_visitChildren(CXCursor parent,
3239 CXCursorVisitor visitor,
3240 CXClientData client_data) {
3241 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3242 /*VisitPreprocessorLast=*/false);
3243 return CursorVis.VisitChildren(parent);
3244}
3245
3246#ifndef __has_feature
3247#define __has_feature(x) 0
3248#endif
3249#if __has_feature(blocks)
3250typedef enum CXChildVisitResult
3251 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3252
3253static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3254 CXClientData client_data) {
3255 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3256 return block(cursor, parent);
3257}
3258#else
3259// If we are compiled with a compiler that doesn't have native blocks support,
3260// define and call the block manually, so the
3261typedef struct _CXChildVisitResult
3262{
3263 void *isa;
3264 int flags;
3265 int reserved;
3266 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3267 CXCursor);
3268} *CXCursorVisitorBlock;
3269
3270static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3271 CXClientData client_data) {
3272 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3273 return block->invoke(block, cursor, parent);
3274}
3275#endif
3276
3277
3278unsigned clang_visitChildrenWithBlock(CXCursor parent,
3279 CXCursorVisitorBlock block) {
3280 return clang_visitChildren(parent, visitWithBlock, block);
3281}
3282
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003283static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003285 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003287 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003289 if (const ObjCPropertyImplDecl *PropImpl =
3290 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003292 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003293
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003294 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003296 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003298 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 }
3300
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003301 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003302 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003303
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003304 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3306 // and returns different names. NamedDecl returns the class name and
3307 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003308 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003309
3310 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003311 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003312
3313 SmallString<1024> S;
3314 llvm::raw_svector_ostream os(S);
3315 ND->printName(os);
3316
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003317 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003318}
3319
3320CXString clang_getCursorSpelling(CXCursor C) {
3321 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003322 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003323
3324 if (clang_isReference(C.kind)) {
3325 switch (C.kind) {
3326 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003327 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003328 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 }
3330 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003331 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003332 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 }
3334 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003335 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003337 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 }
3339 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003340 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003341 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 }
3343 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003344 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 assert(Type && "Missing type decl");
3346
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003347 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 getAsString());
3349 }
3350 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003351 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 assert(Template && "Missing template decl");
3353
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003354 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 }
3356
3357 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003358 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 assert(NS && "Missing namespace decl");
3360
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003361 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 }
3363
3364 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003365 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 assert(Field && "Missing member decl");
3367
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003368 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 }
3370
3371 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003372 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 assert(Label && "Missing label");
3374
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003375 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 }
3377
3378 case CXCursor_OverloadedDeclRef: {
3379 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003380 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3381 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003382 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003383 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003385 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003386 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 OverloadedTemplateStorage *Ovl
3388 = Storage.get<OverloadedTemplateStorage*>();
3389 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003390 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003391 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 }
3393
3394 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003395 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 assert(Var && "Missing variable decl");
3397
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003398 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 }
3400
3401 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003402 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 }
3404 }
3405
3406 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003407 const Expr *E = getCursorExpr(C);
3408
3409 if (C.kind == CXCursor_ObjCStringLiteral ||
3410 C.kind == CXCursor_StringLiteral) {
3411 const StringLiteral *SLit;
3412 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3413 SLit = OSL->getString();
3414 } else {
3415 SLit = cast<StringLiteral>(E);
3416 }
3417 SmallString<256> Buf;
3418 llvm::raw_svector_ostream OS(Buf);
3419 SLit->outputString(OS);
3420 return cxstring::createDup(OS.str());
3421 }
3422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003423 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 if (D)
3425 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003426 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 }
3428
3429 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003430 const Stmt *S = getCursorStmt(C);
3431 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003432 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003433
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003434 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 }
3436
3437 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003438 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 ->getNameStart());
3440
3441 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003442 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 ->getNameStart());
3444
3445 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003446 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003447
3448 if (clang_isDeclaration(C.kind))
3449 return getDeclSpelling(getCursorDecl(C));
3450
3451 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003452 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003453 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 }
3455
3456 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003457 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003458 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 }
3460
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003461 if (C.kind == CXCursor_PackedAttr) {
3462 return cxstring::createRef("packed");
3463 }
3464
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003465 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003466}
3467
3468CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3469 unsigned pieceIndex,
3470 unsigned options) {
3471 if (clang_Cursor_isNull(C))
3472 return clang_getNullRange();
3473
3474 ASTContext &Ctx = getCursorContext(C);
3475
3476 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003477 const Stmt *S = getCursorStmt(C);
3478 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 if (pieceIndex > 0)
3480 return clang_getNullRange();
3481 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3482 }
3483
3484 return clang_getNullRange();
3485 }
3486
3487 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003488 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3490 if (pieceIndex >= ME->getNumSelectorLocs())
3491 return clang_getNullRange();
3492 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3493 }
3494 }
3495
3496 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3497 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3500 if (pieceIndex >= MD->getNumSelectorLocs())
3501 return clang_getNullRange();
3502 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3503 }
3504 }
3505
3506 if (C.kind == CXCursor_ObjCCategoryDecl ||
3507 C.kind == CXCursor_ObjCCategoryImplDecl) {
3508 if (pieceIndex > 0)
3509 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003510 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3512 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003513 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3515 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3516 }
3517
3518 if (C.kind == CXCursor_ModuleImportDecl) {
3519 if (pieceIndex > 0)
3520 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003521 if (const ImportDecl *ImportD =
3522 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3524 if (!Locs.empty())
3525 return cxloc::translateSourceRange(Ctx,
3526 SourceRange(Locs.front(), Locs.back()));
3527 }
3528 return clang_getNullRange();
3529 }
3530
3531 // FIXME: A CXCursor_InclusionDirective should give the location of the
3532 // filename, but we don't keep track of this.
3533
3534 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3535 // but we don't keep track of this.
3536
3537 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3538 // but we don't keep track of this.
3539
3540 // Default handling, give the location of the cursor.
3541
3542 if (pieceIndex > 0)
3543 return clang_getNullRange();
3544
3545 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3546 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3547 return cxloc::translateSourceRange(Ctx, Loc);
3548}
3549
3550CXString clang_getCursorDisplayName(CXCursor C) {
3551 if (!clang_isDeclaration(C.kind))
3552 return clang_getCursorSpelling(C);
3553
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003554 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003556 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003557
3558 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003559 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 D = FunTmpl->getTemplatedDecl();
3561
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003562 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 SmallString<64> Str;
3564 llvm::raw_svector_ostream OS(Str);
3565 OS << *Function;
3566 if (Function->getPrimaryTemplate())
3567 OS << "<>";
3568 OS << "(";
3569 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3570 if (I)
3571 OS << ", ";
3572 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3573 }
3574
3575 if (Function->isVariadic()) {
3576 if (Function->getNumParams())
3577 OS << ", ";
3578 OS << "...";
3579 }
3580 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003581 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 }
3583
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003584 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 SmallString<64> Str;
3586 llvm::raw_svector_ostream OS(Str);
3587 OS << *ClassTemplate;
3588 OS << "<";
3589 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3590 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3591 if (I)
3592 OS << ", ";
3593
3594 NamedDecl *Param = Params->getParam(I);
3595 if (Param->getIdentifier()) {
3596 OS << Param->getIdentifier()->getName();
3597 continue;
3598 }
3599
3600 // There is no parameter name, which makes this tricky. Try to come up
3601 // with something useful that isn't too long.
3602 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3603 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3604 else if (NonTypeTemplateParmDecl *NTTP
3605 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3606 OS << NTTP->getType().getAsString(Policy);
3607 else
3608 OS << "template<...> class";
3609 }
3610
3611 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003612 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 }
3614
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003615 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3617 // If the type was explicitly written, use that.
3618 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003619 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003620
Benjamin Kramer9170e912013-02-22 15:46:01 +00003621 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 llvm::raw_svector_ostream OS(Str);
3623 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003624 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 ClassSpec->getTemplateArgs().data(),
3626 ClassSpec->getTemplateArgs().size(),
3627 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003628 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 }
3630
3631 return clang_getCursorSpelling(C);
3632}
3633
3634CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3635 switch (Kind) {
3636 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003764 case CXCursor_ObjCSelfExpr:
3765 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003882 case CXCursor_PackedAttr:
3883 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003884 case CXCursor_PureAttr:
3885 return cxstring::createRef("attribute(pure)");
3886 case CXCursor_ConstAttr:
3887 return cxstring::createRef("attribute(const)");
3888 case CXCursor_NoDuplicateAttr:
3889 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003890 case CXCursor_CUDAConstantAttr:
3891 return cxstring::createRef("attribute(constant)");
3892 case CXCursor_CUDADeviceAttr:
3893 return cxstring::createRef("attribute(device)");
3894 case CXCursor_CUDAGlobalAttr:
3895 return cxstring::createRef("attribute(global)");
3896 case CXCursor_CUDAHostAttr:
3897 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003946 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003947 return cxstring::createRef("OMPParallelDirective");
3948 case CXCursor_OMPSimdDirective:
3949 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 }
3951
3952 llvm_unreachable("Unhandled CXCursorKind");
3953}
3954
3955struct GetCursorData {
3956 SourceLocation TokenBeginLoc;
3957 bool PointsAtMacroArgExpansion;
3958 bool VisitedObjCPropertyImplDecl;
3959 SourceLocation VisitedDeclaratorDeclStartLoc;
3960 CXCursor &BestCursor;
3961
3962 GetCursorData(SourceManager &SM,
3963 SourceLocation tokenBegin, CXCursor &outputCursor)
3964 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3965 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3966 VisitedObjCPropertyImplDecl = false;
3967 }
3968};
3969
3970static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3971 CXCursor parent,
3972 CXClientData client_data) {
3973 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3974 CXCursor *BestCursor = &Data->BestCursor;
3975
3976 // If we point inside a macro argument we should provide info of what the
3977 // token is so use the actual cursor, don't replace it with a macro expansion
3978 // cursor.
3979 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3980 return CXChildVisit_Recurse;
3981
3982 if (clang_isDeclaration(cursor.kind)) {
3983 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003984 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3986 if (MD->isImplicit())
3987 return CXChildVisit_Break;
3988
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003989 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3991 // Check that when we have multiple @class references in the same line,
3992 // that later ones do not override the previous ones.
3993 // If we have:
3994 // @class Foo, Bar;
3995 // source ranges for both start at '@', so 'Bar' will end up overriding
3996 // 'Foo' even though the cursor location was at 'Foo'.
3997 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3998 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003999 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4001 if (PrevID != ID &&
4002 !PrevID->isThisDeclarationADefinition() &&
4003 !ID->isThisDeclarationADefinition())
4004 return CXChildVisit_Break;
4005 }
4006
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004007 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4009 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4010 // Check that when we have multiple declarators in the same line,
4011 // that later ones do not override the previous ones.
4012 // If we have:
4013 // int Foo, Bar;
4014 // source ranges for both start at 'int', so 'Bar' will end up overriding
4015 // 'Foo' even though the cursor location was at 'Foo'.
4016 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4017 return CXChildVisit_Break;
4018 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4019
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004020 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4022 (void)PropImp;
4023 // Check that when we have multiple @synthesize in the same line,
4024 // that later ones do not override the previous ones.
4025 // If we have:
4026 // @synthesize Foo, Bar;
4027 // source ranges for both start at '@', so 'Bar' will end up overriding
4028 // 'Foo' even though the cursor location was at 'Foo'.
4029 if (Data->VisitedObjCPropertyImplDecl)
4030 return CXChildVisit_Break;
4031 Data->VisitedObjCPropertyImplDecl = true;
4032 }
4033 }
4034
4035 if (clang_isExpression(cursor.kind) &&
4036 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004037 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 // Avoid having the cursor of an expression replace the declaration cursor
4039 // when the expression source range overlaps the declaration range.
4040 // This can happen for C++ constructor expressions whose range generally
4041 // include the variable declaration, e.g.:
4042 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4043 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4044 D->getLocation() == Data->TokenBeginLoc)
4045 return CXChildVisit_Break;
4046 }
4047 }
4048
4049 // If our current best cursor is the construction of a temporary object,
4050 // don't replace that cursor with a type reference, because we want
4051 // clang_getCursor() to point at the constructor.
4052 if (clang_isExpression(BestCursor->kind) &&
4053 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4054 cursor.kind == CXCursor_TypeRef) {
4055 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4056 // as having the actual point on the type reference.
4057 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4058 return CXChildVisit_Recurse;
4059 }
4060
4061 *BestCursor = cursor;
4062 return CXChildVisit_Recurse;
4063}
4064
4065CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004066 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004067 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004069 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004070
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004071 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4073
4074 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4075 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4076
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004077 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 CXFile SearchFile;
4079 unsigned SearchLine, SearchColumn;
4080 CXFile ResultFile;
4081 unsigned ResultLine, ResultColumn;
4082 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4083 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4084 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4085
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004086 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4087 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 &ResultColumn, 0);
4089 SearchFileName = clang_getFileName(SearchFile);
4090 ResultFileName = clang_getFileName(ResultFile);
4091 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4092 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004093 *Log << llvm::format("(%s:%d:%d) = %s",
4094 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4095 clang_getCString(KindSpelling))
4096 << llvm::format("(%s:%d:%d):%s%s",
4097 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4098 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 clang_disposeString(SearchFileName);
4100 clang_disposeString(ResultFileName);
4101 clang_disposeString(KindSpelling);
4102 clang_disposeString(USR);
4103
4104 CXCursor Definition = clang_getCursorDefinition(Result);
4105 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4106 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4107 CXString DefinitionKindSpelling
4108 = clang_getCursorKindSpelling(Definition.kind);
4109 CXFile DefinitionFile;
4110 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004111 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 &DefinitionLine, &DefinitionColumn, 0);
4113 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004114 *Log << llvm::format(" -> %s(%s:%d:%d)",
4115 clang_getCString(DefinitionKindSpelling),
4116 clang_getCString(DefinitionFileName),
4117 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 clang_disposeString(DefinitionFileName);
4119 clang_disposeString(DefinitionKindSpelling);
4120 }
4121 }
4122
4123 return Result;
4124}
4125
4126CXCursor clang_getNullCursor(void) {
4127 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4128}
4129
4130unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004131 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4132 // can't set consistently. For example, when visiting a DeclStmt we will set
4133 // it but we don't set it on the result of clang_getCursorDefinition for
4134 // a reference of the same declaration.
4135 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4136 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4137 // to provide that kind of info.
4138 if (clang_isDeclaration(X.kind))
4139 X.data[1] = 0;
4140 if (clang_isDeclaration(Y.kind))
4141 Y.data[1] = 0;
4142
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 return X == Y;
4144}
4145
4146unsigned clang_hashCursor(CXCursor C) {
4147 unsigned Index = 0;
4148 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4149 Index = 1;
4150
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004151 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 std::make_pair(C.kind, C.data[Index]));
4153}
4154
4155unsigned clang_isInvalid(enum CXCursorKind K) {
4156 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4157}
4158
4159unsigned clang_isDeclaration(enum CXCursorKind K) {
4160 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4161 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4162}
4163
4164unsigned clang_isReference(enum CXCursorKind K) {
4165 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4166}
4167
4168unsigned clang_isExpression(enum CXCursorKind K) {
4169 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4170}
4171
4172unsigned clang_isStatement(enum CXCursorKind K) {
4173 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4174}
4175
4176unsigned clang_isAttribute(enum CXCursorKind K) {
4177 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4178}
4179
4180unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4181 return K == CXCursor_TranslationUnit;
4182}
4183
4184unsigned clang_isPreprocessing(enum CXCursorKind K) {
4185 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4186}
4187
4188unsigned clang_isUnexposed(enum CXCursorKind K) {
4189 switch (K) {
4190 case CXCursor_UnexposedDecl:
4191 case CXCursor_UnexposedExpr:
4192 case CXCursor_UnexposedStmt:
4193 case CXCursor_UnexposedAttr:
4194 return true;
4195 default:
4196 return false;
4197 }
4198}
4199
4200CXCursorKind clang_getCursorKind(CXCursor C) {
4201 return C.kind;
4202}
4203
4204CXSourceLocation clang_getCursorLocation(CXCursor C) {
4205 if (clang_isReference(C.kind)) {
4206 switch (C.kind) {
4207 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004208 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 = getCursorObjCSuperClassRef(C);
4210 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4211 }
4212
4213 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004214 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 = getCursorObjCProtocolRef(C);
4216 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4217 }
4218
4219 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004220 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 = getCursorObjCClassRef(C);
4222 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4223 }
4224
4225 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004226 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4228 }
4229
4230 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004231 std::pair<const TemplateDecl *, SourceLocation> P =
4232 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4234 }
4235
4236 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004237 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4239 }
4240
4241 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004242 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4244 }
4245
4246 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004247 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4249 }
4250
4251 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004252 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 if (!BaseSpec)
4254 return clang_getNullLocation();
4255
4256 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4257 return cxloc::translateSourceLocation(getCursorContext(C),
4258 TSInfo->getTypeLoc().getBeginLoc());
4259
4260 return cxloc::translateSourceLocation(getCursorContext(C),
4261 BaseSpec->getLocStart());
4262 }
4263
4264 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004265 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4267 }
4268
4269 case CXCursor_OverloadedDeclRef:
4270 return cxloc::translateSourceLocation(getCursorContext(C),
4271 getCursorOverloadedDeclRef(C).second);
4272
4273 default:
4274 // FIXME: Need a way to enumerate all non-reference cases.
4275 llvm_unreachable("Missed a reference kind");
4276 }
4277 }
4278
4279 if (clang_isExpression(C.kind))
4280 return cxloc::translateSourceLocation(getCursorContext(C),
4281 getLocationFromExpr(getCursorExpr(C)));
4282
4283 if (clang_isStatement(C.kind))
4284 return cxloc::translateSourceLocation(getCursorContext(C),
4285 getCursorStmt(C)->getLocStart());
4286
4287 if (C.kind == CXCursor_PreprocessingDirective) {
4288 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4289 return cxloc::translateSourceLocation(getCursorContext(C), L);
4290 }
4291
4292 if (C.kind == CXCursor_MacroExpansion) {
4293 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004294 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 return cxloc::translateSourceLocation(getCursorContext(C), L);
4296 }
4297
4298 if (C.kind == CXCursor_MacroDefinition) {
4299 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4300 return cxloc::translateSourceLocation(getCursorContext(C), L);
4301 }
4302
4303 if (C.kind == CXCursor_InclusionDirective) {
4304 SourceLocation L
4305 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4306 return cxloc::translateSourceLocation(getCursorContext(C), L);
4307 }
4308
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004309 if (clang_isAttribute(C.kind)) {
4310 SourceLocation L
4311 = cxcursor::getCursorAttr(C)->getLocation();
4312 return cxloc::translateSourceLocation(getCursorContext(C), L);
4313 }
4314
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 if (!clang_isDeclaration(C.kind))
4316 return clang_getNullLocation();
4317
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004318 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004319 if (!D)
4320 return clang_getNullLocation();
4321
4322 SourceLocation Loc = D->getLocation();
4323 // FIXME: Multiple variables declared in a single declaration
4324 // currently lack the information needed to correctly determine their
4325 // ranges when accounting for the type-specifier. We use context
4326 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4327 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004328 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004329 if (!cxcursor::isFirstInDeclGroup(C))
4330 Loc = VD->getLocation();
4331 }
4332
4333 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004334 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004335 Loc = MD->getSelectorStartLoc();
4336
4337 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4338}
4339
4340} // end extern "C"
4341
4342CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4343 assert(TU);
4344
4345 // Guard against an invalid SourceLocation, or we may assert in one
4346 // of the following calls.
4347 if (SLoc.isInvalid())
4348 return clang_getNullCursor();
4349
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004350 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004351
4352 // Translate the given source location to make it point at the beginning of
4353 // the token under the cursor.
4354 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4355 CXXUnit->getASTContext().getLangOpts());
4356
4357 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4358 if (SLoc.isValid()) {
4359 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4360 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4361 /*VisitPreprocessorLast=*/true,
4362 /*VisitIncludedEntities=*/false,
4363 SourceLocation(SLoc));
4364 CursorVis.visitFileRegion();
4365 }
4366
4367 return Result;
4368}
4369
4370static SourceRange getRawCursorExtent(CXCursor C) {
4371 if (clang_isReference(C.kind)) {
4372 switch (C.kind) {
4373 case CXCursor_ObjCSuperClassRef:
4374 return getCursorObjCSuperClassRef(C).second;
4375
4376 case CXCursor_ObjCProtocolRef:
4377 return getCursorObjCProtocolRef(C).second;
4378
4379 case CXCursor_ObjCClassRef:
4380 return getCursorObjCClassRef(C).second;
4381
4382 case CXCursor_TypeRef:
4383 return getCursorTypeRef(C).second;
4384
4385 case CXCursor_TemplateRef:
4386 return getCursorTemplateRef(C).second;
4387
4388 case CXCursor_NamespaceRef:
4389 return getCursorNamespaceRef(C).second;
4390
4391 case CXCursor_MemberRef:
4392 return getCursorMemberRef(C).second;
4393
4394 case CXCursor_CXXBaseSpecifier:
4395 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4396
4397 case CXCursor_LabelRef:
4398 return getCursorLabelRef(C).second;
4399
4400 case CXCursor_OverloadedDeclRef:
4401 return getCursorOverloadedDeclRef(C).second;
4402
4403 case CXCursor_VariableRef:
4404 return getCursorVariableRef(C).second;
4405
4406 default:
4407 // FIXME: Need a way to enumerate all non-reference cases.
4408 llvm_unreachable("Missed a reference kind");
4409 }
4410 }
4411
4412 if (clang_isExpression(C.kind))
4413 return getCursorExpr(C)->getSourceRange();
4414
4415 if (clang_isStatement(C.kind))
4416 return getCursorStmt(C)->getSourceRange();
4417
4418 if (clang_isAttribute(C.kind))
4419 return getCursorAttr(C)->getRange();
4420
4421 if (C.kind == CXCursor_PreprocessingDirective)
4422 return cxcursor::getCursorPreprocessingDirective(C);
4423
4424 if (C.kind == CXCursor_MacroExpansion) {
4425 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004426 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004427 return TU->mapRangeFromPreamble(Range);
4428 }
4429
4430 if (C.kind == CXCursor_MacroDefinition) {
4431 ASTUnit *TU = getCursorASTUnit(C);
4432 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4433 return TU->mapRangeFromPreamble(Range);
4434 }
4435
4436 if (C.kind == CXCursor_InclusionDirective) {
4437 ASTUnit *TU = getCursorASTUnit(C);
4438 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4439 return TU->mapRangeFromPreamble(Range);
4440 }
4441
4442 if (C.kind == CXCursor_TranslationUnit) {
4443 ASTUnit *TU = getCursorASTUnit(C);
4444 FileID MainID = TU->getSourceManager().getMainFileID();
4445 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4446 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4447 return SourceRange(Start, End);
4448 }
4449
4450 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004451 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 if (!D)
4453 return SourceRange();
4454
4455 SourceRange R = D->getSourceRange();
4456 // FIXME: Multiple variables declared in a single declaration
4457 // currently lack the information needed to correctly determine their
4458 // ranges when accounting for the type-specifier. We use context
4459 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4460 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004461 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004462 if (!cxcursor::isFirstInDeclGroup(C))
4463 R.setBegin(VD->getLocation());
4464 }
4465 return R;
4466 }
4467 return SourceRange();
4468}
4469
4470/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4471/// the decl-specifier-seq for declarations.
4472static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4473 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004474 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004475 if (!D)
4476 return SourceRange();
4477
4478 SourceRange R = D->getSourceRange();
4479
4480 // Adjust the start of the location for declarations preceded by
4481 // declaration specifiers.
4482 SourceLocation StartLoc;
4483 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4484 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4485 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004486 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4488 StartLoc = TI->getTypeLoc().getLocStart();
4489 }
4490
4491 if (StartLoc.isValid() && R.getBegin().isValid() &&
4492 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4493 R.setBegin(StartLoc);
4494
4495 // FIXME: Multiple variables declared in a single declaration
4496 // currently lack the information needed to correctly determine their
4497 // ranges when accounting for the type-specifier. We use context
4498 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4499 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004500 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 if (!cxcursor::isFirstInDeclGroup(C))
4502 R.setBegin(VD->getLocation());
4503 }
4504
4505 return R;
4506 }
4507
4508 return getRawCursorExtent(C);
4509}
4510
4511extern "C" {
4512
4513CXSourceRange clang_getCursorExtent(CXCursor C) {
4514 SourceRange R = getRawCursorExtent(C);
4515 if (R.isInvalid())
4516 return clang_getNullRange();
4517
4518 return cxloc::translateSourceRange(getCursorContext(C), R);
4519}
4520
4521CXCursor clang_getCursorReferenced(CXCursor C) {
4522 if (clang_isInvalid(C.kind))
4523 return clang_getNullCursor();
4524
4525 CXTranslationUnit tu = getCursorTU(C);
4526 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004527 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 if (!D)
4529 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004530 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004532 if (const ObjCPropertyImplDecl *PropImpl =
4533 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4535 return MakeCXCursor(Property, tu);
4536
4537 return C;
4538 }
4539
4540 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004541 const Expr *E = getCursorExpr(C);
4542 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 if (D) {
4544 CXCursor declCursor = MakeCXCursor(D, tu);
4545 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4546 declCursor);
4547 return declCursor;
4548 }
4549
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004550 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 return MakeCursorOverloadedDeclRef(Ovl, tu);
4552
4553 return clang_getNullCursor();
4554 }
4555
4556 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004557 const Stmt *S = getCursorStmt(C);
4558 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 if (LabelDecl *label = Goto->getLabel())
4560 if (LabelStmt *labelS = label->getStmt())
4561 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4562
4563 return clang_getNullCursor();
4564 }
4565
4566 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004567 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 return MakeMacroDefinitionCursor(Def, tu);
4569 }
4570
4571 if (!clang_isReference(C.kind))
4572 return clang_getNullCursor();
4573
4574 switch (C.kind) {
4575 case CXCursor_ObjCSuperClassRef:
4576 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4577
4578 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004579 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4580 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 return MakeCXCursor(Def, tu);
4582
4583 return MakeCXCursor(Prot, tu);
4584 }
4585
4586 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004587 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4588 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 return MakeCXCursor(Def, tu);
4590
4591 return MakeCXCursor(Class, tu);
4592 }
4593
4594 case CXCursor_TypeRef:
4595 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4596
4597 case CXCursor_TemplateRef:
4598 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4599
4600 case CXCursor_NamespaceRef:
4601 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4602
4603 case CXCursor_MemberRef:
4604 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4605
4606 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004607 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4609 tu ));
4610 }
4611
4612 case CXCursor_LabelRef:
4613 // FIXME: We end up faking the "parent" declaration here because we
4614 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004615 return MakeCXCursor(getCursorLabelRef(C).first,
4616 cxtu::getASTUnit(tu)->getASTContext()
4617 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 tu);
4619
4620 case CXCursor_OverloadedDeclRef:
4621 return C;
4622
4623 case CXCursor_VariableRef:
4624 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4625
4626 default:
4627 // We would prefer to enumerate all non-reference cursor kinds here.
4628 llvm_unreachable("Unhandled reference cursor kind");
4629 }
4630}
4631
4632CXCursor clang_getCursorDefinition(CXCursor C) {
4633 if (clang_isInvalid(C.kind))
4634 return clang_getNullCursor();
4635
4636 CXTranslationUnit TU = getCursorTU(C);
4637
4638 bool WasReference = false;
4639 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4640 C = clang_getCursorReferenced(C);
4641 WasReference = true;
4642 }
4643
4644 if (C.kind == CXCursor_MacroExpansion)
4645 return clang_getCursorReferenced(C);
4646
4647 if (!clang_isDeclaration(C.kind))
4648 return clang_getNullCursor();
4649
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004650 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 if (!D)
4652 return clang_getNullCursor();
4653
4654 switch (D->getKind()) {
4655 // Declaration kinds that don't really separate the notions of
4656 // declaration and definition.
4657 case Decl::Namespace:
4658 case Decl::Typedef:
4659 case Decl::TypeAlias:
4660 case Decl::TypeAliasTemplate:
4661 case Decl::TemplateTypeParm:
4662 case Decl::EnumConstant:
4663 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004664 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case Decl::IndirectField:
4666 case Decl::ObjCIvar:
4667 case Decl::ObjCAtDefsField:
4668 case Decl::ImplicitParam:
4669 case Decl::ParmVar:
4670 case Decl::NonTypeTemplateParm:
4671 case Decl::TemplateTemplateParm:
4672 case Decl::ObjCCategoryImpl:
4673 case Decl::ObjCImplementation:
4674 case Decl::AccessSpec:
4675 case Decl::LinkageSpec:
4676 case Decl::ObjCPropertyImpl:
4677 case Decl::FileScopeAsm:
4678 case Decl::StaticAssert:
4679 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004680 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case Decl::Label: // FIXME: Is this right??
4682 case Decl::ClassScopeFunctionSpecialization:
4683 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004684 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 return C;
4686
4687 // Declaration kinds that don't make any sense here, but are
4688 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004689 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 case Decl::TranslationUnit:
4691 break;
4692
4693 // Declaration kinds for which the definition is not resolvable.
4694 case Decl::UnresolvedUsingTypename:
4695 case Decl::UnresolvedUsingValue:
4696 break;
4697
4698 case Decl::UsingDirective:
4699 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4700 TU);
4701
4702 case Decl::NamespaceAlias:
4703 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4704
4705 case Decl::Enum:
4706 case Decl::Record:
4707 case Decl::CXXRecord:
4708 case Decl::ClassTemplateSpecialization:
4709 case Decl::ClassTemplatePartialSpecialization:
4710 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4711 return MakeCXCursor(Def, TU);
4712 return clang_getNullCursor();
4713
4714 case Decl::Function:
4715 case Decl::CXXMethod:
4716 case Decl::CXXConstructor:
4717 case Decl::CXXDestructor:
4718 case Decl::CXXConversion: {
4719 const FunctionDecl *Def = 0;
4720 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004721 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 return clang_getNullCursor();
4723 }
4724
Larisse Voufo39a1e502013-08-06 01:03:05 +00004725 case Decl::Var:
4726 case Decl::VarTemplateSpecialization:
4727 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004729 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 return MakeCXCursor(Def, TU);
4731 return clang_getNullCursor();
4732 }
4733
4734 case Decl::FunctionTemplate: {
4735 const FunctionDecl *Def = 0;
4736 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4737 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4738 return clang_getNullCursor();
4739 }
4740
4741 case Decl::ClassTemplate: {
4742 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4743 ->getDefinition())
4744 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4745 TU);
4746 return clang_getNullCursor();
4747 }
4748
Larisse Voufo39a1e502013-08-06 01:03:05 +00004749 case Decl::VarTemplate: {
4750 if (VarDecl *Def =
4751 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4752 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4753 return clang_getNullCursor();
4754 }
4755
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 case Decl::Using:
4757 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4758 D->getLocation(), TU);
4759
4760 case Decl::UsingShadow:
4761 return clang_getCursorDefinition(
4762 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4763 TU));
4764
4765 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004766 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 if (Method->isThisDeclarationADefinition())
4768 return C;
4769
4770 // Dig out the method definition in the associated
4771 // @implementation, if we have it.
4772 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004773 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4775 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4776 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4777 Method->isInstanceMethod()))
4778 if (Def->isThisDeclarationADefinition())
4779 return MakeCXCursor(Def, TU);
4780
4781 return clang_getNullCursor();
4782 }
4783
4784 case Decl::ObjCCategory:
4785 if (ObjCCategoryImplDecl *Impl
4786 = cast<ObjCCategoryDecl>(D)->getImplementation())
4787 return MakeCXCursor(Impl, TU);
4788 return clang_getNullCursor();
4789
4790 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004791 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004792 return MakeCXCursor(Def, TU);
4793 return clang_getNullCursor();
4794
4795 case Decl::ObjCInterface: {
4796 // There are two notions of a "definition" for an Objective-C
4797 // class: the interface and its implementation. When we resolved a
4798 // reference to an Objective-C class, produce the @interface as
4799 // the definition; when we were provided with the interface,
4800 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004801 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004802 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004803 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004804 return MakeCXCursor(Def, TU);
4805 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4806 return MakeCXCursor(Impl, TU);
4807 return clang_getNullCursor();
4808 }
4809
4810 case Decl::ObjCProperty:
4811 // FIXME: We don't really know where to find the
4812 // ObjCPropertyImplDecls that implement this property.
4813 return clang_getNullCursor();
4814
4815 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004816 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004818 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 return MakeCXCursor(Def, TU);
4820
4821 return clang_getNullCursor();
4822
4823 case Decl::Friend:
4824 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4825 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4826 return clang_getNullCursor();
4827
4828 case Decl::FriendTemplate:
4829 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4830 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4831 return clang_getNullCursor();
4832 }
4833
4834 return clang_getNullCursor();
4835}
4836
4837unsigned clang_isCursorDefinition(CXCursor C) {
4838 if (!clang_isDeclaration(C.kind))
4839 return 0;
4840
4841 return clang_getCursorDefinition(C) == C;
4842}
4843
4844CXCursor clang_getCanonicalCursor(CXCursor C) {
4845 if (!clang_isDeclaration(C.kind))
4846 return C;
4847
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004848 if (const Decl *D = getCursorDecl(C)) {
4849 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004850 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4851 return MakeCXCursor(CatD, getCursorTU(C));
4852
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004853 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4854 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004855 return MakeCXCursor(IFD, getCursorTU(C));
4856
4857 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4858 }
4859
4860 return C;
4861}
4862
4863int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4864 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4865}
4866
4867unsigned clang_getNumOverloadedDecls(CXCursor C) {
4868 if (C.kind != CXCursor_OverloadedDeclRef)
4869 return 0;
4870
4871 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004872 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 return E->getNumDecls();
4874
4875 if (OverloadedTemplateStorage *S
4876 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4877 return S->size();
4878
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004879 const Decl *D = Storage.get<const Decl *>();
4880 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004881 return Using->shadow_size();
4882
4883 return 0;
4884}
4885
4886CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4887 if (cursor.kind != CXCursor_OverloadedDeclRef)
4888 return clang_getNullCursor();
4889
4890 if (index >= clang_getNumOverloadedDecls(cursor))
4891 return clang_getNullCursor();
4892
4893 CXTranslationUnit TU = getCursorTU(cursor);
4894 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004895 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004896 return MakeCXCursor(E->decls_begin()[index], TU);
4897
4898 if (OverloadedTemplateStorage *S
4899 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4900 return MakeCXCursor(S->begin()[index], TU);
4901
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004902 const Decl *D = Storage.get<const Decl *>();
4903 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004904 // FIXME: This is, unfortunately, linear time.
4905 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4906 std::advance(Pos, index);
4907 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4908 }
4909
4910 return clang_getNullCursor();
4911}
4912
4913void clang_getDefinitionSpellingAndExtent(CXCursor C,
4914 const char **startBuf,
4915 const char **endBuf,
4916 unsigned *startLine,
4917 unsigned *startColumn,
4918 unsigned *endLine,
4919 unsigned *endColumn) {
4920 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004921 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004922 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4923
4924 SourceManager &SM = FD->getASTContext().getSourceManager();
4925 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4926 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4927 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4928 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4929 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4930 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4931}
4932
4933
4934CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4935 unsigned PieceIndex) {
4936 RefNamePieces Pieces;
4937
4938 switch (C.kind) {
4939 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004940 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004941 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4942 E->getQualifierLoc().getSourceRange());
4943 break;
4944
4945 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004946 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004947 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4948 E->getQualifierLoc().getSourceRange(),
4949 E->getOptionalExplicitTemplateArgs());
4950 break;
4951
4952 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004953 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004954 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004955 const Expr *Callee = OCE->getCallee();
4956 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004957 Callee = ICE->getSubExpr();
4958
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004959 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004960 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4961 DRE->getQualifierLoc().getSourceRange());
4962 }
4963 break;
4964
4965 default:
4966 break;
4967 }
4968
4969 if (Pieces.empty()) {
4970 if (PieceIndex == 0)
4971 return clang_getCursorExtent(C);
4972 } else if (PieceIndex < Pieces.size()) {
4973 SourceRange R = Pieces[PieceIndex];
4974 if (R.isValid())
4975 return cxloc::translateSourceRange(getCursorContext(C), R);
4976 }
4977
4978 return clang_getNullRange();
4979}
4980
4981void clang_enableStackTraces(void) {
4982 llvm::sys::PrintStackTraceOnErrorSignal();
4983}
4984
4985void clang_executeOnThread(void (*fn)(void*), void *user_data,
4986 unsigned stack_size) {
4987 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4988}
4989
4990} // end: extern "C"
4991
4992//===----------------------------------------------------------------------===//
4993// Token-based Operations.
4994//===----------------------------------------------------------------------===//
4995
4996/* CXToken layout:
4997 * int_data[0]: a CXTokenKind
4998 * int_data[1]: starting token location
4999 * int_data[2]: token length
5000 * int_data[3]: reserved
5001 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5002 * otherwise unused.
5003 */
5004extern "C" {
5005
5006CXTokenKind clang_getTokenKind(CXToken CXTok) {
5007 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5008}
5009
5010CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5011 switch (clang_getTokenKind(CXTok)) {
5012 case CXToken_Identifier:
5013 case CXToken_Keyword:
5014 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005015 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005016 ->getNameStart());
5017
5018 case CXToken_Literal: {
5019 // We have stashed the starting pointer in the ptr_data field. Use it.
5020 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005021 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005022 }
5023
5024 case CXToken_Punctuation:
5025 case CXToken_Comment:
5026 break;
5027 }
5028
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005029 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005030 LOG_BAD_TU(TU);
5031 return cxstring::createEmpty();
5032 }
5033
Guy Benyei11169dd2012-12-18 14:30:41 +00005034 // We have to find the starting buffer pointer the hard way, by
5035 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005036 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005037 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005038 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005039
5040 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5041 std::pair<FileID, unsigned> LocInfo
5042 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5043 bool Invalid = false;
5044 StringRef Buffer
5045 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5046 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005047 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005048
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005049 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005050}
5051
5052CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005053 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005054 LOG_BAD_TU(TU);
5055 return clang_getNullLocation();
5056 }
5057
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005058 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005059 if (!CXXUnit)
5060 return clang_getNullLocation();
5061
5062 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5063 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5064}
5065
5066CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005067 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005068 LOG_BAD_TU(TU);
5069 return clang_getNullRange();
5070 }
5071
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005072 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005073 if (!CXXUnit)
5074 return clang_getNullRange();
5075
5076 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5077 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5078}
5079
5080static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5081 SmallVectorImpl<CXToken> &CXTokens) {
5082 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5083 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005084 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005085 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005086 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005087
5088 // Cannot tokenize across files.
5089 if (BeginLocInfo.first != EndLocInfo.first)
5090 return;
5091
5092 // Create a lexer
5093 bool Invalid = false;
5094 StringRef Buffer
5095 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5096 if (Invalid)
5097 return;
5098
5099 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5100 CXXUnit->getASTContext().getLangOpts(),
5101 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5102 Lex.SetCommentRetentionState(true);
5103
5104 // Lex tokens until we hit the end of the range.
5105 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5106 Token Tok;
5107 bool previousWasAt = false;
5108 do {
5109 // Lex the next token
5110 Lex.LexFromRawLexer(Tok);
5111 if (Tok.is(tok::eof))
5112 break;
5113
5114 // Initialize the CXToken.
5115 CXToken CXTok;
5116
5117 // - Common fields
5118 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5119 CXTok.int_data[2] = Tok.getLength();
5120 CXTok.int_data[3] = 0;
5121
5122 // - Kind-specific fields
5123 if (Tok.isLiteral()) {
5124 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005125 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 } else if (Tok.is(tok::raw_identifier)) {
5127 // Lookup the identifier to determine whether we have a keyword.
5128 IdentifierInfo *II
5129 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5130
5131 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5132 CXTok.int_data[0] = CXToken_Keyword;
5133 }
5134 else {
5135 CXTok.int_data[0] = Tok.is(tok::identifier)
5136 ? CXToken_Identifier
5137 : CXToken_Keyword;
5138 }
5139 CXTok.ptr_data = II;
5140 } else if (Tok.is(tok::comment)) {
5141 CXTok.int_data[0] = CXToken_Comment;
5142 CXTok.ptr_data = 0;
5143 } else {
5144 CXTok.int_data[0] = CXToken_Punctuation;
5145 CXTok.ptr_data = 0;
5146 }
5147 CXTokens.push_back(CXTok);
5148 previousWasAt = Tok.is(tok::at);
5149 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5150}
5151
5152void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5153 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005154 LOG_FUNC_SECTION {
5155 *Log << TU << ' ' << Range;
5156 }
5157
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 if (Tokens)
5159 *Tokens = 0;
5160 if (NumTokens)
5161 *NumTokens = 0;
5162
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005163 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005164 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005165 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005166 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005167
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005168 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005169 if (!CXXUnit || !Tokens || !NumTokens)
5170 return;
5171
5172 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5173
5174 SourceRange R = cxloc::translateCXSourceRange(Range);
5175 if (R.isInvalid())
5176 return;
5177
5178 SmallVector<CXToken, 32> CXTokens;
5179 getTokens(CXXUnit, R, CXTokens);
5180
5181 if (CXTokens.empty())
5182 return;
5183
5184 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5185 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5186 *NumTokens = CXTokens.size();
5187}
5188
5189void clang_disposeTokens(CXTranslationUnit TU,
5190 CXToken *Tokens, unsigned NumTokens) {
5191 free(Tokens);
5192}
5193
5194} // end: extern "C"
5195
5196//===----------------------------------------------------------------------===//
5197// Token annotation APIs.
5198//===----------------------------------------------------------------------===//
5199
Guy Benyei11169dd2012-12-18 14:30:41 +00005200static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5201 CXCursor parent,
5202 CXClientData client_data);
5203static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5204 CXClientData client_data);
5205
5206namespace {
5207class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 CXToken *Tokens;
5209 CXCursor *Cursors;
5210 unsigned NumTokens;
5211 unsigned TokIdx;
5212 unsigned PreprocessingTokIdx;
5213 CursorVisitor AnnotateVis;
5214 SourceManager &SrcMgr;
5215 bool HasContextSensitiveKeywords;
5216
5217 struct PostChildrenInfo {
5218 CXCursor Cursor;
5219 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005220 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 unsigned BeforeChildrenTokenIdx;
5222 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005223 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005224
5225 CXToken &getTok(unsigned Idx) {
5226 assert(Idx < NumTokens);
5227 return Tokens[Idx];
5228 }
5229 const CXToken &getTok(unsigned Idx) const {
5230 assert(Idx < NumTokens);
5231 return Tokens[Idx];
5232 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005233 bool MoreTokens() const { return TokIdx < NumTokens; }
5234 unsigned NextToken() const { return TokIdx; }
5235 void AdvanceToken() { ++TokIdx; }
5236 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005237 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 }
5239 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005240 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005241 }
5242 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005243 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 }
5245
5246 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005247 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 SourceRange);
5249
5250public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005251 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005252 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005253 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005255 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 AnnotateTokensVisitor, this,
5257 /*VisitPreprocessorLast=*/true,
5258 /*VisitIncludedEntities=*/false,
5259 RegionOfInterest,
5260 /*VisitDeclsOnly=*/false,
5261 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005262 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005263 HasContextSensitiveKeywords(false) { }
5264
5265 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5266 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5267 bool postVisitChildren(CXCursor cursor);
5268 void AnnotateTokens();
5269
5270 /// \brief Determine whether the annotator saw any cursors that have
5271 /// context-sensitive keywords.
5272 bool hasContextSensitiveKeywords() const {
5273 return HasContextSensitiveKeywords;
5274 }
5275
5276 ~AnnotateTokensWorker() {
5277 assert(PostChildrenInfos.empty());
5278 }
5279};
5280}
5281
5282void AnnotateTokensWorker::AnnotateTokens() {
5283 // Walk the AST within the region of interest, annotating tokens
5284 // along the way.
5285 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005286}
Guy Benyei11169dd2012-12-18 14:30:41 +00005287
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005288static inline void updateCursorAnnotation(CXCursor &Cursor,
5289 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005290 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005291 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005292 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005293}
5294
5295/// \brief It annotates and advances tokens with a cursor until the comparison
5296//// between the cursor location and the source range is the same as
5297/// \arg compResult.
5298///
5299/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5300/// Pass RangeOverlap to annotate tokens inside a range.
5301void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5302 RangeComparisonResult compResult,
5303 SourceRange range) {
5304 while (MoreTokens()) {
5305 const unsigned I = NextToken();
5306 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005307 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5308 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005309
5310 SourceLocation TokLoc = GetTokenLoc(I);
5311 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005312 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005313 AdvanceToken();
5314 continue;
5315 }
5316 break;
5317 }
5318}
5319
5320/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005321/// \returns true if it advanced beyond all macro tokens, false otherwise.
5322bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005323 CXCursor updateC,
5324 RangeComparisonResult compResult,
5325 SourceRange range) {
5326 assert(MoreTokens());
5327 assert(isFunctionMacroToken(NextToken()) &&
5328 "Should be called only for macro arg tokens");
5329
5330 // This works differently than annotateAndAdvanceTokens; because expanded
5331 // macro arguments can have arbitrary translation-unit source order, we do not
5332 // advance the token index one by one until a token fails the range test.
5333 // We only advance once past all of the macro arg tokens if all of them
5334 // pass the range test. If one of them fails we keep the token index pointing
5335 // at the start of the macro arg tokens so that the failing token will be
5336 // annotated by a subsequent annotation try.
5337
5338 bool atLeastOneCompFail = false;
5339
5340 unsigned I = NextToken();
5341 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5342 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5343 if (TokLoc.isFileID())
5344 continue; // not macro arg token, it's parens or comma.
5345 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5346 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5347 Cursors[I] = updateC;
5348 } else
5349 atLeastOneCompFail = true;
5350 }
5351
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005352 if (atLeastOneCompFail)
5353 return false;
5354
5355 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5356 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005357}
5358
5359enum CXChildVisitResult
5360AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005361 SourceRange cursorRange = getRawCursorExtent(cursor);
5362 if (cursorRange.isInvalid())
5363 return CXChildVisit_Recurse;
5364
5365 if (!HasContextSensitiveKeywords) {
5366 // Objective-C properties can have context-sensitive keywords.
5367 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005368 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005369 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5370 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5371 }
5372 // Objective-C methods can have context-sensitive keywords.
5373 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5374 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005375 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5377 if (Method->getObjCDeclQualifier())
5378 HasContextSensitiveKeywords = true;
5379 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005380 for (const auto *P : Method->params()) {
5381 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005382 HasContextSensitiveKeywords = true;
5383 break;
5384 }
5385 }
5386 }
5387 }
5388 }
5389 // C++ methods can have context-sensitive keywords.
5390 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005391 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005392 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5393 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5394 HasContextSensitiveKeywords = true;
5395 }
5396 }
5397 // C++ classes can have context-sensitive keywords.
5398 else if (cursor.kind == CXCursor_StructDecl ||
5399 cursor.kind == CXCursor_ClassDecl ||
5400 cursor.kind == CXCursor_ClassTemplate ||
5401 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005402 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 if (D->hasAttr<FinalAttr>())
5404 HasContextSensitiveKeywords = true;
5405 }
5406 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005407
5408 // Don't override a property annotation with its getter/setter method.
5409 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5410 parent.kind == CXCursor_ObjCPropertyDecl)
5411 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005412
5413 if (clang_isPreprocessing(cursor.kind)) {
5414 // Items in the preprocessing record are kept separate from items in
5415 // declarations, so we keep a separate token index.
5416 unsigned SavedTokIdx = TokIdx;
5417 TokIdx = PreprocessingTokIdx;
5418
5419 // Skip tokens up until we catch up to the beginning of the preprocessing
5420 // entry.
5421 while (MoreTokens()) {
5422 const unsigned I = NextToken();
5423 SourceLocation TokLoc = GetTokenLoc(I);
5424 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5425 case RangeBefore:
5426 AdvanceToken();
5427 continue;
5428 case RangeAfter:
5429 case RangeOverlap:
5430 break;
5431 }
5432 break;
5433 }
5434
5435 // Look at all of the tokens within this range.
5436 while (MoreTokens()) {
5437 const unsigned I = NextToken();
5438 SourceLocation TokLoc = GetTokenLoc(I);
5439 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5440 case RangeBefore:
5441 llvm_unreachable("Infeasible");
5442 case RangeAfter:
5443 break;
5444 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005445 // For macro expansions, just note where the beginning of the macro
5446 // expansion occurs.
5447 if (cursor.kind == CXCursor_MacroExpansion) {
5448 if (TokLoc == cursorRange.getBegin())
5449 Cursors[I] = cursor;
5450 AdvanceToken();
5451 break;
5452 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005453 // We may have already annotated macro names inside macro definitions.
5454 if (Cursors[I].kind != CXCursor_MacroExpansion)
5455 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 continue;
5458 }
5459 break;
5460 }
5461
5462 // Save the preprocessing token index; restore the non-preprocessing
5463 // token index.
5464 PreprocessingTokIdx = TokIdx;
5465 TokIdx = SavedTokIdx;
5466 return CXChildVisit_Recurse;
5467 }
5468
5469 if (cursorRange.isInvalid())
5470 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005471
5472 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 const enum CXCursorKind K = clang_getCursorKind(parent);
5475 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005476 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5477 // Attributes are annotated out-of-order, skip tokens until we reach it.
5478 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 ? clang_getNullCursor() : parent;
5480
5481 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5482
5483 // Avoid having the cursor of an expression "overwrite" the annotation of the
5484 // variable declaration that it belongs to.
5485 // This can happen for C++ constructor expressions whose range generally
5486 // include the variable declaration, e.g.:
5487 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005488 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005489 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005490 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 const unsigned I = NextToken();
5492 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5493 E->getLocStart() == D->getLocation() &&
5494 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005495 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005496 AdvanceToken();
5497 }
5498 }
5499 }
5500
5501 // Before recursing into the children keep some state that we are going
5502 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5503 // extra work after the child nodes are visited.
5504 // Note that we don't call VisitChildren here to avoid traversing statements
5505 // code-recursively which can blow the stack.
5506
5507 PostChildrenInfo Info;
5508 Info.Cursor = cursor;
5509 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005510 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 Info.BeforeChildrenTokenIdx = NextToken();
5512 PostChildrenInfos.push_back(Info);
5513
5514 return CXChildVisit_Recurse;
5515}
5516
5517bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5518 if (PostChildrenInfos.empty())
5519 return false;
5520 const PostChildrenInfo &Info = PostChildrenInfos.back();
5521 if (!clang_equalCursors(Info.Cursor, cursor))
5522 return false;
5523
5524 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5525 const unsigned AfterChildren = NextToken();
5526 SourceRange cursorRange = Info.CursorRange;
5527
5528 // Scan the tokens that are at the end of the cursor, but are not captured
5529 // but the child cursors.
5530 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5531
5532 // Scan the tokens that are at the beginning of the cursor, but are not
5533 // capture by the child cursors.
5534 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5535 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5536 break;
5537
5538 Cursors[I] = cursor;
5539 }
5540
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005541 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5542 // encountered the attribute cursor.
5543 if (clang_isAttribute(cursor.kind))
5544 TokIdx = Info.BeforeReachingCursorIdx;
5545
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 PostChildrenInfos.pop_back();
5547 return false;
5548}
5549
5550static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5551 CXCursor parent,
5552 CXClientData client_data) {
5553 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5554}
5555
5556static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5557 CXClientData client_data) {
5558 return static_cast<AnnotateTokensWorker*>(client_data)->
5559 postVisitChildren(cursor);
5560}
5561
5562namespace {
5563
5564/// \brief Uses the macro expansions in the preprocessing record to find
5565/// and mark tokens that are macro arguments. This info is used by the
5566/// AnnotateTokensWorker.
5567class MarkMacroArgTokensVisitor {
5568 SourceManager &SM;
5569 CXToken *Tokens;
5570 unsigned NumTokens;
5571 unsigned CurIdx;
5572
5573public:
5574 MarkMacroArgTokensVisitor(SourceManager &SM,
5575 CXToken *tokens, unsigned numTokens)
5576 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5577
5578 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5579 if (cursor.kind != CXCursor_MacroExpansion)
5580 return CXChildVisit_Continue;
5581
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005582 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005583 if (macroRange.getBegin() == macroRange.getEnd())
5584 return CXChildVisit_Continue; // it's not a function macro.
5585
5586 for (; CurIdx < NumTokens; ++CurIdx) {
5587 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5588 macroRange.getBegin()))
5589 break;
5590 }
5591
5592 if (CurIdx == NumTokens)
5593 return CXChildVisit_Break;
5594
5595 for (; CurIdx < NumTokens; ++CurIdx) {
5596 SourceLocation tokLoc = getTokenLoc(CurIdx);
5597 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5598 break;
5599
5600 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5601 }
5602
5603 if (CurIdx == NumTokens)
5604 return CXChildVisit_Break;
5605
5606 return CXChildVisit_Continue;
5607 }
5608
5609private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005610 CXToken &getTok(unsigned Idx) {
5611 assert(Idx < NumTokens);
5612 return Tokens[Idx];
5613 }
5614 const CXToken &getTok(unsigned Idx) const {
5615 assert(Idx < NumTokens);
5616 return Tokens[Idx];
5617 }
5618
Guy Benyei11169dd2012-12-18 14:30:41 +00005619 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005620 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005621 }
5622
5623 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5624 // The third field is reserved and currently not used. Use it here
5625 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005626 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005627 }
5628};
5629
5630} // end anonymous namespace
5631
5632static CXChildVisitResult
5633MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5634 CXClientData client_data) {
5635 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5636 parent);
5637}
5638
5639namespace {
5640 struct clang_annotateTokens_Data {
5641 CXTranslationUnit TU;
5642 ASTUnit *CXXUnit;
5643 CXToken *Tokens;
5644 unsigned NumTokens;
5645 CXCursor *Cursors;
5646 };
5647}
5648
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005649/// \brief Used by \c annotatePreprocessorTokens.
5650/// \returns true if lexing was finished, false otherwise.
5651static bool lexNext(Lexer &Lex, Token &Tok,
5652 unsigned &NextIdx, unsigned NumTokens) {
5653 if (NextIdx >= NumTokens)
5654 return true;
5655
5656 ++NextIdx;
5657 Lex.LexFromRawLexer(Tok);
5658 if (Tok.is(tok::eof))
5659 return true;
5660
5661 return false;
5662}
5663
Guy Benyei11169dd2012-12-18 14:30:41 +00005664static void annotatePreprocessorTokens(CXTranslationUnit TU,
5665 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005666 CXCursor *Cursors,
5667 CXToken *Tokens,
5668 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005669 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005670
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005671 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005672 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5673 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005674 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005676 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005677
5678 if (BeginLocInfo.first != EndLocInfo.first)
5679 return;
5680
5681 StringRef Buffer;
5682 bool Invalid = false;
5683 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5684 if (Buffer.empty() || Invalid)
5685 return;
5686
5687 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5688 CXXUnit->getASTContext().getLangOpts(),
5689 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5690 Buffer.end());
5691 Lex.SetCommentRetentionState(true);
5692
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005693 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005694 // Lex tokens in raw mode until we hit the end of the range, to avoid
5695 // entering #includes or expanding macros.
5696 while (true) {
5697 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005698 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5699 break;
5700 unsigned TokIdx = NextIdx-1;
5701 assert(Tok.getLocation() ==
5702 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005703
5704 reprocess:
5705 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005706 // We have found a preprocessing directive. Annotate the tokens
5707 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005708 //
5709 // FIXME: Some simple tests here could identify macro definitions and
5710 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005711
5712 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005713 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5714 break;
5715
5716 MacroInfo *MI = 0;
Alp Toker2d57cea2014-05-17 04:53:25 +00005717 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005718 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5719 break;
5720
5721 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005722 IdentifierInfo &II =
5723 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005724 SourceLocation MappedTokLoc =
5725 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5726 MI = getMacroInfo(II, MappedTokLoc, TU);
5727 }
5728 }
5729
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005730 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005731 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005732 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5733 finished = true;
5734 break;
5735 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005736 // If we are in a macro definition, check if the token was ever a
5737 // macro name and annotate it if that's the case.
5738 if (MI) {
5739 SourceLocation SaveLoc = Tok.getLocation();
5740 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5741 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5742 Tok.setLocation(SaveLoc);
5743 if (MacroDef)
5744 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5745 Tok.getLocation(), TU);
5746 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005747 } while (!Tok.isAtStartOfLine());
5748
5749 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5750 assert(TokIdx <= LastIdx);
5751 SourceLocation EndLoc =
5752 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5753 CXCursor Cursor =
5754 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5755
5756 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005757 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005758
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005759 if (finished)
5760 break;
5761 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005763 }
5764}
5765
5766// This gets run a separate thread to avoid stack blowout.
5767static void clang_annotateTokensImpl(void *UserData) {
5768 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5769 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5770 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5771 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5772 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5773
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005774 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005775 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5776 setThreadBackgroundPriority();
5777
5778 // Determine the region of interest, which contains all of the tokens.
5779 SourceRange RegionOfInterest;
5780 RegionOfInterest.setBegin(
5781 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5782 RegionOfInterest.setEnd(
5783 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5784 Tokens[NumTokens-1])));
5785
Guy Benyei11169dd2012-12-18 14:30:41 +00005786 // Relex the tokens within the source range to look for preprocessing
5787 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005788 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005789
5790 // If begin location points inside a macro argument, set it to the expansion
5791 // location so we can have the full context when annotating semantically.
5792 {
5793 SourceManager &SM = CXXUnit->getSourceManager();
5794 SourceLocation Loc =
5795 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5796 if (Loc.isMacroID())
5797 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5798 }
5799
Guy Benyei11169dd2012-12-18 14:30:41 +00005800 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5801 // Search and mark tokens that are macro argument expansions.
5802 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5803 Tokens, NumTokens);
5804 CursorVisitor MacroArgMarker(TU,
5805 MarkMacroArgTokensVisitorDelegate, &Visitor,
5806 /*VisitPreprocessorLast=*/true,
5807 /*VisitIncludedEntities=*/false,
5808 RegionOfInterest);
5809 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5810 }
5811
5812 // Annotate all of the source locations in the region of interest that map to
5813 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005814 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005815
5816 // FIXME: We use a ridiculous stack size here because the data-recursion
5817 // algorithm uses a large stack frame than the non-data recursive version,
5818 // and AnnotationTokensWorker currently transforms the data-recursion
5819 // algorithm back into a traditional recursion by explicitly calling
5820 // VisitChildren(). We will need to remove this explicit recursive call.
5821 W.AnnotateTokens();
5822
5823 // If we ran into any entities that involve context-sensitive keywords,
5824 // take another pass through the tokens to mark them as such.
5825 if (W.hasContextSensitiveKeywords()) {
5826 for (unsigned I = 0; I != NumTokens; ++I) {
5827 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5828 continue;
5829
5830 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5831 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005832 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005833 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5834 if (Property->getPropertyAttributesAsWritten() != 0 &&
5835 llvm::StringSwitch<bool>(II->getName())
5836 .Case("readonly", true)
5837 .Case("assign", true)
5838 .Case("unsafe_unretained", true)
5839 .Case("readwrite", true)
5840 .Case("retain", true)
5841 .Case("copy", true)
5842 .Case("nonatomic", true)
5843 .Case("atomic", true)
5844 .Case("getter", true)
5845 .Case("setter", true)
5846 .Case("strong", true)
5847 .Case("weak", true)
5848 .Default(false))
5849 Tokens[I].int_data[0] = CXToken_Keyword;
5850 }
5851 continue;
5852 }
5853
5854 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5855 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5856 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5857 if (llvm::StringSwitch<bool>(II->getName())
5858 .Case("in", true)
5859 .Case("out", true)
5860 .Case("inout", true)
5861 .Case("oneway", true)
5862 .Case("bycopy", true)
5863 .Case("byref", true)
5864 .Default(false))
5865 Tokens[I].int_data[0] = CXToken_Keyword;
5866 continue;
5867 }
5868
5869 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5870 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5871 Tokens[I].int_data[0] = CXToken_Keyword;
5872 continue;
5873 }
5874 }
5875 }
5876}
5877
5878extern "C" {
5879
5880void clang_annotateTokens(CXTranslationUnit TU,
5881 CXToken *Tokens, unsigned NumTokens,
5882 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005883 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005884 LOG_BAD_TU(TU);
5885 return;
5886 }
5887 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005888 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005889 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005890 }
5891
5892 LOG_FUNC_SECTION {
5893 *Log << TU << ' ';
5894 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5895 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5896 *Log << clang_getRange(bloc, eloc);
5897 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005898
5899 // Any token we don't specifically annotate will have a NULL cursor.
5900 CXCursor C = clang_getNullCursor();
5901 for (unsigned I = 0; I != NumTokens; ++I)
5902 Cursors[I] = C;
5903
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005904 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005905 if (!CXXUnit)
5906 return;
5907
5908 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5909
5910 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5911 llvm::CrashRecoveryContext CRC;
5912 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5913 GetSafetyThreadStackSize() * 2)) {
5914 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5915 }
5916}
5917
5918} // end: extern "C"
5919
5920//===----------------------------------------------------------------------===//
5921// Operations for querying linkage of a cursor.
5922//===----------------------------------------------------------------------===//
5923
5924extern "C" {
5925CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5926 if (!clang_isDeclaration(cursor.kind))
5927 return CXLinkage_Invalid;
5928
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005929 const Decl *D = cxcursor::getCursorDecl(cursor);
5930 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005931 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005932 case NoLinkage:
5933 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005934 case InternalLinkage: return CXLinkage_Internal;
5935 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5936 case ExternalLinkage: return CXLinkage_External;
5937 };
5938
5939 return CXLinkage_Invalid;
5940}
5941} // end: extern "C"
5942
5943//===----------------------------------------------------------------------===//
5944// Operations for querying language of a cursor.
5945//===----------------------------------------------------------------------===//
5946
5947static CXLanguageKind getDeclLanguage(const Decl *D) {
5948 if (!D)
5949 return CXLanguage_C;
5950
5951 switch (D->getKind()) {
5952 default:
5953 break;
5954 case Decl::ImplicitParam:
5955 case Decl::ObjCAtDefsField:
5956 case Decl::ObjCCategory:
5957 case Decl::ObjCCategoryImpl:
5958 case Decl::ObjCCompatibleAlias:
5959 case Decl::ObjCImplementation:
5960 case Decl::ObjCInterface:
5961 case Decl::ObjCIvar:
5962 case Decl::ObjCMethod:
5963 case Decl::ObjCProperty:
5964 case Decl::ObjCPropertyImpl:
5965 case Decl::ObjCProtocol:
5966 return CXLanguage_ObjC;
5967 case Decl::CXXConstructor:
5968 case Decl::CXXConversion:
5969 case Decl::CXXDestructor:
5970 case Decl::CXXMethod:
5971 case Decl::CXXRecord:
5972 case Decl::ClassTemplate:
5973 case Decl::ClassTemplatePartialSpecialization:
5974 case Decl::ClassTemplateSpecialization:
5975 case Decl::Friend:
5976 case Decl::FriendTemplate:
5977 case Decl::FunctionTemplate:
5978 case Decl::LinkageSpec:
5979 case Decl::Namespace:
5980 case Decl::NamespaceAlias:
5981 case Decl::NonTypeTemplateParm:
5982 case Decl::StaticAssert:
5983 case Decl::TemplateTemplateParm:
5984 case Decl::TemplateTypeParm:
5985 case Decl::UnresolvedUsingTypename:
5986 case Decl::UnresolvedUsingValue:
5987 case Decl::Using:
5988 case Decl::UsingDirective:
5989 case Decl::UsingShadow:
5990 return CXLanguage_CPlusPlus;
5991 }
5992
5993 return CXLanguage_C;
5994}
5995
5996extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005997
5998static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5999 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6000 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006001
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006002 switch (D->getAvailability()) {
6003 case AR_Available:
6004 case AR_NotYetIntroduced:
6005 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006006 return getCursorAvailabilityForDecl(
6007 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006008 return CXAvailability_Available;
6009
6010 case AR_Deprecated:
6011 return CXAvailability_Deprecated;
6012
6013 case AR_Unavailable:
6014 return CXAvailability_NotAvailable;
6015 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006016
6017 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006018}
6019
Guy Benyei11169dd2012-12-18 14:30:41 +00006020enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6021 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006022 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6023 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006024
6025 return CXAvailability_Available;
6026}
6027
6028static CXVersion convertVersion(VersionTuple In) {
6029 CXVersion Out = { -1, -1, -1 };
6030 if (In.empty())
6031 return Out;
6032
6033 Out.Major = In.getMajor();
6034
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006035 Optional<unsigned> Minor = In.getMinor();
6036 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006037 Out.Minor = *Minor;
6038 else
6039 return Out;
6040
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006041 Optional<unsigned> Subminor = In.getSubminor();
6042 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006043 Out.Subminor = *Subminor;
6044
6045 return Out;
6046}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006047
6048static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6049 int *always_deprecated,
6050 CXString *deprecated_message,
6051 int *always_unavailable,
6052 CXString *unavailable_message,
6053 CXPlatformAvailability *availability,
6054 int availability_size) {
6055 bool HadAvailAttr = false;
6056 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006057 for (auto A : D->attrs()) {
6058 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006059 HadAvailAttr = true;
6060 if (always_deprecated)
6061 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006062 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006063 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006064 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006065 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006066 continue;
6067 }
6068
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006069 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006070 HadAvailAttr = true;
6071 if (always_unavailable)
6072 *always_unavailable = 1;
6073 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006074 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006075 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6076 }
6077 continue;
6078 }
6079
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006080 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006081 HadAvailAttr = true;
6082 if (N < availability_size) {
6083 availability[N].Platform
6084 = cxstring::createDup(Avail->getPlatform()->getName());
6085 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6086 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6087 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6088 availability[N].Unavailable = Avail->getUnavailable();
6089 availability[N].Message = cxstring::createDup(Avail->getMessage());
6090 }
6091 ++N;
6092 }
6093 }
6094
6095 if (!HadAvailAttr)
6096 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6097 return getCursorPlatformAvailabilityForDecl(
6098 cast<Decl>(EnumConst->getDeclContext()),
6099 always_deprecated,
6100 deprecated_message,
6101 always_unavailable,
6102 unavailable_message,
6103 availability,
6104 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006105
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006106 return N;
6107}
6108
Guy Benyei11169dd2012-12-18 14:30:41 +00006109int clang_getCursorPlatformAvailability(CXCursor cursor,
6110 int *always_deprecated,
6111 CXString *deprecated_message,
6112 int *always_unavailable,
6113 CXString *unavailable_message,
6114 CXPlatformAvailability *availability,
6115 int availability_size) {
6116 if (always_deprecated)
6117 *always_deprecated = 0;
6118 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006119 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006120 if (always_unavailable)
6121 *always_unavailable = 0;
6122 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006123 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006124
Guy Benyei11169dd2012-12-18 14:30:41 +00006125 if (!clang_isDeclaration(cursor.kind))
6126 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006127
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006128 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006129 if (!D)
6130 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006131
6132 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6133 deprecated_message,
6134 always_unavailable,
6135 unavailable_message,
6136 availability,
6137 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006138}
6139
6140void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6141 clang_disposeString(availability->Platform);
6142 clang_disposeString(availability->Message);
6143}
6144
6145CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6146 if (clang_isDeclaration(cursor.kind))
6147 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6148
6149 return CXLanguage_Invalid;
6150}
6151
6152 /// \brief If the given cursor is the "templated" declaration
6153 /// descibing a class or function template, return the class or
6154 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006155static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006156 if (!D)
6157 return 0;
6158
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006159 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006160 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6161 return FunTmpl;
6162
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006163 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006164 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6165 return ClassTmpl;
6166
6167 return D;
6168}
6169
6170CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6171 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006172 if (const Decl *D = getCursorDecl(cursor)) {
6173 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006174 if (!DC)
6175 return clang_getNullCursor();
6176
6177 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6178 getCursorTU(cursor));
6179 }
6180 }
6181
6182 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006183 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006184 return MakeCXCursor(D, getCursorTU(cursor));
6185 }
6186
6187 return clang_getNullCursor();
6188}
6189
6190CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6191 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006192 if (const Decl *D = getCursorDecl(cursor)) {
6193 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006194 if (!DC)
6195 return clang_getNullCursor();
6196
6197 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6198 getCursorTU(cursor));
6199 }
6200 }
6201
6202 // FIXME: Note that we can't easily compute the lexical context of a
6203 // statement or expression, so we return nothing.
6204 return clang_getNullCursor();
6205}
6206
6207CXFile clang_getIncludedFile(CXCursor cursor) {
6208 if (cursor.kind != CXCursor_InclusionDirective)
6209 return 0;
6210
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006211 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006212 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006213}
6214
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006215unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6216 if (C.kind != CXCursor_ObjCPropertyDecl)
6217 return CXObjCPropertyAttr_noattr;
6218
6219 unsigned Result = CXObjCPropertyAttr_noattr;
6220 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6221 ObjCPropertyDecl::PropertyAttributeKind Attr =
6222 PD->getPropertyAttributesAsWritten();
6223
6224#define SET_CXOBJCPROP_ATTR(A) \
6225 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6226 Result |= CXObjCPropertyAttr_##A
6227 SET_CXOBJCPROP_ATTR(readonly);
6228 SET_CXOBJCPROP_ATTR(getter);
6229 SET_CXOBJCPROP_ATTR(assign);
6230 SET_CXOBJCPROP_ATTR(readwrite);
6231 SET_CXOBJCPROP_ATTR(retain);
6232 SET_CXOBJCPROP_ATTR(copy);
6233 SET_CXOBJCPROP_ATTR(nonatomic);
6234 SET_CXOBJCPROP_ATTR(setter);
6235 SET_CXOBJCPROP_ATTR(atomic);
6236 SET_CXOBJCPROP_ATTR(weak);
6237 SET_CXOBJCPROP_ATTR(strong);
6238 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6239#undef SET_CXOBJCPROP_ATTR
6240
6241 return Result;
6242}
6243
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006244unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6245 if (!clang_isDeclaration(C.kind))
6246 return CXObjCDeclQualifier_None;
6247
6248 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6249 const Decl *D = getCursorDecl(C);
6250 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6251 QT = MD->getObjCDeclQualifier();
6252 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6253 QT = PD->getObjCDeclQualifier();
6254 if (QT == Decl::OBJC_TQ_None)
6255 return CXObjCDeclQualifier_None;
6256
6257 unsigned Result = CXObjCDeclQualifier_None;
6258 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6259 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6260 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6261 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6262 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6263 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6264
6265 return Result;
6266}
6267
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006268unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6269 if (!clang_isDeclaration(C.kind))
6270 return 0;
6271
6272 const Decl *D = getCursorDecl(C);
6273 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6274 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6275 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6276 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6277
6278 return 0;
6279}
6280
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006281unsigned clang_Cursor_isVariadic(CXCursor C) {
6282 if (!clang_isDeclaration(C.kind))
6283 return 0;
6284
6285 const Decl *D = getCursorDecl(C);
6286 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6287 return FD->isVariadic();
6288 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6289 return MD->isVariadic();
6290
6291 return 0;
6292}
6293
Guy Benyei11169dd2012-12-18 14:30:41 +00006294CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6295 if (!clang_isDeclaration(C.kind))
6296 return clang_getNullRange();
6297
6298 const Decl *D = getCursorDecl(C);
6299 ASTContext &Context = getCursorContext(C);
6300 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6301 if (!RC)
6302 return clang_getNullRange();
6303
6304 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6305}
6306
6307CXString clang_Cursor_getRawCommentText(CXCursor C) {
6308 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006309 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006310
6311 const Decl *D = getCursorDecl(C);
6312 ASTContext &Context = getCursorContext(C);
6313 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6314 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6315 StringRef();
6316
6317 // Don't duplicate the string because RawText points directly into source
6318 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006319 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006320}
6321
6322CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6323 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006324 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006325
6326 const Decl *D = getCursorDecl(C);
6327 const ASTContext &Context = getCursorContext(C);
6328 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6329
6330 if (RC) {
6331 StringRef BriefText = RC->getBriefText(Context);
6332
6333 // Don't duplicate the string because RawComment ensures that this memory
6334 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006335 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006336 }
6337
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006338 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006339}
6340
Guy Benyei11169dd2012-12-18 14:30:41 +00006341CXModule clang_Cursor_getModule(CXCursor C) {
6342 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006343 if (const ImportDecl *ImportD =
6344 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006345 return ImportD->getImportedModule();
6346 }
6347
6348 return 0;
6349}
6350
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006351CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6352 if (isNotUsableTU(TU)) {
6353 LOG_BAD_TU(TU);
6354 return nullptr;
6355 }
6356 if (!File)
6357 return nullptr;
6358 FileEntry *FE = static_cast<FileEntry *>(File);
6359
6360 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6361 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6362 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6363
6364 if (Module *Mod = Header.getModule()) {
6365 if (Header.getRole() != ModuleMap::ExcludedHeader)
6366 return Mod;
6367 }
6368 return nullptr;
6369}
6370
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006371CXFile clang_Module_getASTFile(CXModule CXMod) {
6372 if (!CXMod)
6373 return 0;
6374 Module *Mod = static_cast<Module*>(CXMod);
6375 return const_cast<FileEntry *>(Mod->getASTFile());
6376}
6377
Guy Benyei11169dd2012-12-18 14:30:41 +00006378CXModule clang_Module_getParent(CXModule CXMod) {
6379 if (!CXMod)
6380 return 0;
6381 Module *Mod = static_cast<Module*>(CXMod);
6382 return Mod->Parent;
6383}
6384
6385CXString clang_Module_getName(CXModule CXMod) {
6386 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006387 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006388 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006389 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006390}
6391
6392CXString clang_Module_getFullName(CXModule CXMod) {
6393 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006394 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006395 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006396 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006397}
6398
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006399int clang_Module_isSystem(CXModule CXMod) {
6400 if (!CXMod)
6401 return 0;
6402 Module *Mod = static_cast<Module*>(CXMod);
6403 return Mod->IsSystem;
6404}
6405
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006406unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6407 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006408 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006409 LOG_BAD_TU(TU);
6410 return 0;
6411 }
6412 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006413 return 0;
6414 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006415 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6416 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6417 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006418}
6419
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006420CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6421 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006422 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006423 LOG_BAD_TU(TU);
6424 return 0;
6425 }
6426 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006427 return 0;
6428 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006429 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006430
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006431 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6432 if (Index < TopHeaders.size())
6433 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006434
6435 return 0;
6436}
6437
6438} // end: extern "C"
6439
6440//===----------------------------------------------------------------------===//
6441// C++ AST instrospection.
6442//===----------------------------------------------------------------------===//
6443
6444extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006445unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6446 if (!clang_isDeclaration(C.kind))
6447 return 0;
6448
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006449 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006450 const CXXMethodDecl *Method =
6451 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006452 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6453}
6454
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006455unsigned clang_CXXMethod_isConst(CXCursor C) {
6456 if (!clang_isDeclaration(C.kind))
6457 return 0;
6458
6459 const Decl *D = cxcursor::getCursorDecl(C);
6460 const CXXMethodDecl *Method =
6461 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
6462 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6463}
6464
Guy Benyei11169dd2012-12-18 14:30:41 +00006465unsigned clang_CXXMethod_isStatic(CXCursor C) {
6466 if (!clang_isDeclaration(C.kind))
6467 return 0;
6468
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006469 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006470 const CXXMethodDecl *Method =
6471 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006472 return (Method && Method->isStatic()) ? 1 : 0;
6473}
6474
6475unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6476 if (!clang_isDeclaration(C.kind))
6477 return 0;
6478
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006479 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006480 const CXXMethodDecl *Method =
6481 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006482 return (Method && Method->isVirtual()) ? 1 : 0;
6483}
6484} // end: extern "C"
6485
6486//===----------------------------------------------------------------------===//
6487// Attribute introspection.
6488//===----------------------------------------------------------------------===//
6489
6490extern "C" {
6491CXType clang_getIBOutletCollectionType(CXCursor C) {
6492 if (C.kind != CXCursor_IBOutletCollectionAttr)
6493 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6494
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006495 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006496 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6497
6498 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6499}
6500} // end: extern "C"
6501
6502//===----------------------------------------------------------------------===//
6503// Inspecting memory usage.
6504//===----------------------------------------------------------------------===//
6505
6506typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6507
6508static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6509 enum CXTUResourceUsageKind k,
6510 unsigned long amount) {
6511 CXTUResourceUsageEntry entry = { k, amount };
6512 entries.push_back(entry);
6513}
6514
6515extern "C" {
6516
6517const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6518 const char *str = "";
6519 switch (kind) {
6520 case CXTUResourceUsage_AST:
6521 str = "ASTContext: expressions, declarations, and types";
6522 break;
6523 case CXTUResourceUsage_Identifiers:
6524 str = "ASTContext: identifiers";
6525 break;
6526 case CXTUResourceUsage_Selectors:
6527 str = "ASTContext: selectors";
6528 break;
6529 case CXTUResourceUsage_GlobalCompletionResults:
6530 str = "Code completion: cached global results";
6531 break;
6532 case CXTUResourceUsage_SourceManagerContentCache:
6533 str = "SourceManager: content cache allocator";
6534 break;
6535 case CXTUResourceUsage_AST_SideTables:
6536 str = "ASTContext: side tables";
6537 break;
6538 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6539 str = "SourceManager: malloc'ed memory buffers";
6540 break;
6541 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6542 str = "SourceManager: mmap'ed memory buffers";
6543 break;
6544 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6545 str = "ExternalASTSource: malloc'ed memory buffers";
6546 break;
6547 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6548 str = "ExternalASTSource: mmap'ed memory buffers";
6549 break;
6550 case CXTUResourceUsage_Preprocessor:
6551 str = "Preprocessor: malloc'ed memory";
6552 break;
6553 case CXTUResourceUsage_PreprocessingRecord:
6554 str = "Preprocessor: PreprocessingRecord";
6555 break;
6556 case CXTUResourceUsage_SourceManager_DataStructures:
6557 str = "SourceManager: data structures and tables";
6558 break;
6559 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6560 str = "Preprocessor: header search tables";
6561 break;
6562 }
6563 return str;
6564}
6565
6566CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006567 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006568 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006569 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6570 return usage;
6571 }
6572
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006573 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006574 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006575 ASTContext &astContext = astUnit->getASTContext();
6576
6577 // How much memory is used by AST nodes and types?
6578 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6579 (unsigned long) astContext.getASTAllocatedMemory());
6580
6581 // How much memory is used by identifiers?
6582 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6583 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6584
6585 // How much memory is used for selectors?
6586 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6587 (unsigned long) astContext.Selectors.getTotalMemory());
6588
6589 // How much memory is used by ASTContext's side tables?
6590 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6591 (unsigned long) astContext.getSideTableAllocatedMemory());
6592
6593 // How much memory is used for caching global code completion results?
6594 unsigned long completionBytes = 0;
6595 if (GlobalCodeCompletionAllocator *completionAllocator =
6596 astUnit->getCachedCompletionAllocator().getPtr()) {
6597 completionBytes = completionAllocator->getTotalMemory();
6598 }
6599 createCXTUResourceUsageEntry(*entries,
6600 CXTUResourceUsage_GlobalCompletionResults,
6601 completionBytes);
6602
6603 // How much memory is being used by SourceManager's content cache?
6604 createCXTUResourceUsageEntry(*entries,
6605 CXTUResourceUsage_SourceManagerContentCache,
6606 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6607
6608 // How much memory is being used by the MemoryBuffer's in SourceManager?
6609 const SourceManager::MemoryBufferSizes &srcBufs =
6610 astUnit->getSourceManager().getMemoryBufferSizes();
6611
6612 createCXTUResourceUsageEntry(*entries,
6613 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6614 (unsigned long) srcBufs.malloc_bytes);
6615 createCXTUResourceUsageEntry(*entries,
6616 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6617 (unsigned long) srcBufs.mmap_bytes);
6618 createCXTUResourceUsageEntry(*entries,
6619 CXTUResourceUsage_SourceManager_DataStructures,
6620 (unsigned long) astContext.getSourceManager()
6621 .getDataStructureSizes());
6622
6623 // How much memory is being used by the ExternalASTSource?
6624 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6625 const ExternalASTSource::MemoryBufferSizes &sizes =
6626 esrc->getMemoryBufferSizes();
6627
6628 createCXTUResourceUsageEntry(*entries,
6629 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6630 (unsigned long) sizes.malloc_bytes);
6631 createCXTUResourceUsageEntry(*entries,
6632 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6633 (unsigned long) sizes.mmap_bytes);
6634 }
6635
6636 // How much memory is being used by the Preprocessor?
6637 Preprocessor &pp = astUnit->getPreprocessor();
6638 createCXTUResourceUsageEntry(*entries,
6639 CXTUResourceUsage_Preprocessor,
6640 pp.getTotalMemory());
6641
6642 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6643 createCXTUResourceUsageEntry(*entries,
6644 CXTUResourceUsage_PreprocessingRecord,
6645 pRec->getTotalMemory());
6646 }
6647
6648 createCXTUResourceUsageEntry(*entries,
6649 CXTUResourceUsage_Preprocessor_HeaderSearch,
6650 pp.getHeaderSearchInfo().getTotalMemory());
6651
6652 CXTUResourceUsage usage = { (void*) entries.get(),
6653 (unsigned) entries->size(),
6654 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006655 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006656 return usage;
6657}
6658
6659void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6660 if (usage.data)
6661 delete (MemUsageEntries*) usage.data;
6662}
6663
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006664CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6665 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006666 skipped->count = 0;
6667 skipped->ranges = 0;
6668
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006669 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006670 LOG_BAD_TU(TU);
6671 return skipped;
6672 }
6673
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006674 if (!file)
6675 return skipped;
6676
6677 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6678 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6679 if (!ppRec)
6680 return skipped;
6681
6682 ASTContext &Ctx = astUnit->getASTContext();
6683 SourceManager &sm = Ctx.getSourceManager();
6684 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6685 FileID wantedFileID = sm.translateFile(fileEntry);
6686
6687 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6688 std::vector<SourceRange> wantedRanges;
6689 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6690 i != ei; ++i) {
6691 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6692 wantedRanges.push_back(*i);
6693 }
6694
6695 skipped->count = wantedRanges.size();
6696 skipped->ranges = new CXSourceRange[skipped->count];
6697 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6698 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6699
6700 return skipped;
6701}
6702
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006703void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6704 if (ranges) {
6705 delete[] ranges->ranges;
6706 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006707 }
6708}
6709
Guy Benyei11169dd2012-12-18 14:30:41 +00006710} // end extern "C"
6711
6712void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6713 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6714 for (unsigned I = 0; I != Usage.numEntries; ++I)
6715 fprintf(stderr, " %s: %lu\n",
6716 clang_getTUResourceUsageName(Usage.entries[I].kind),
6717 Usage.entries[I].amount);
6718
6719 clang_disposeCXTUResourceUsage(Usage);
6720}
6721
6722//===----------------------------------------------------------------------===//
6723// Misc. utility functions.
6724//===----------------------------------------------------------------------===//
6725
6726/// Default to using an 8 MB stack size on "safety" threads.
6727static unsigned SafetyStackThreadSize = 8 << 20;
6728
6729namespace clang {
6730
6731bool RunSafely(llvm::CrashRecoveryContext &CRC,
6732 void (*Fn)(void*), void *UserData,
6733 unsigned Size) {
6734 if (!Size)
6735 Size = GetSafetyThreadStackSize();
6736 if (Size)
6737 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6738 return CRC.RunSafely(Fn, UserData);
6739}
6740
6741unsigned GetSafetyThreadStackSize() {
6742 return SafetyStackThreadSize;
6743}
6744
6745void SetSafetyThreadStackSize(unsigned Value) {
6746 SafetyStackThreadSize = Value;
6747}
6748
6749}
6750
6751void clang::setThreadBackgroundPriority() {
6752 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6753 return;
6754
6755 // FIXME: Move to llvm/Support and make it cross-platform.
6756#ifdef __APPLE__
6757 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6758#endif
6759}
6760
6761void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6762 if (!Unit)
6763 return;
6764
6765 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6766 DEnd = Unit->stored_diag_end();
6767 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006768 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006769 CXString Msg = clang_formatDiagnostic(&Diag,
6770 clang_defaultDiagnosticDisplayOptions());
6771 fprintf(stderr, "%s\n", clang_getCString(Msg));
6772 clang_disposeString(Msg);
6773 }
6774#ifdef LLVM_ON_WIN32
6775 // On Windows, force a flush, since there may be multiple copies of
6776 // stderr and stdout in the file system, all with different buffers
6777 // but writing to the same device.
6778 fflush(stderr);
6779#endif
6780}
6781
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006782MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6783 SourceLocation MacroDefLoc,
6784 CXTranslationUnit TU){
6785 if (MacroDefLoc.isInvalid() || !TU)
6786 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006787 if (!II.hadMacroDefinition())
6788 return 0;
6789
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006790 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006791 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006792 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006793 if (MD) {
6794 for (MacroDirective::DefInfo
6795 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6796 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6797 return Def.getMacroInfo();
6798 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006799 }
6800
6801 return 0;
6802}
6803
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006804const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6805 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006806 if (!MacroDef || !TU)
6807 return 0;
6808 const IdentifierInfo *II = MacroDef->getName();
6809 if (!II)
6810 return 0;
6811
6812 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6813}
6814
6815MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6816 const Token &Tok,
6817 CXTranslationUnit TU) {
6818 if (!MI || !TU)
6819 return 0;
6820 if (Tok.isNot(tok::raw_identifier))
6821 return 0;
6822
6823 if (MI->getNumTokens() == 0)
6824 return 0;
6825 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6826 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006827 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006828
6829 // Check that the token is inside the definition and not its argument list.
6830 SourceManager &SM = Unit->getSourceManager();
6831 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6832 return 0;
6833 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6834 return 0;
6835
6836 Preprocessor &PP = Unit->getPreprocessor();
6837 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6838 if (!PPRec)
6839 return 0;
6840
Alp Toker2d57cea2014-05-17 04:53:25 +00006841 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006842 if (!II.hadMacroDefinition())
6843 return 0;
6844
6845 // Check that the identifier is not one of the macro arguments.
6846 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6847 return 0;
6848
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006849 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6850 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006851 return 0;
6852
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006853 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006854}
6855
6856MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6857 SourceLocation Loc,
6858 CXTranslationUnit TU) {
6859 if (Loc.isInvalid() || !MI || !TU)
6860 return 0;
6861
6862 if (MI->getNumTokens() == 0)
6863 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006864 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006865 Preprocessor &PP = Unit->getPreprocessor();
6866 if (!PP.getPreprocessingRecord())
6867 return 0;
6868 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6869 Token Tok;
6870 if (PP.getRawToken(Loc, Tok))
6871 return 0;
6872
6873 return checkForMacroInMacroDefinition(MI, Tok, TU);
6874}
6875
Guy Benyei11169dd2012-12-18 14:30:41 +00006876extern "C" {
6877
6878CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006879 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006880}
6881
6882} // end: extern "C"
6883
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006884Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6885 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006886 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006887 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006888 if (Unit->isMainFileAST())
6889 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006890 return *this;
6891 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006892 } else {
6893 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006894 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006895 return *this;
6896}
6897
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006898Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6899 *this << FE->getName();
6900 return *this;
6901}
6902
6903Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6904 CXString cursorName = clang_getCursorDisplayName(cursor);
6905 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6906 clang_disposeString(cursorName);
6907 return *this;
6908}
6909
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006910Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6911 CXFile File;
6912 unsigned Line, Column;
6913 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6914 CXString FileName = clang_getFileName(File);
6915 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6916 clang_disposeString(FileName);
6917 return *this;
6918}
6919
6920Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6921 CXSourceLocation BLoc = clang_getRangeStart(range);
6922 CXSourceLocation ELoc = clang_getRangeEnd(range);
6923
6924 CXFile BFile;
6925 unsigned BLine, BColumn;
6926 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6927
6928 CXFile EFile;
6929 unsigned ELine, EColumn;
6930 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6931
6932 CXString BFileName = clang_getFileName(BFile);
6933 if (BFile == EFile) {
6934 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6935 BLine, BColumn, ELine, EColumn);
6936 } else {
6937 CXString EFileName = clang_getFileName(EFile);
6938 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6939 BLine, BColumn)
6940 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6941 ELine, EColumn);
6942 clang_disposeString(EFileName);
6943 }
6944 clang_disposeString(BFileName);
6945 return *this;
6946}
6947
6948Logger &cxindex::Logger::operator<<(CXString Str) {
6949 *this << clang_getCString(Str);
6950 return *this;
6951}
6952
6953Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6954 LogOS << Fmt;
6955 return *this;
6956}
6957
6958cxindex::Logger::~Logger() {
6959 LogOS.flush();
6960
6961 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6962
6963 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6964
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006965 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006966 OS << "[libclang:" << Name << ':';
6967
6968 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00006969#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006970 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6971 OS << tid << ':';
6972#endif
6973
6974 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6975 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6976 OS << Msg.str() << '\n';
6977
6978 if (Trace) {
6979 llvm::sys::PrintStackTrace(stderr);
6980 OS << "--------------------------------------------------\n";
6981 }
6982}