blob: 93cb0500df804c598e825edf200944cb0edbdfa2 [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)
Craig Topper69186e72014-06-08 08:38:04 +000066 return nullptr;
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();
Craig Topper69186e72014-06-08 08:38:04 +000072 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000074 D->CommentToXML = nullptr;
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;
Craig Topper69186e72014-06-08 08:38:04 +0000324 DeclContext *CurDC = nullptr;
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 {
Craig Topper69186e72014-06-08 08:38:04 +0000353 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000354 }
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,
Craig Topper69186e72014-06-08 08:38:04 +00001706 D, isFirst ? (void*) 1 : (void*) nullptr) {}
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);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001854 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001855 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001856 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001857 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858
Guy Benyei11169dd2012-12-18 14:30:41 +00001859private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001861 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1862 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1864 void AddStmt(const Stmt *S);
1865 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001867 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001868 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001869};
1870} // end anonyous namespace
1871
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001873 // 'S' should always be non-null, since it comes from the
1874 // statement we are visiting.
1875 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1876}
1877
1878void
1879EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1880 if (Qualifier)
1881 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1882}
1883
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 if (S)
1886 WL.push_back(StmtVisit(S, Parent));
1887}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001889 if (D)
1890 WL.push_back(DeclVisit(D, Parent, isFirst));
1891}
1892void EnqueueVisitor::
1893 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1894 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001895 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001896}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001898 if (D)
1899 WL.push_back(MemberRefVisit(D, L, Parent));
1900}
1901void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1902 if (TI)
1903 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1904 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001905void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001906 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001907 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001908 AddStmt(*Child);
1909 }
1910 if (size == WL.size())
1911 return;
1912 // Now reverse the entries we just added. This will match the DFS
1913 // ordering performed by the worklist.
1914 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1915 std::reverse(I, E);
1916}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001917namespace {
1918class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1919 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001920 /// \brief Process clauses with list of variables.
1921 template <typename T>
1922 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001923public:
1924 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1925#define OPENMP_CLAUSE(Name, Class) \
1926 void Visit##Class(const Class *C);
1927#include "clang/Basic/OpenMPKinds.def"
1928};
1929
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001930void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1931 Visitor->AddStmt(C->getCondition());
1932}
1933
Alexey Bataev568a8332014-03-06 06:15:19 +00001934void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1935 Visitor->AddStmt(C->getNumThreads());
1936}
1937
Alexey Bataev62c87d22014-03-21 04:51:18 +00001938void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1939 Visitor->AddStmt(C->getSafelen());
1940}
1941
Alexander Musman8bd31e62014-05-27 15:12:19 +00001942void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1943 Visitor->AddStmt(C->getNumForLoops());
1944}
1945
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001947
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001948void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1949
Alexey Bataev56dafe82014-06-20 07:16:17 +00001950void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1951 Visitor->AddStmt(C->getChunkSize());
1952}
1953
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001954void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1955
Alexey Bataev236070f2014-06-20 11:19:47 +00001956void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1957
Alexey Bataev756c1962013-09-24 03:17:45 +00001958template<typename T>
1959void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001960 for (const auto *I : Node->varlists())
1961 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001962}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001963
1964void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001965 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001966}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001967void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1968 const OMPFirstprivateClause *C) {
1969 VisitOMPClauseList(C);
1970}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001971void OMPClauseEnqueue::VisitOMPLastprivateClause(
1972 const OMPLastprivateClause *C) {
1973 VisitOMPClauseList(C);
1974}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001975void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001976 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001977}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001978void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1979 VisitOMPClauseList(C);
1980}
Alexander Musman8dba6642014-04-22 13:09:42 +00001981void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1982 VisitOMPClauseList(C);
1983 Visitor->AddStmt(C->getStep());
1984}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001985void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1986 VisitOMPClauseList(C);
1987 Visitor->AddStmt(C->getAlignment());
1988}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001989void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1990 VisitOMPClauseList(C);
1991}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001992}
Alexey Bataev756c1962013-09-24 03:17:45 +00001993
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001994void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1995 unsigned size = WL.size();
1996 OMPClauseEnqueue Visitor(this);
1997 Visitor.Visit(S);
1998 if (size == WL.size())
1999 return;
2000 // Now reverse the entries we just added. This will match the DFS
2001 // ordering performed by the worklist.
2002 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2003 std::reverse(I, E);
2004}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002005void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002006 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2007}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002008void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002009 AddDecl(B->getBlockDecl());
2010}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002011void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002012 EnqueueChildren(E);
2013 AddTypeLoc(E->getTypeSourceInfo());
2014}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002015void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2016 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002017 E = S->body_rend(); I != E; ++I) {
2018 AddStmt(*I);
2019 }
2020}
2021void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002022VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002023 AddStmt(S->getSubStmt());
2024 AddDeclarationNameInfo(S);
2025 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2026 AddNestedNameSpecifierLoc(QualifierLoc);
2027}
2028
2029void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002030VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002031 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2032 AddDeclarationNameInfo(E);
2033 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2034 AddNestedNameSpecifierLoc(QualifierLoc);
2035 if (!E->isImplicitAccess())
2036 AddStmt(E->getBase());
2037}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002039 // Enqueue the initializer , if any.
2040 AddStmt(E->getInitializer());
2041 // Enqueue the array size, if any.
2042 AddStmt(E->getArraySize());
2043 // Enqueue the allocated type.
2044 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2045 // Enqueue the placement arguments.
2046 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2047 AddStmt(E->getPlacementArg(I-1));
2048}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002050 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2051 AddStmt(CE->getArg(I-1));
2052 AddStmt(CE->getCallee());
2053 AddStmt(CE->getArg(0));
2054}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2056 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002057 // Visit the name of the type being destroyed.
2058 AddTypeLoc(E->getDestroyedTypeInfo());
2059 // Visit the scope type that looks disturbingly like the nested-name-specifier
2060 // but isn't.
2061 AddTypeLoc(E->getScopeTypeInfo());
2062 // Visit the nested-name-specifier.
2063 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2064 AddNestedNameSpecifierLoc(QualifierLoc);
2065 // Visit base expression.
2066 AddStmt(E->getBase());
2067}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2069 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 AddTypeLoc(E->getTypeSourceInfo());
2071}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002072void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2073 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 EnqueueChildren(E);
2075 AddTypeLoc(E->getTypeSourceInfo());
2076}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 EnqueueChildren(E);
2079 if (E->isTypeOperand())
2080 AddTypeLoc(E->getTypeOperandSourceInfo());
2081}
2082
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002083void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2084 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002085 EnqueueChildren(E);
2086 AddTypeLoc(E->getTypeSourceInfo());
2087}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 EnqueueChildren(E);
2090 if (E->isTypeOperand())
2091 AddTypeLoc(E->getTypeOperandSourceInfo());
2092}
2093
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002094void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002095 EnqueueChildren(S);
2096 AddDecl(S->getExceptionDecl());
2097}
2098
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002100 if (DR->hasExplicitTemplateArgs()) {
2101 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2102 }
2103 WL.push_back(DeclRefExprParts(DR, Parent));
2104}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002105void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2106 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002107 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2108 AddDeclarationNameInfo(E);
2109 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2110}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002111void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002112 unsigned size = WL.size();
2113 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002114 for (const auto *D : S->decls()) {
2115 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 isFirst = false;
2117 }
2118 if (size == WL.size())
2119 return;
2120 // Now reverse the entries we just added. This will match the DFS
2121 // ordering performed by the worklist.
2122 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2123 std::reverse(I, E);
2124}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002127 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 D = E->designators_rbegin(), DEnd = E->designators_rend();
2129 D != DEnd; ++D) {
2130 if (D->isFieldDesignator()) {
2131 if (FieldDecl *Field = D->getField())
2132 AddMemberRef(Field, D->getFieldLoc());
2133 continue;
2134 }
2135 if (D->isArrayDesignator()) {
2136 AddStmt(E->getArrayIndex(*D));
2137 continue;
2138 }
2139 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2140 AddStmt(E->getArrayRangeEnd(*D));
2141 AddStmt(E->getArrayRangeStart(*D));
2142 }
2143}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002144void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002145 EnqueueChildren(E);
2146 AddTypeLoc(E->getTypeInfoAsWritten());
2147}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002149 AddStmt(FS->getBody());
2150 AddStmt(FS->getInc());
2151 AddStmt(FS->getCond());
2152 AddDecl(FS->getConditionVariable());
2153 AddStmt(FS->getInit());
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 AddStmt(If->getElse());
2160 AddStmt(If->getThen());
2161 AddStmt(If->getCond());
2162 AddDecl(If->getConditionVariable());
2163}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 // We care about the syntactic form of the initializer list, only.
2166 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2167 IE = Syntactic;
2168 EnqueueChildren(IE);
2169}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002170void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002171 WL.push_back(MemberExprParts(M, Parent));
2172
2173 // If the base of the member access expression is an implicit 'this', don't
2174 // visit it.
2175 // FIXME: If we ever want to show these implicit accesses, this will be
2176 // unfortunate. However, clang_getCursor() relies on this behavior.
2177 if (!M->isImplicitAccess())
2178 AddStmt(M->getBase());
2179}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 AddTypeLoc(E->getEncodedTypeSourceInfo());
2182}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002184 EnqueueChildren(M);
2185 AddTypeLoc(M->getClassReceiverTypeInfo());
2186}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 // Visit the components of the offsetof expression.
2189 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2190 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2191 const OffsetOfNode &Node = E->getComponent(I-1);
2192 switch (Node.getKind()) {
2193 case OffsetOfNode::Array:
2194 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2195 break;
2196 case OffsetOfNode::Field:
2197 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2198 break;
2199 case OffsetOfNode::Identifier:
2200 case OffsetOfNode::Base:
2201 continue;
2202 }
2203 }
2204 // Visit the type into which we're computing the offset.
2205 AddTypeLoc(E->getTypeSourceInfo());
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2209 WL.push_back(OverloadExprParts(E, Parent));
2210}
2211void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 EnqueueChildren(E);
2214 if (E->isArgumentType())
2215 AddTypeLoc(E->getArgumentTypeInfo());
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 EnqueueChildren(S);
2219}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 AddStmt(S->getBody());
2222 AddStmt(S->getCond());
2223 AddDecl(S->getConditionVariable());
2224}
2225
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 AddStmt(W->getBody());
2228 AddStmt(W->getCond());
2229 AddDecl(W->getConditionVariable());
2230}
2231
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 for (unsigned I = E->getNumArgs(); I > 0; --I)
2234 AddTypeLoc(E->getArg(I-1));
2235}
2236
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002238 AddTypeLoc(E->getQueriedTypeSourceInfo());
2239}
2240
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002242 EnqueueChildren(E);
2243}
2244
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002246 VisitOverloadExpr(U);
2247 if (!U->isImplicitAccess())
2248 AddStmt(U->getBase());
2249}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 AddStmt(E->getSubExpr());
2252 AddTypeLoc(E->getWrittenTypeInfo());
2253}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002254void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002255 WL.push_back(SizeOfPackExprParts(E, Parent));
2256}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 // If the opaque value has a source expression, just transparently
2259 // visit that. This is useful for (e.g.) pseudo-object expressions.
2260 if (Expr *SourceExpr = E->getSourceExpr())
2261 return Visit(SourceExpr);
2262}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 AddStmt(E->getBody());
2265 WL.push_back(LambdaExprParts(E, Parent));
2266}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 // Treat the expression like its syntactic form.
2269 Visit(E->getSyntacticForm());
2270}
2271
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002272void EnqueueVisitor::VisitOMPExecutableDirective(
2273 const OMPExecutableDirective *D) {
2274 EnqueueChildren(D);
2275 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2276 E = D->clauses().end();
2277 I != E; ++I)
2278 EnqueueChildren(*I);
2279}
2280
2281void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2282 VisitOMPExecutableDirective(D);
2283}
2284
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002285void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2286 VisitOMPExecutableDirective(D);
2287}
2288
Alexey Bataevf29276e2014-06-18 04:14:57 +00002289void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2290 VisitOMPExecutableDirective(D);
2291}
2292
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002293void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2294 VisitOMPExecutableDirective(D);
2295}
2296
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002297void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2298 VisitOMPExecutableDirective(D);
2299}
2300
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002301void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2302 VisitOMPExecutableDirective(D);
2303}
2304
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002305void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002306 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2307}
2308
2309bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2310 if (RegionOfInterest.isValid()) {
2311 SourceRange Range = getRawCursorExtent(C);
2312 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2313 return false;
2314 }
2315 return true;
2316}
2317
2318bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2319 while (!WL.empty()) {
2320 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002321 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002322
2323 // Set the Parent field, then back to its old value once we're done.
2324 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2325
2326 switch (LI.getKind()) {
2327 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002328 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002329 if (!D)
2330 continue;
2331
2332 // For now, perform default visitation for Decls.
2333 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2334 cast<DeclVisit>(&LI)->isFirst())))
2335 return true;
2336
2337 continue;
2338 }
2339 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2340 const ASTTemplateArgumentListInfo *ArgList =
2341 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2342 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2343 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2344 Arg != ArgEnd; ++Arg) {
2345 if (VisitTemplateArgumentLoc(*Arg))
2346 return true;
2347 }
2348 continue;
2349 }
2350 case VisitorJob::TypeLocVisitKind: {
2351 // Perform default visitation for TypeLocs.
2352 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2353 return true;
2354 continue;
2355 }
2356 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002357 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002358 if (LabelStmt *stmt = LS->getStmt()) {
2359 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2360 TU))) {
2361 return true;
2362 }
2363 }
2364 continue;
2365 }
2366
2367 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2368 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2369 if (VisitNestedNameSpecifierLoc(V->get()))
2370 return true;
2371 continue;
2372 }
2373
2374 case VisitorJob::DeclarationNameInfoVisitKind: {
2375 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2376 ->get()))
2377 return true;
2378 continue;
2379 }
2380 case VisitorJob::MemberRefVisitKind: {
2381 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2382 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2383 return true;
2384 continue;
2385 }
2386 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002387 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002388 if (!S)
2389 continue;
2390
2391 // Update the current cursor.
2392 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2393 if (!IsInRegionOfInterest(Cursor))
2394 continue;
2395 switch (Visitor(Cursor, Parent, ClientData)) {
2396 case CXChildVisit_Break: return true;
2397 case CXChildVisit_Continue: break;
2398 case CXChildVisit_Recurse:
2399 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002400 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002401 EnqueueWorkList(WL, S);
2402 break;
2403 }
2404 continue;
2405 }
2406 case VisitorJob::MemberExprPartsKind: {
2407 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002408 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002409
2410 // Visit the nested-name-specifier
2411 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2412 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2413 return true;
2414
2415 // Visit the declaration name.
2416 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2417 return true;
2418
2419 // Visit the explicitly-specified template arguments, if any.
2420 if (M->hasExplicitTemplateArgs()) {
2421 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2422 *ArgEnd = Arg + M->getNumTemplateArgs();
2423 Arg != ArgEnd; ++Arg) {
2424 if (VisitTemplateArgumentLoc(*Arg))
2425 return true;
2426 }
2427 }
2428 continue;
2429 }
2430 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002431 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002432 // Visit nested-name-specifier, if present.
2433 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2434 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2435 return true;
2436 // Visit declaration name.
2437 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2438 return true;
2439 continue;
2440 }
2441 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002442 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002443 // Visit the nested-name-specifier.
2444 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2445 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2446 return true;
2447 // Visit the declaration name.
2448 if (VisitDeclarationNameInfo(O->getNameInfo()))
2449 return true;
2450 // Visit the overloaded declaration reference.
2451 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2452 return true;
2453 continue;
2454 }
2455 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002456 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002457 NamedDecl *Pack = E->getPack();
2458 if (isa<TemplateTypeParmDecl>(Pack)) {
2459 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2460 E->getPackLoc(), TU)))
2461 return true;
2462
2463 continue;
2464 }
2465
2466 if (isa<TemplateTemplateParmDecl>(Pack)) {
2467 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2468 E->getPackLoc(), TU)))
2469 return true;
2470
2471 continue;
2472 }
2473
2474 // Non-type template parameter packs and function parameter packs are
2475 // treated like DeclRefExpr cursors.
2476 continue;
2477 }
2478
2479 case VisitorJob::LambdaExprPartsKind: {
2480 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002481 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002482 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2483 CEnd = E->explicit_capture_end();
2484 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002485 // FIXME: Lambda init-captures.
2486 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002487 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002488
Guy Benyei11169dd2012-12-18 14:30:41 +00002489 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2490 C->getLocation(),
2491 TU)))
2492 return true;
2493 }
2494
2495 // Visit parameters and return type, if present.
2496 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2497 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2498 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2499 // Visit the whole type.
2500 if (Visit(TL))
2501 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002502 } else if (FunctionProtoTypeLoc Proto =
2503 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002504 if (E->hasExplicitParameters()) {
2505 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002506 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2507 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002508 return true;
2509 } else {
2510 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002511 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002512 return true;
2513 }
2514 }
2515 }
2516 break;
2517 }
2518
2519 case VisitorJob::PostChildrenVisitKind:
2520 if (PostChildrenVisitor(Parent, ClientData))
2521 return true;
2522 break;
2523 }
2524 }
2525 return false;
2526}
2527
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002528bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002529 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002530 if (!WorkListFreeList.empty()) {
2531 WL = WorkListFreeList.back();
2532 WL->clear();
2533 WorkListFreeList.pop_back();
2534 }
2535 else {
2536 WL = new VisitorWorkList();
2537 WorkListCache.push_back(WL);
2538 }
2539 EnqueueWorkList(*WL, S);
2540 bool result = RunVisitorWorkList(*WL);
2541 WorkListFreeList.push_back(WL);
2542 return result;
2543}
2544
2545namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002546typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002547RefNamePieces
2548buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2549 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2550 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002551 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2552 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2553 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2554
2555 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2556
2557 RefNamePieces Pieces;
2558
2559 if (WantQualifier && QLoc.isValid())
2560 Pieces.push_back(QLoc);
2561
2562 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2563 Pieces.push_back(NI.getLoc());
2564
2565 if (WantTemplateArgs && TemplateArgs)
2566 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2567 TemplateArgs->RAngleLoc));
2568
2569 if (Kind == DeclarationName::CXXOperatorName) {
2570 Pieces.push_back(SourceLocation::getFromRawEncoding(
2571 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2572 Pieces.push_back(SourceLocation::getFromRawEncoding(
2573 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2574 }
2575
2576 if (WantSinglePiece) {
2577 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2578 Pieces.clear();
2579 Pieces.push_back(R);
2580 }
2581
2582 return Pieces;
2583}
2584}
2585
2586//===----------------------------------------------------------------------===//
2587// Misc. API hooks.
2588//===----------------------------------------------------------------------===//
2589
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00002590static llvm::sys::Mutex EnableMultithreadingMutex;
2591static bool EnabledMultithreading;
Guy Benyei11169dd2012-12-18 14:30:41 +00002592
Chad Rosier05c71aa2013-03-27 18:28:23 +00002593static void fatal_error_handler(void *user_data, const std::string& reason,
2594 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002595 // Write the result out to stderr avoiding errs() because raw_ostreams can
2596 // call report_fatal_error.
2597 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2598 ::abort();
2599}
2600
2601extern "C" {
2602CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2603 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002604 // We use crash recovery to make some of our APIs more reliable, implicitly
2605 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002606 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2607 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002608
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00002609 // Enable support for multithreading in LLVM.
2610 {
2611 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2612 if (!EnabledMultithreading) {
2613 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2614 llvm::llvm_start_multithreaded();
2615 EnabledMultithreading = true;
2616 }
2617 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002618
2619 CIndexer *CIdxr = new CIndexer();
2620 if (excludeDeclarationsFromPCH)
2621 CIdxr->setOnlyLocalDecls();
2622 if (displayDiagnostics)
2623 CIdxr->setDisplayDiagnostics();
2624
2625 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2626 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2627 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2628 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2629 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2630 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2631
2632 return CIdxr;
2633}
2634
2635void clang_disposeIndex(CXIndex CIdx) {
2636 if (CIdx)
2637 delete static_cast<CIndexer *>(CIdx);
2638}
2639
2640void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2641 if (CIdx)
2642 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2643}
2644
2645unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2646 if (CIdx)
2647 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2648 return 0;
2649}
2650
2651void clang_toggleCrashRecovery(unsigned isEnabled) {
2652 if (isEnabled)
2653 llvm::CrashRecoveryContext::Enable();
2654 else
2655 llvm::CrashRecoveryContext::Disable();
2656}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002657
Guy Benyei11169dd2012-12-18 14:30:41 +00002658CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2659 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002660 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002661 enum CXErrorCode Result =
2662 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002663 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002664 assert((TU && Result == CXError_Success) ||
2665 (!TU && Result != CXError_Success));
2666 return TU;
2667}
2668
2669enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2670 const char *ast_filename,
2671 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002672 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002673 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002674
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002675 if (!CIdx || !ast_filename || !out_TU)
2676 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002677
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002678 LOG_FUNC_SECTION {
2679 *Log << ast_filename;
2680 }
2681
Guy Benyei11169dd2012-12-18 14:30:41 +00002682 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2683 FileSystemOptions FileSystemOpts;
2684
2685 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002686 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002687 CXXIdx->getOnlyLocalDecls(), None,
2688 /*CaptureDiagnostics=*/true,
2689 /*AllowPCHWithCompilerErrors=*/true,
2690 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002691 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2692 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002693}
2694
2695unsigned clang_defaultEditingTranslationUnitOptions() {
2696 return CXTranslationUnit_PrecompiledPreamble |
2697 CXTranslationUnit_CacheCompletionResults;
2698}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002699
Guy Benyei11169dd2012-12-18 14:30:41 +00002700CXTranslationUnit
2701clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2702 const char *source_filename,
2703 int num_command_line_args,
2704 const char * const *command_line_args,
2705 unsigned num_unsaved_files,
2706 struct CXUnsavedFile *unsaved_files) {
2707 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2708 return clang_parseTranslationUnit(CIdx, source_filename,
2709 command_line_args, num_command_line_args,
2710 unsaved_files, num_unsaved_files,
2711 Options);
2712}
2713
2714struct ParseTranslationUnitInfo {
2715 CXIndex CIdx;
2716 const char *source_filename;
2717 const char *const *command_line_args;
2718 int num_command_line_args;
2719 struct CXUnsavedFile *unsaved_files;
2720 unsigned num_unsaved_files;
2721 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002722 CXTranslationUnit *out_TU;
2723 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002724};
2725static void clang_parseTranslationUnit_Impl(void *UserData) {
2726 ParseTranslationUnitInfo *PTUI =
2727 static_cast<ParseTranslationUnitInfo*>(UserData);
2728 CXIndex CIdx = PTUI->CIdx;
2729 const char *source_filename = PTUI->source_filename;
2730 const char * const *command_line_args = PTUI->command_line_args;
2731 int num_command_line_args = PTUI->num_command_line_args;
2732 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2733 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2734 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002735 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002736
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002737 // Set up the initial return values.
2738 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002739 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002740 PTUI->result = CXError_Failure;
2741
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002742 // Check arguments.
2743 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002744 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002745 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002746 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002747 }
2748
Guy Benyei11169dd2012-12-18 14:30:41 +00002749 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2750
2751 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2752 setThreadBackgroundPriority();
2753
2754 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2755 // FIXME: Add a flag for modules.
2756 TranslationUnitKind TUKind
2757 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002758 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002759 = options & CXTranslationUnit_CacheCompletionResults;
2760 bool IncludeBriefCommentsInCodeCompletion
2761 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2762 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2763 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2764
2765 // Configure the diagnostics.
2766 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002767 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002768
2769 // Recover resources if we crash before exiting this function.
2770 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2771 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2772 DiagCleanup(Diags.getPtr());
2773
Ahmed Charlesb8984322014-03-07 20:03:18 +00002774 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2775 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002776
2777 // Recover resources if we crash before exiting this function.
2778 llvm::CrashRecoveryContextCleanupRegistrar<
2779 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2780
2781 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2782 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2783 const llvm::MemoryBuffer *Buffer
2784 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2785 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2786 Buffer));
2787 }
2788
Ahmed Charlesb8984322014-03-07 20:03:18 +00002789 std::unique_ptr<std::vector<const char *>> Args(
2790 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002791
2792 // Recover resources if we crash before exiting this method.
2793 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2794 ArgsCleanup(Args.get());
2795
2796 // Since the Clang C library is primarily used by batch tools dealing with
2797 // (often very broken) source code, where spell-checking can have a
2798 // significant negative impact on performance (particularly when
2799 // precompiled headers are involved), we disable it by default.
2800 // Only do this if we haven't found a spell-checking-related argument.
2801 bool FoundSpellCheckingArgument = false;
2802 for (int I = 0; I != num_command_line_args; ++I) {
2803 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2804 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2805 FoundSpellCheckingArgument = true;
2806 break;
2807 }
2808 }
2809 if (!FoundSpellCheckingArgument)
2810 Args->push_back("-fno-spell-checking");
2811
2812 Args->insert(Args->end(), command_line_args,
2813 command_line_args + num_command_line_args);
2814
2815 // The 'source_filename' argument is optional. If the caller does not
2816 // specify it then it is assumed that the source file is specified
2817 // in the actual argument list.
2818 // Put the source file after command_line_args otherwise if '-x' flag is
2819 // present it will be unused.
2820 if (source_filename)
2821 Args->push_back(source_filename);
2822
2823 // Do we need the detailed preprocessing record?
2824 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2825 Args->push_back("-Xclang");
2826 Args->push_back("-detailed-preprocessing-record");
2827 }
2828
2829 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002830 std::unique_ptr<ASTUnit> ErrUnit;
2831 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002832 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002833 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2834 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2835 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2836 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2837 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2838 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002839
2840 if (NumErrors != Diags->getClient()->getNumErrors()) {
2841 // Make sure to check that 'Unit' is non-NULL.
2842 if (CXXIdx->getDisplayDiagnostics())
2843 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2844 }
2845
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002846 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2847 PTUI->result = CXError_ASTReadError;
2848 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002849 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002850 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2851 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002852}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002853
2854CXTranslationUnit
2855clang_parseTranslationUnit(CXIndex CIdx,
2856 const char *source_filename,
2857 const char *const *command_line_args,
2858 int num_command_line_args,
2859 struct CXUnsavedFile *unsaved_files,
2860 unsigned num_unsaved_files,
2861 unsigned options) {
2862 CXTranslationUnit TU;
2863 enum CXErrorCode Result = clang_parseTranslationUnit2(
2864 CIdx, source_filename, command_line_args, num_command_line_args,
2865 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002866 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002867 assert((TU && Result == CXError_Success) ||
2868 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002869 return TU;
2870}
2871
2872enum CXErrorCode clang_parseTranslationUnit2(
2873 CXIndex CIdx,
2874 const char *source_filename,
2875 const char *const *command_line_args,
2876 int num_command_line_args,
2877 struct CXUnsavedFile *unsaved_files,
2878 unsigned num_unsaved_files,
2879 unsigned options,
2880 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002881 LOG_FUNC_SECTION {
2882 *Log << source_filename << ": ";
2883 for (int i = 0; i != num_command_line_args; ++i)
2884 *Log << command_line_args[i] << " ";
2885 }
2886
Guy Benyei11169dd2012-12-18 14:30:41 +00002887 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2888 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002889 num_unsaved_files, options, out_TU,
2890 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002891 llvm::CrashRecoveryContext CRC;
2892
2893 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2894 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2895 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2896 fprintf(stderr, " 'command_line_args' : [");
2897 for (int i = 0; i != num_command_line_args; ++i) {
2898 if (i)
2899 fprintf(stderr, ", ");
2900 fprintf(stderr, "'%s'", command_line_args[i]);
2901 }
2902 fprintf(stderr, "],\n");
2903 fprintf(stderr, " 'unsaved_files' : [");
2904 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2905 if (i)
2906 fprintf(stderr, ", ");
2907 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2908 unsaved_files[i].Length);
2909 }
2910 fprintf(stderr, "],\n");
2911 fprintf(stderr, " 'options' : %d,\n", options);
2912 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002913
2914 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002915 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002916 if (CXTranslationUnit *TU = PTUI.out_TU)
2917 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002918 }
2919
2920 return PTUI.result;
2921}
2922
2923unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2924 return CXSaveTranslationUnit_None;
2925}
2926
2927namespace {
2928
2929struct SaveTranslationUnitInfo {
2930 CXTranslationUnit TU;
2931 const char *FileName;
2932 unsigned options;
2933 CXSaveError result;
2934};
2935
2936}
2937
2938static void clang_saveTranslationUnit_Impl(void *UserData) {
2939 SaveTranslationUnitInfo *STUI =
2940 static_cast<SaveTranslationUnitInfo*>(UserData);
2941
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002942 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002943 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2944 setThreadBackgroundPriority();
2945
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002946 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002947 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2948}
2949
2950int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2951 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002952 LOG_FUNC_SECTION {
2953 *Log << TU << ' ' << FileName;
2954 }
2955
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002956 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002957 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002958 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002959 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002960
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002961 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002962 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2963 if (!CXXUnit->hasSema())
2964 return CXSaveError_InvalidTU;
2965
2966 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2967
2968 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2969 getenv("LIBCLANG_NOTHREADS")) {
2970 clang_saveTranslationUnit_Impl(&STUI);
2971
2972 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2973 PrintLibclangResourceUsage(TU);
2974
2975 return STUI.result;
2976 }
2977
2978 // We have an AST that has invalid nodes due to compiler errors.
2979 // Use a crash recovery thread for protection.
2980
2981 llvm::CrashRecoveryContext CRC;
2982
2983 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2984 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2985 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2986 fprintf(stderr, " 'options' : %d,\n", options);
2987 fprintf(stderr, "}\n");
2988
2989 return CXSaveError_Unknown;
2990
2991 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2992 PrintLibclangResourceUsage(TU);
2993 }
2994
2995 return STUI.result;
2996}
2997
2998void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2999 if (CTUnit) {
3000 // If the translation unit has been marked as unsafe to free, just discard
3001 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003002 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3003 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003004 return;
3005
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003006 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003007 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003008 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3009 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003010 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 delete CTUnit;
3012 }
3013}
3014
3015unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3016 return CXReparse_None;
3017}
3018
3019struct ReparseTranslationUnitInfo {
3020 CXTranslationUnit TU;
3021 unsigned num_unsaved_files;
3022 struct CXUnsavedFile *unsaved_files;
3023 unsigned options;
3024 int result;
3025};
3026
3027static void clang_reparseTranslationUnit_Impl(void *UserData) {
3028 ReparseTranslationUnitInfo *RTUI =
3029 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003030 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003031
Guy Benyei11169dd2012-12-18 14:30:41 +00003032 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003033 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3034 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3035 unsigned options = RTUI->options;
3036 (void) options;
3037
3038 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003039 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003040 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003041 RTUI->result = CXError_InvalidArguments;
3042 return;
3043 }
Craig Topper69186e72014-06-08 08:38:04 +00003044 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003045 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003046 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003047 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003048
3049 // Reset the associated diagnostics.
3050 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003051 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003052
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003053 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003054 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3055 setThreadBackgroundPriority();
3056
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003057 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003058 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003059
3060 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3061 new std::vector<ASTUnit::RemappedFile>());
3062
Guy Benyei11169dd2012-12-18 14:30:41 +00003063 // Recover resources if we crash before exiting this function.
3064 llvm::CrashRecoveryContextCleanupRegistrar<
3065 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3066
3067 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3068 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3069 const llvm::MemoryBuffer *Buffer
3070 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3071 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3072 Buffer));
3073 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003074
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003075 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003076 RTUI->result = CXError_Success;
3077 else if (isASTReadError(CXXUnit))
3078 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003079}
3080
3081int clang_reparseTranslationUnit(CXTranslationUnit TU,
3082 unsigned num_unsaved_files,
3083 struct CXUnsavedFile *unsaved_files,
3084 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003085 LOG_FUNC_SECTION {
3086 *Log << TU;
3087 }
3088
Guy Benyei11169dd2012-12-18 14:30:41 +00003089 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003090 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003091
3092 if (getenv("LIBCLANG_NOTHREADS")) {
3093 clang_reparseTranslationUnit_Impl(&RTUI);
3094 return RTUI.result;
3095 }
3096
3097 llvm::CrashRecoveryContext CRC;
3098
3099 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3100 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003101 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003102 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3104 PrintLibclangResourceUsage(TU);
3105
3106 return RTUI.result;
3107}
3108
3109
3110CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003111 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003112 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003113 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003114 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003115
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003116 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003117 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003118}
3119
3120CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003121 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003122 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003123 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003124 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003125
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003126 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003127 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3128}
3129
3130} // end: extern "C"
3131
3132//===----------------------------------------------------------------------===//
3133// CXFile Operations.
3134//===----------------------------------------------------------------------===//
3135
3136extern "C" {
3137CXString clang_getFileName(CXFile SFile) {
3138 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003139 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003140
3141 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003142 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003143}
3144
3145time_t clang_getFileTime(CXFile SFile) {
3146 if (!SFile)
3147 return 0;
3148
3149 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3150 return FEnt->getModificationTime();
3151}
3152
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003153CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003154 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003155 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003156 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003157 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003158
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003159 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003160
3161 FileManager &FMgr = CXXUnit->getFileManager();
3162 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3163}
3164
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003165unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3166 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003167 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003168 LOG_BAD_TU(TU);
3169 return 0;
3170 }
3171
3172 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 return 0;
3174
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003175 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 FileEntry *FEnt = static_cast<FileEntry *>(file);
3177 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3178 .isFileMultipleIncludeGuarded(FEnt);
3179}
3180
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003181int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3182 if (!file || !outID)
3183 return 1;
3184
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003185 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003186 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3187 outID->data[0] = ID.getDevice();
3188 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003189 outID->data[2] = FEnt->getModificationTime();
3190 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003191}
3192
Guy Benyei11169dd2012-12-18 14:30:41 +00003193} // end: extern "C"
3194
3195//===----------------------------------------------------------------------===//
3196// CXCursor Operations.
3197//===----------------------------------------------------------------------===//
3198
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003199static const Decl *getDeclFromExpr(const Stmt *E) {
3200 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 return getDeclFromExpr(CE->getSubExpr());
3202
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003203 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003205 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003207 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003209 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 if (PRE->isExplicitProperty())
3211 return PRE->getExplicitProperty();
3212 // It could be messaging both getter and setter as in:
3213 // ++myobj.myprop;
3214 // in which case prefer to associate the setter since it is less obvious
3215 // from inspecting the source that the setter is going to get called.
3216 if (PRE->isMessagingSetter())
3217 return PRE->getImplicitPropertySetter();
3218 return PRE->getImplicitPropertyGetter();
3219 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003220 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003222 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 if (Expr *Src = OVE->getSourceExpr())
3224 return getDeclFromExpr(Src);
3225
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003226 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003228 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 if (!CE->isElidable())
3230 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003231 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 return OME->getMethodDecl();
3233
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003234 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003236 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003237 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3238 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003239 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3241 isa<ParmVarDecl>(SizeOfPack->getPack()))
3242 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003243
3244 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003245}
3246
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003247static SourceLocation getLocationFromExpr(const Expr *E) {
3248 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003249 return getLocationFromExpr(CE->getSubExpr());
3250
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003251 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003252 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003253 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003255 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003257 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003258 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003259 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003261 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 return PropRef->getLocation();
3263
3264 return E->getLocStart();
3265}
3266
3267extern "C" {
3268
3269unsigned clang_visitChildren(CXCursor parent,
3270 CXCursorVisitor visitor,
3271 CXClientData client_data) {
3272 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3273 /*VisitPreprocessorLast=*/false);
3274 return CursorVis.VisitChildren(parent);
3275}
3276
3277#ifndef __has_feature
3278#define __has_feature(x) 0
3279#endif
3280#if __has_feature(blocks)
3281typedef enum CXChildVisitResult
3282 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3283
3284static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3285 CXClientData client_data) {
3286 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3287 return block(cursor, parent);
3288}
3289#else
3290// If we are compiled with a compiler that doesn't have native blocks support,
3291// define and call the block manually, so the
3292typedef struct _CXChildVisitResult
3293{
3294 void *isa;
3295 int flags;
3296 int reserved;
3297 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3298 CXCursor);
3299} *CXCursorVisitorBlock;
3300
3301static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3302 CXClientData client_data) {
3303 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3304 return block->invoke(block, cursor, parent);
3305}
3306#endif
3307
3308
3309unsigned clang_visitChildrenWithBlock(CXCursor parent,
3310 CXCursorVisitorBlock block) {
3311 return clang_visitChildren(parent, visitWithBlock, block);
3312}
3313
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003314static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003316 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003317
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003318 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003320 if (const ObjCPropertyImplDecl *PropImpl =
3321 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003323 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003324
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003325 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003327 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003328
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003329 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 }
3331
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003332 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003333 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003334
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003335 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3337 // and returns different names. NamedDecl returns the class name and
3338 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003339 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003340
3341 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003342 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003343
3344 SmallString<1024> S;
3345 llvm::raw_svector_ostream os(S);
3346 ND->printName(os);
3347
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003348 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003349}
3350
3351CXString clang_getCursorSpelling(CXCursor C) {
3352 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003353 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003354
3355 if (clang_isReference(C.kind)) {
3356 switch (C.kind) {
3357 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003358 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003359 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 }
3361 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003362 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003363 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 }
3365 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003366 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003368 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 }
3370 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003371 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003372 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 }
3374 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003375 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 assert(Type && "Missing type decl");
3377
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003378 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 getAsString());
3380 }
3381 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003382 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 assert(Template && "Missing template decl");
3384
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003385 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 }
3387
3388 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003389 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 assert(NS && "Missing namespace decl");
3391
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003392 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 }
3394
3395 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003396 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 assert(Field && "Missing member decl");
3398
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003399 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 }
3401
3402 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003403 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 assert(Label && "Missing label");
3405
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003406 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 }
3408
3409 case CXCursor_OverloadedDeclRef: {
3410 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003411 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3412 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003413 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003414 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003416 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003417 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 OverloadedTemplateStorage *Ovl
3419 = Storage.get<OverloadedTemplateStorage*>();
3420 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003421 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003422 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 }
3424
3425 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003426 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 assert(Var && "Missing variable decl");
3428
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003429 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003430 }
3431
3432 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003433 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 }
3435 }
3436
3437 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003438 const Expr *E = getCursorExpr(C);
3439
3440 if (C.kind == CXCursor_ObjCStringLiteral ||
3441 C.kind == CXCursor_StringLiteral) {
3442 const StringLiteral *SLit;
3443 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3444 SLit = OSL->getString();
3445 } else {
3446 SLit = cast<StringLiteral>(E);
3447 }
3448 SmallString<256> Buf;
3449 llvm::raw_svector_ostream OS(Buf);
3450 SLit->outputString(OS);
3451 return cxstring::createDup(OS.str());
3452 }
3453
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003454 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 if (D)
3456 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003457 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 }
3459
3460 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003461 const Stmt *S = getCursorStmt(C);
3462 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003463 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003464
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003465 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 }
3467
3468 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003469 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 ->getNameStart());
3471
3472 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003473 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 ->getNameStart());
3475
3476 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003477 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003478
3479 if (clang_isDeclaration(C.kind))
3480 return getDeclSpelling(getCursorDecl(C));
3481
3482 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003483 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003484 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 }
3486
3487 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003488 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003489 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 }
3491
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003492 if (C.kind == CXCursor_PackedAttr) {
3493 return cxstring::createRef("packed");
3494 }
3495
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003496 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003497}
3498
3499CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3500 unsigned pieceIndex,
3501 unsigned options) {
3502 if (clang_Cursor_isNull(C))
3503 return clang_getNullRange();
3504
3505 ASTContext &Ctx = getCursorContext(C);
3506
3507 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003508 const Stmt *S = getCursorStmt(C);
3509 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 if (pieceIndex > 0)
3511 return clang_getNullRange();
3512 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3513 }
3514
3515 return clang_getNullRange();
3516 }
3517
3518 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003519 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3521 if (pieceIndex >= ME->getNumSelectorLocs())
3522 return clang_getNullRange();
3523 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3524 }
3525 }
3526
3527 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3528 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003529 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3531 if (pieceIndex >= MD->getNumSelectorLocs())
3532 return clang_getNullRange();
3533 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3534 }
3535 }
3536
3537 if (C.kind == CXCursor_ObjCCategoryDecl ||
3538 C.kind == CXCursor_ObjCCategoryImplDecl) {
3539 if (pieceIndex > 0)
3540 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003541 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3543 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003544 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3546 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3547 }
3548
3549 if (C.kind == CXCursor_ModuleImportDecl) {
3550 if (pieceIndex > 0)
3551 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003552 if (const ImportDecl *ImportD =
3553 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3555 if (!Locs.empty())
3556 return cxloc::translateSourceRange(Ctx,
3557 SourceRange(Locs.front(), Locs.back()));
3558 }
3559 return clang_getNullRange();
3560 }
3561
3562 // FIXME: A CXCursor_InclusionDirective should give the location of the
3563 // filename, but we don't keep track of this.
3564
3565 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3566 // but we don't keep track of this.
3567
3568 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3569 // but we don't keep track of this.
3570
3571 // Default handling, give the location of the cursor.
3572
3573 if (pieceIndex > 0)
3574 return clang_getNullRange();
3575
3576 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3577 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3578 return cxloc::translateSourceRange(Ctx, Loc);
3579}
3580
3581CXString clang_getCursorDisplayName(CXCursor C) {
3582 if (!clang_isDeclaration(C.kind))
3583 return clang_getCursorSpelling(C);
3584
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003585 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003587 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003588
3589 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003590 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 D = FunTmpl->getTemplatedDecl();
3592
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003593 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 SmallString<64> Str;
3595 llvm::raw_svector_ostream OS(Str);
3596 OS << *Function;
3597 if (Function->getPrimaryTemplate())
3598 OS << "<>";
3599 OS << "(";
3600 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3601 if (I)
3602 OS << ", ";
3603 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3604 }
3605
3606 if (Function->isVariadic()) {
3607 if (Function->getNumParams())
3608 OS << ", ";
3609 OS << "...";
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 ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 SmallString<64> Str;
3617 llvm::raw_svector_ostream OS(Str);
3618 OS << *ClassTemplate;
3619 OS << "<";
3620 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3621 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3622 if (I)
3623 OS << ", ";
3624
3625 NamedDecl *Param = Params->getParam(I);
3626 if (Param->getIdentifier()) {
3627 OS << Param->getIdentifier()->getName();
3628 continue;
3629 }
3630
3631 // There is no parameter name, which makes this tricky. Try to come up
3632 // with something useful that isn't too long.
3633 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3634 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3635 else if (NonTypeTemplateParmDecl *NTTP
3636 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3637 OS << NTTP->getType().getAsString(Policy);
3638 else
3639 OS << "template<...> class";
3640 }
3641
3642 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003643 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 }
3645
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003646 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3648 // If the type was explicitly written, use that.
3649 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003650 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003651
Benjamin Kramer9170e912013-02-22 15:46:01 +00003652 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 llvm::raw_svector_ostream OS(Str);
3654 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003655 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 ClassSpec->getTemplateArgs().data(),
3657 ClassSpec->getTemplateArgs().size(),
3658 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003659 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 }
3661
3662 return clang_getCursorSpelling(C);
3663}
3664
3665CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3666 switch (Kind) {
3667 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003795 case CXCursor_ObjCSelfExpr:
3796 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003913 case CXCursor_PackedAttr:
3914 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003915 case CXCursor_PureAttr:
3916 return cxstring::createRef("attribute(pure)");
3917 case CXCursor_ConstAttr:
3918 return cxstring::createRef("attribute(const)");
3919 case CXCursor_NoDuplicateAttr:
3920 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003921 case CXCursor_CUDAConstantAttr:
3922 return cxstring::createRef("attribute(constant)");
3923 case CXCursor_CUDADeviceAttr:
3924 return cxstring::createRef("attribute(device)");
3925 case CXCursor_CUDAGlobalAttr:
3926 return cxstring::createRef("attribute(global)");
3927 case CXCursor_CUDAHostAttr:
3928 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003977 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003978 return cxstring::createRef("OMPParallelDirective");
3979 case CXCursor_OMPSimdDirective:
3980 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003981 case CXCursor_OMPForDirective:
3982 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00003983 case CXCursor_OMPSectionsDirective:
3984 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003985 case CXCursor_OMPSectionDirective:
3986 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00003987 case CXCursor_OMPSingleDirective:
3988 return cxstring::createRef("OMPSingleDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 }
3990
3991 llvm_unreachable("Unhandled CXCursorKind");
3992}
3993
3994struct GetCursorData {
3995 SourceLocation TokenBeginLoc;
3996 bool PointsAtMacroArgExpansion;
3997 bool VisitedObjCPropertyImplDecl;
3998 SourceLocation VisitedDeclaratorDeclStartLoc;
3999 CXCursor &BestCursor;
4000
4001 GetCursorData(SourceManager &SM,
4002 SourceLocation tokenBegin, CXCursor &outputCursor)
4003 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4004 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4005 VisitedObjCPropertyImplDecl = false;
4006 }
4007};
4008
4009static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4010 CXCursor parent,
4011 CXClientData client_data) {
4012 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4013 CXCursor *BestCursor = &Data->BestCursor;
4014
4015 // If we point inside a macro argument we should provide info of what the
4016 // token is so use the actual cursor, don't replace it with a macro expansion
4017 // cursor.
4018 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4019 return CXChildVisit_Recurse;
4020
4021 if (clang_isDeclaration(cursor.kind)) {
4022 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004023 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4025 if (MD->isImplicit())
4026 return CXChildVisit_Break;
4027
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004028 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4030 // Check that when we have multiple @class references in the same line,
4031 // that later ones do not override the previous ones.
4032 // If we have:
4033 // @class Foo, Bar;
4034 // source ranges for both start at '@', so 'Bar' will end up overriding
4035 // 'Foo' even though the cursor location was at 'Foo'.
4036 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4037 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004038 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4040 if (PrevID != ID &&
4041 !PrevID->isThisDeclarationADefinition() &&
4042 !ID->isThisDeclarationADefinition())
4043 return CXChildVisit_Break;
4044 }
4045
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004046 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4048 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4049 // Check that when we have multiple declarators in the same line,
4050 // that later ones do not override the previous ones.
4051 // If we have:
4052 // int Foo, Bar;
4053 // source ranges for both start at 'int', so 'Bar' will end up overriding
4054 // 'Foo' even though the cursor location was at 'Foo'.
4055 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4056 return CXChildVisit_Break;
4057 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4058
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004059 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4061 (void)PropImp;
4062 // Check that when we have multiple @synthesize in the same line,
4063 // that later ones do not override the previous ones.
4064 // If we have:
4065 // @synthesize Foo, Bar;
4066 // source ranges for both start at '@', so 'Bar' will end up overriding
4067 // 'Foo' even though the cursor location was at 'Foo'.
4068 if (Data->VisitedObjCPropertyImplDecl)
4069 return CXChildVisit_Break;
4070 Data->VisitedObjCPropertyImplDecl = true;
4071 }
4072 }
4073
4074 if (clang_isExpression(cursor.kind) &&
4075 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004076 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 // Avoid having the cursor of an expression replace the declaration cursor
4078 // when the expression source range overlaps the declaration range.
4079 // This can happen for C++ constructor expressions whose range generally
4080 // include the variable declaration, e.g.:
4081 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4082 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4083 D->getLocation() == Data->TokenBeginLoc)
4084 return CXChildVisit_Break;
4085 }
4086 }
4087
4088 // If our current best cursor is the construction of a temporary object,
4089 // don't replace that cursor with a type reference, because we want
4090 // clang_getCursor() to point at the constructor.
4091 if (clang_isExpression(BestCursor->kind) &&
4092 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4093 cursor.kind == CXCursor_TypeRef) {
4094 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4095 // as having the actual point on the type reference.
4096 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4097 return CXChildVisit_Recurse;
4098 }
4099
4100 *BestCursor = cursor;
4101 return CXChildVisit_Recurse;
4102}
4103
4104CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004105 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004106 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004108 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004109
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004110 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4112
4113 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4114 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4115
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004116 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 CXFile SearchFile;
4118 unsigned SearchLine, SearchColumn;
4119 CXFile ResultFile;
4120 unsigned ResultLine, ResultColumn;
4121 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4122 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4123 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004124
4125 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4126 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004127 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004128 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 SearchFileName = clang_getFileName(SearchFile);
4130 ResultFileName = clang_getFileName(ResultFile);
4131 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4132 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004133 *Log << llvm::format("(%s:%d:%d) = %s",
4134 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4135 clang_getCString(KindSpelling))
4136 << llvm::format("(%s:%d:%d):%s%s",
4137 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4138 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 clang_disposeString(SearchFileName);
4140 clang_disposeString(ResultFileName);
4141 clang_disposeString(KindSpelling);
4142 clang_disposeString(USR);
4143
4144 CXCursor Definition = clang_getCursorDefinition(Result);
4145 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4146 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4147 CXString DefinitionKindSpelling
4148 = clang_getCursorKindSpelling(Definition.kind);
4149 CXFile DefinitionFile;
4150 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004151 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004152 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004154 *Log << llvm::format(" -> %s(%s:%d:%d)",
4155 clang_getCString(DefinitionKindSpelling),
4156 clang_getCString(DefinitionFileName),
4157 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 clang_disposeString(DefinitionFileName);
4159 clang_disposeString(DefinitionKindSpelling);
4160 }
4161 }
4162
4163 return Result;
4164}
4165
4166CXCursor clang_getNullCursor(void) {
4167 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4168}
4169
4170unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004171 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4172 // can't set consistently. For example, when visiting a DeclStmt we will set
4173 // it but we don't set it on the result of clang_getCursorDefinition for
4174 // a reference of the same declaration.
4175 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4176 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4177 // to provide that kind of info.
4178 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004179 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004180 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004181 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004182
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 return X == Y;
4184}
4185
4186unsigned clang_hashCursor(CXCursor C) {
4187 unsigned Index = 0;
4188 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4189 Index = 1;
4190
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004191 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 std::make_pair(C.kind, C.data[Index]));
4193}
4194
4195unsigned clang_isInvalid(enum CXCursorKind K) {
4196 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4197}
4198
4199unsigned clang_isDeclaration(enum CXCursorKind K) {
4200 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4201 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4202}
4203
4204unsigned clang_isReference(enum CXCursorKind K) {
4205 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4206}
4207
4208unsigned clang_isExpression(enum CXCursorKind K) {
4209 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4210}
4211
4212unsigned clang_isStatement(enum CXCursorKind K) {
4213 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4214}
4215
4216unsigned clang_isAttribute(enum CXCursorKind K) {
4217 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4218}
4219
4220unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4221 return K == CXCursor_TranslationUnit;
4222}
4223
4224unsigned clang_isPreprocessing(enum CXCursorKind K) {
4225 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4226}
4227
4228unsigned clang_isUnexposed(enum CXCursorKind K) {
4229 switch (K) {
4230 case CXCursor_UnexposedDecl:
4231 case CXCursor_UnexposedExpr:
4232 case CXCursor_UnexposedStmt:
4233 case CXCursor_UnexposedAttr:
4234 return true;
4235 default:
4236 return false;
4237 }
4238}
4239
4240CXCursorKind clang_getCursorKind(CXCursor C) {
4241 return C.kind;
4242}
4243
4244CXSourceLocation clang_getCursorLocation(CXCursor C) {
4245 if (clang_isReference(C.kind)) {
4246 switch (C.kind) {
4247 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004248 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 = getCursorObjCSuperClassRef(C);
4250 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4251 }
4252
4253 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004254 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 = getCursorObjCProtocolRef(C);
4256 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4257 }
4258
4259 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004260 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 = getCursorObjCClassRef(C);
4262 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4263 }
4264
4265 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004266 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4268 }
4269
4270 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004271 std::pair<const TemplateDecl *, SourceLocation> P =
4272 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4274 }
4275
4276 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004277 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4279 }
4280
4281 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004282 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4284 }
4285
4286 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004287 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4289 }
4290
4291 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004292 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 if (!BaseSpec)
4294 return clang_getNullLocation();
4295
4296 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4297 return cxloc::translateSourceLocation(getCursorContext(C),
4298 TSInfo->getTypeLoc().getBeginLoc());
4299
4300 return cxloc::translateSourceLocation(getCursorContext(C),
4301 BaseSpec->getLocStart());
4302 }
4303
4304 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004305 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4307 }
4308
4309 case CXCursor_OverloadedDeclRef:
4310 return cxloc::translateSourceLocation(getCursorContext(C),
4311 getCursorOverloadedDeclRef(C).second);
4312
4313 default:
4314 // FIXME: Need a way to enumerate all non-reference cases.
4315 llvm_unreachable("Missed a reference kind");
4316 }
4317 }
4318
4319 if (clang_isExpression(C.kind))
4320 return cxloc::translateSourceLocation(getCursorContext(C),
4321 getLocationFromExpr(getCursorExpr(C)));
4322
4323 if (clang_isStatement(C.kind))
4324 return cxloc::translateSourceLocation(getCursorContext(C),
4325 getCursorStmt(C)->getLocStart());
4326
4327 if (C.kind == CXCursor_PreprocessingDirective) {
4328 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4329 return cxloc::translateSourceLocation(getCursorContext(C), L);
4330 }
4331
4332 if (C.kind == CXCursor_MacroExpansion) {
4333 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004334 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004335 return cxloc::translateSourceLocation(getCursorContext(C), L);
4336 }
4337
4338 if (C.kind == CXCursor_MacroDefinition) {
4339 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4340 return cxloc::translateSourceLocation(getCursorContext(C), L);
4341 }
4342
4343 if (C.kind == CXCursor_InclusionDirective) {
4344 SourceLocation L
4345 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4346 return cxloc::translateSourceLocation(getCursorContext(C), L);
4347 }
4348
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004349 if (clang_isAttribute(C.kind)) {
4350 SourceLocation L
4351 = cxcursor::getCursorAttr(C)->getLocation();
4352 return cxloc::translateSourceLocation(getCursorContext(C), L);
4353 }
4354
Guy Benyei11169dd2012-12-18 14:30:41 +00004355 if (!clang_isDeclaration(C.kind))
4356 return clang_getNullLocation();
4357
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004358 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004359 if (!D)
4360 return clang_getNullLocation();
4361
4362 SourceLocation Loc = D->getLocation();
4363 // FIXME: Multiple variables declared in a single declaration
4364 // currently lack the information needed to correctly determine their
4365 // ranges when accounting for the type-specifier. We use context
4366 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4367 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004368 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004369 if (!cxcursor::isFirstInDeclGroup(C))
4370 Loc = VD->getLocation();
4371 }
4372
4373 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004374 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004375 Loc = MD->getSelectorStartLoc();
4376
4377 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4378}
4379
4380} // end extern "C"
4381
4382CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4383 assert(TU);
4384
4385 // Guard against an invalid SourceLocation, or we may assert in one
4386 // of the following calls.
4387 if (SLoc.isInvalid())
4388 return clang_getNullCursor();
4389
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004390 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004391
4392 // Translate the given source location to make it point at the beginning of
4393 // the token under the cursor.
4394 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4395 CXXUnit->getASTContext().getLangOpts());
4396
4397 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4398 if (SLoc.isValid()) {
4399 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4400 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4401 /*VisitPreprocessorLast=*/true,
4402 /*VisitIncludedEntities=*/false,
4403 SourceLocation(SLoc));
4404 CursorVis.visitFileRegion();
4405 }
4406
4407 return Result;
4408}
4409
4410static SourceRange getRawCursorExtent(CXCursor C) {
4411 if (clang_isReference(C.kind)) {
4412 switch (C.kind) {
4413 case CXCursor_ObjCSuperClassRef:
4414 return getCursorObjCSuperClassRef(C).second;
4415
4416 case CXCursor_ObjCProtocolRef:
4417 return getCursorObjCProtocolRef(C).second;
4418
4419 case CXCursor_ObjCClassRef:
4420 return getCursorObjCClassRef(C).second;
4421
4422 case CXCursor_TypeRef:
4423 return getCursorTypeRef(C).second;
4424
4425 case CXCursor_TemplateRef:
4426 return getCursorTemplateRef(C).second;
4427
4428 case CXCursor_NamespaceRef:
4429 return getCursorNamespaceRef(C).second;
4430
4431 case CXCursor_MemberRef:
4432 return getCursorMemberRef(C).second;
4433
4434 case CXCursor_CXXBaseSpecifier:
4435 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4436
4437 case CXCursor_LabelRef:
4438 return getCursorLabelRef(C).second;
4439
4440 case CXCursor_OverloadedDeclRef:
4441 return getCursorOverloadedDeclRef(C).second;
4442
4443 case CXCursor_VariableRef:
4444 return getCursorVariableRef(C).second;
4445
4446 default:
4447 // FIXME: Need a way to enumerate all non-reference cases.
4448 llvm_unreachable("Missed a reference kind");
4449 }
4450 }
4451
4452 if (clang_isExpression(C.kind))
4453 return getCursorExpr(C)->getSourceRange();
4454
4455 if (clang_isStatement(C.kind))
4456 return getCursorStmt(C)->getSourceRange();
4457
4458 if (clang_isAttribute(C.kind))
4459 return getCursorAttr(C)->getRange();
4460
4461 if (C.kind == CXCursor_PreprocessingDirective)
4462 return cxcursor::getCursorPreprocessingDirective(C);
4463
4464 if (C.kind == CXCursor_MacroExpansion) {
4465 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004466 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 return TU->mapRangeFromPreamble(Range);
4468 }
4469
4470 if (C.kind == CXCursor_MacroDefinition) {
4471 ASTUnit *TU = getCursorASTUnit(C);
4472 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4473 return TU->mapRangeFromPreamble(Range);
4474 }
4475
4476 if (C.kind == CXCursor_InclusionDirective) {
4477 ASTUnit *TU = getCursorASTUnit(C);
4478 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4479 return TU->mapRangeFromPreamble(Range);
4480 }
4481
4482 if (C.kind == CXCursor_TranslationUnit) {
4483 ASTUnit *TU = getCursorASTUnit(C);
4484 FileID MainID = TU->getSourceManager().getMainFileID();
4485 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4486 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4487 return SourceRange(Start, End);
4488 }
4489
4490 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004491 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004492 if (!D)
4493 return SourceRange();
4494
4495 SourceRange R = D->getSourceRange();
4496 // FIXME: Multiple variables declared in a single declaration
4497 // currently lack the information needed to correctly determine their
4498 // ranges when accounting for the type-specifier. We use context
4499 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4500 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004501 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 if (!cxcursor::isFirstInDeclGroup(C))
4503 R.setBegin(VD->getLocation());
4504 }
4505 return R;
4506 }
4507 return SourceRange();
4508}
4509
4510/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4511/// the decl-specifier-seq for declarations.
4512static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4513 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004514 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 if (!D)
4516 return SourceRange();
4517
4518 SourceRange R = D->getSourceRange();
4519
4520 // Adjust the start of the location for declarations preceded by
4521 // declaration specifiers.
4522 SourceLocation StartLoc;
4523 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4524 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4525 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004526 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4528 StartLoc = TI->getTypeLoc().getLocStart();
4529 }
4530
4531 if (StartLoc.isValid() && R.getBegin().isValid() &&
4532 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4533 R.setBegin(StartLoc);
4534
4535 // FIXME: Multiple variables declared in a single declaration
4536 // currently lack the information needed to correctly determine their
4537 // ranges when accounting for the type-specifier. We use context
4538 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4539 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004540 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 if (!cxcursor::isFirstInDeclGroup(C))
4542 R.setBegin(VD->getLocation());
4543 }
4544
4545 return R;
4546 }
4547
4548 return getRawCursorExtent(C);
4549}
4550
4551extern "C" {
4552
4553CXSourceRange clang_getCursorExtent(CXCursor C) {
4554 SourceRange R = getRawCursorExtent(C);
4555 if (R.isInvalid())
4556 return clang_getNullRange();
4557
4558 return cxloc::translateSourceRange(getCursorContext(C), R);
4559}
4560
4561CXCursor clang_getCursorReferenced(CXCursor C) {
4562 if (clang_isInvalid(C.kind))
4563 return clang_getNullCursor();
4564
4565 CXTranslationUnit tu = getCursorTU(C);
4566 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004567 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 if (!D)
4569 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004570 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004572 if (const ObjCPropertyImplDecl *PropImpl =
4573 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004574 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4575 return MakeCXCursor(Property, tu);
4576
4577 return C;
4578 }
4579
4580 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004581 const Expr *E = getCursorExpr(C);
4582 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 if (D) {
4584 CXCursor declCursor = MakeCXCursor(D, tu);
4585 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4586 declCursor);
4587 return declCursor;
4588 }
4589
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004590 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 return MakeCursorOverloadedDeclRef(Ovl, tu);
4592
4593 return clang_getNullCursor();
4594 }
4595
4596 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004597 const Stmt *S = getCursorStmt(C);
4598 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 if (LabelDecl *label = Goto->getLabel())
4600 if (LabelStmt *labelS = label->getStmt())
4601 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4602
4603 return clang_getNullCursor();
4604 }
4605
4606 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004607 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 return MakeMacroDefinitionCursor(Def, tu);
4609 }
4610
4611 if (!clang_isReference(C.kind))
4612 return clang_getNullCursor();
4613
4614 switch (C.kind) {
4615 case CXCursor_ObjCSuperClassRef:
4616 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4617
4618 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004619 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4620 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 return MakeCXCursor(Def, tu);
4622
4623 return MakeCXCursor(Prot, tu);
4624 }
4625
4626 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004627 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4628 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 return MakeCXCursor(Def, tu);
4630
4631 return MakeCXCursor(Class, tu);
4632 }
4633
4634 case CXCursor_TypeRef:
4635 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4636
4637 case CXCursor_TemplateRef:
4638 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4639
4640 case CXCursor_NamespaceRef:
4641 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4642
4643 case CXCursor_MemberRef:
4644 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4645
4646 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004647 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004648 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4649 tu ));
4650 }
4651
4652 case CXCursor_LabelRef:
4653 // FIXME: We end up faking the "parent" declaration here because we
4654 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004655 return MakeCXCursor(getCursorLabelRef(C).first,
4656 cxtu::getASTUnit(tu)->getASTContext()
4657 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 tu);
4659
4660 case CXCursor_OverloadedDeclRef:
4661 return C;
4662
4663 case CXCursor_VariableRef:
4664 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4665
4666 default:
4667 // We would prefer to enumerate all non-reference cursor kinds here.
4668 llvm_unreachable("Unhandled reference cursor kind");
4669 }
4670}
4671
4672CXCursor clang_getCursorDefinition(CXCursor C) {
4673 if (clang_isInvalid(C.kind))
4674 return clang_getNullCursor();
4675
4676 CXTranslationUnit TU = getCursorTU(C);
4677
4678 bool WasReference = false;
4679 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4680 C = clang_getCursorReferenced(C);
4681 WasReference = true;
4682 }
4683
4684 if (C.kind == CXCursor_MacroExpansion)
4685 return clang_getCursorReferenced(C);
4686
4687 if (!clang_isDeclaration(C.kind))
4688 return clang_getNullCursor();
4689
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004690 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 if (!D)
4692 return clang_getNullCursor();
4693
4694 switch (D->getKind()) {
4695 // Declaration kinds that don't really separate the notions of
4696 // declaration and definition.
4697 case Decl::Namespace:
4698 case Decl::Typedef:
4699 case Decl::TypeAlias:
4700 case Decl::TypeAliasTemplate:
4701 case Decl::TemplateTypeParm:
4702 case Decl::EnumConstant:
4703 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004704 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 case Decl::IndirectField:
4706 case Decl::ObjCIvar:
4707 case Decl::ObjCAtDefsField:
4708 case Decl::ImplicitParam:
4709 case Decl::ParmVar:
4710 case Decl::NonTypeTemplateParm:
4711 case Decl::TemplateTemplateParm:
4712 case Decl::ObjCCategoryImpl:
4713 case Decl::ObjCImplementation:
4714 case Decl::AccessSpec:
4715 case Decl::LinkageSpec:
4716 case Decl::ObjCPropertyImpl:
4717 case Decl::FileScopeAsm:
4718 case Decl::StaticAssert:
4719 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004720 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 case Decl::Label: // FIXME: Is this right??
4722 case Decl::ClassScopeFunctionSpecialization:
4723 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004724 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 return C;
4726
4727 // Declaration kinds that don't make any sense here, but are
4728 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004729 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 case Decl::TranslationUnit:
4731 break;
4732
4733 // Declaration kinds for which the definition is not resolvable.
4734 case Decl::UnresolvedUsingTypename:
4735 case Decl::UnresolvedUsingValue:
4736 break;
4737
4738 case Decl::UsingDirective:
4739 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4740 TU);
4741
4742 case Decl::NamespaceAlias:
4743 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4744
4745 case Decl::Enum:
4746 case Decl::Record:
4747 case Decl::CXXRecord:
4748 case Decl::ClassTemplateSpecialization:
4749 case Decl::ClassTemplatePartialSpecialization:
4750 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4751 return MakeCXCursor(Def, TU);
4752 return clang_getNullCursor();
4753
4754 case Decl::Function:
4755 case Decl::CXXMethod:
4756 case Decl::CXXConstructor:
4757 case Decl::CXXDestructor:
4758 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004759 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004761 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004762 return clang_getNullCursor();
4763 }
4764
Larisse Voufo39a1e502013-08-06 01:03:05 +00004765 case Decl::Var:
4766 case Decl::VarTemplateSpecialization:
4767 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004769 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 return MakeCXCursor(Def, TU);
4771 return clang_getNullCursor();
4772 }
4773
4774 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004775 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004776 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4777 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4778 return clang_getNullCursor();
4779 }
4780
4781 case Decl::ClassTemplate: {
4782 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4783 ->getDefinition())
4784 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4785 TU);
4786 return clang_getNullCursor();
4787 }
4788
Larisse Voufo39a1e502013-08-06 01:03:05 +00004789 case Decl::VarTemplate: {
4790 if (VarDecl *Def =
4791 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4792 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4793 return clang_getNullCursor();
4794 }
4795
Guy Benyei11169dd2012-12-18 14:30:41 +00004796 case Decl::Using:
4797 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4798 D->getLocation(), TU);
4799
4800 case Decl::UsingShadow:
4801 return clang_getCursorDefinition(
4802 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4803 TU));
4804
4805 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004806 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 if (Method->isThisDeclarationADefinition())
4808 return C;
4809
4810 // Dig out the method definition in the associated
4811 // @implementation, if we have it.
4812 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004813 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4815 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4816 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4817 Method->isInstanceMethod()))
4818 if (Def->isThisDeclarationADefinition())
4819 return MakeCXCursor(Def, TU);
4820
4821 return clang_getNullCursor();
4822 }
4823
4824 case Decl::ObjCCategory:
4825 if (ObjCCategoryImplDecl *Impl
4826 = cast<ObjCCategoryDecl>(D)->getImplementation())
4827 return MakeCXCursor(Impl, TU);
4828 return clang_getNullCursor();
4829
4830 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004831 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 return MakeCXCursor(Def, TU);
4833 return clang_getNullCursor();
4834
4835 case Decl::ObjCInterface: {
4836 // There are two notions of a "definition" for an Objective-C
4837 // class: the interface and its implementation. When we resolved a
4838 // reference to an Objective-C class, produce the @interface as
4839 // the definition; when we were provided with the interface,
4840 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004841 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004842 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004843 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 return MakeCXCursor(Def, TU);
4845 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4846 return MakeCXCursor(Impl, TU);
4847 return clang_getNullCursor();
4848 }
4849
4850 case Decl::ObjCProperty:
4851 // FIXME: We don't really know where to find the
4852 // ObjCPropertyImplDecls that implement this property.
4853 return clang_getNullCursor();
4854
4855 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004856 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004858 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 return MakeCXCursor(Def, TU);
4860
4861 return clang_getNullCursor();
4862
4863 case Decl::Friend:
4864 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4865 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4866 return clang_getNullCursor();
4867
4868 case Decl::FriendTemplate:
4869 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4870 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4871 return clang_getNullCursor();
4872 }
4873
4874 return clang_getNullCursor();
4875}
4876
4877unsigned clang_isCursorDefinition(CXCursor C) {
4878 if (!clang_isDeclaration(C.kind))
4879 return 0;
4880
4881 return clang_getCursorDefinition(C) == C;
4882}
4883
4884CXCursor clang_getCanonicalCursor(CXCursor C) {
4885 if (!clang_isDeclaration(C.kind))
4886 return C;
4887
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004888 if (const Decl *D = getCursorDecl(C)) {
4889 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004890 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4891 return MakeCXCursor(CatD, getCursorTU(C));
4892
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004893 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4894 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004895 return MakeCXCursor(IFD, getCursorTU(C));
4896
4897 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4898 }
4899
4900 return C;
4901}
4902
4903int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4904 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4905}
4906
4907unsigned clang_getNumOverloadedDecls(CXCursor C) {
4908 if (C.kind != CXCursor_OverloadedDeclRef)
4909 return 0;
4910
4911 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004912 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 return E->getNumDecls();
4914
4915 if (OverloadedTemplateStorage *S
4916 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4917 return S->size();
4918
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004919 const Decl *D = Storage.get<const Decl *>();
4920 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 return Using->shadow_size();
4922
4923 return 0;
4924}
4925
4926CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4927 if (cursor.kind != CXCursor_OverloadedDeclRef)
4928 return clang_getNullCursor();
4929
4930 if (index >= clang_getNumOverloadedDecls(cursor))
4931 return clang_getNullCursor();
4932
4933 CXTranslationUnit TU = getCursorTU(cursor);
4934 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004935 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004936 return MakeCXCursor(E->decls_begin()[index], TU);
4937
4938 if (OverloadedTemplateStorage *S
4939 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4940 return MakeCXCursor(S->begin()[index], TU);
4941
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004942 const Decl *D = Storage.get<const Decl *>();
4943 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004944 // FIXME: This is, unfortunately, linear time.
4945 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4946 std::advance(Pos, index);
4947 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4948 }
4949
4950 return clang_getNullCursor();
4951}
4952
4953void clang_getDefinitionSpellingAndExtent(CXCursor C,
4954 const char **startBuf,
4955 const char **endBuf,
4956 unsigned *startLine,
4957 unsigned *startColumn,
4958 unsigned *endLine,
4959 unsigned *endColumn) {
4960 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004961 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004962 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4963
4964 SourceManager &SM = FD->getASTContext().getSourceManager();
4965 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4966 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4967 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4968 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4969 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4970 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4971}
4972
4973
4974CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4975 unsigned PieceIndex) {
4976 RefNamePieces Pieces;
4977
4978 switch (C.kind) {
4979 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004980 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004981 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4982 E->getQualifierLoc().getSourceRange());
4983 break;
4984
4985 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004986 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004987 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4988 E->getQualifierLoc().getSourceRange(),
4989 E->getOptionalExplicitTemplateArgs());
4990 break;
4991
4992 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004993 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004995 const Expr *Callee = OCE->getCallee();
4996 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004997 Callee = ICE->getSubExpr();
4998
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004999 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5001 DRE->getQualifierLoc().getSourceRange());
5002 }
5003 break;
5004
5005 default:
5006 break;
5007 }
5008
5009 if (Pieces.empty()) {
5010 if (PieceIndex == 0)
5011 return clang_getCursorExtent(C);
5012 } else if (PieceIndex < Pieces.size()) {
5013 SourceRange R = Pieces[PieceIndex];
5014 if (R.isValid())
5015 return cxloc::translateSourceRange(getCursorContext(C), R);
5016 }
5017
5018 return clang_getNullRange();
5019}
5020
5021void clang_enableStackTraces(void) {
5022 llvm::sys::PrintStackTraceOnErrorSignal();
5023}
5024
5025void clang_executeOnThread(void (*fn)(void*), void *user_data,
5026 unsigned stack_size) {
5027 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5028}
5029
5030} // end: extern "C"
5031
5032//===----------------------------------------------------------------------===//
5033// Token-based Operations.
5034//===----------------------------------------------------------------------===//
5035
5036/* CXToken layout:
5037 * int_data[0]: a CXTokenKind
5038 * int_data[1]: starting token location
5039 * int_data[2]: token length
5040 * int_data[3]: reserved
5041 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5042 * otherwise unused.
5043 */
5044extern "C" {
5045
5046CXTokenKind clang_getTokenKind(CXToken CXTok) {
5047 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5048}
5049
5050CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5051 switch (clang_getTokenKind(CXTok)) {
5052 case CXToken_Identifier:
5053 case CXToken_Keyword:
5054 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005055 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 ->getNameStart());
5057
5058 case CXToken_Literal: {
5059 // We have stashed the starting pointer in the ptr_data field. Use it.
5060 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005061 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005062 }
5063
5064 case CXToken_Punctuation:
5065 case CXToken_Comment:
5066 break;
5067 }
5068
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005069 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005070 LOG_BAD_TU(TU);
5071 return cxstring::createEmpty();
5072 }
5073
Guy Benyei11169dd2012-12-18 14:30:41 +00005074 // We have to find the starting buffer pointer the hard way, by
5075 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005076 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005077 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005078 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005079
5080 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5081 std::pair<FileID, unsigned> LocInfo
5082 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5083 bool Invalid = false;
5084 StringRef Buffer
5085 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5086 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005087 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005088
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005089 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005090}
5091
5092CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005093 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005094 LOG_BAD_TU(TU);
5095 return clang_getNullLocation();
5096 }
5097
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005098 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 if (!CXXUnit)
5100 return clang_getNullLocation();
5101
5102 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5103 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5104}
5105
5106CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005107 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005108 LOG_BAD_TU(TU);
5109 return clang_getNullRange();
5110 }
5111
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005112 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005113 if (!CXXUnit)
5114 return clang_getNullRange();
5115
5116 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5117 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5118}
5119
5120static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5121 SmallVectorImpl<CXToken> &CXTokens) {
5122 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5123 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005124 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005125 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005126 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005127
5128 // Cannot tokenize across files.
5129 if (BeginLocInfo.first != EndLocInfo.first)
5130 return;
5131
5132 // Create a lexer
5133 bool Invalid = false;
5134 StringRef Buffer
5135 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5136 if (Invalid)
5137 return;
5138
5139 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5140 CXXUnit->getASTContext().getLangOpts(),
5141 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5142 Lex.SetCommentRetentionState(true);
5143
5144 // Lex tokens until we hit the end of the range.
5145 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5146 Token Tok;
5147 bool previousWasAt = false;
5148 do {
5149 // Lex the next token
5150 Lex.LexFromRawLexer(Tok);
5151 if (Tok.is(tok::eof))
5152 break;
5153
5154 // Initialize the CXToken.
5155 CXToken CXTok;
5156
5157 // - Common fields
5158 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5159 CXTok.int_data[2] = Tok.getLength();
5160 CXTok.int_data[3] = 0;
5161
5162 // - Kind-specific fields
5163 if (Tok.isLiteral()) {
5164 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005165 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 } else if (Tok.is(tok::raw_identifier)) {
5167 // Lookup the identifier to determine whether we have a keyword.
5168 IdentifierInfo *II
5169 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5170
5171 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5172 CXTok.int_data[0] = CXToken_Keyword;
5173 }
5174 else {
5175 CXTok.int_data[0] = Tok.is(tok::identifier)
5176 ? CXToken_Identifier
5177 : CXToken_Keyword;
5178 }
5179 CXTok.ptr_data = II;
5180 } else if (Tok.is(tok::comment)) {
5181 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005182 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005183 } else {
5184 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005185 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 }
5187 CXTokens.push_back(CXTok);
5188 previousWasAt = Tok.is(tok::at);
5189 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5190}
5191
5192void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5193 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005194 LOG_FUNC_SECTION {
5195 *Log << TU << ' ' << Range;
5196 }
5197
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005199 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 if (NumTokens)
5201 *NumTokens = 0;
5202
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005203 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005204 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005205 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005206 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005207
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005208 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 if (!CXXUnit || !Tokens || !NumTokens)
5210 return;
5211
5212 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5213
5214 SourceRange R = cxloc::translateCXSourceRange(Range);
5215 if (R.isInvalid())
5216 return;
5217
5218 SmallVector<CXToken, 32> CXTokens;
5219 getTokens(CXXUnit, R, CXTokens);
5220
5221 if (CXTokens.empty())
5222 return;
5223
5224 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5225 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5226 *NumTokens = CXTokens.size();
5227}
5228
5229void clang_disposeTokens(CXTranslationUnit TU,
5230 CXToken *Tokens, unsigned NumTokens) {
5231 free(Tokens);
5232}
5233
5234} // end: extern "C"
5235
5236//===----------------------------------------------------------------------===//
5237// Token annotation APIs.
5238//===----------------------------------------------------------------------===//
5239
Guy Benyei11169dd2012-12-18 14:30:41 +00005240static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5241 CXCursor parent,
5242 CXClientData client_data);
5243static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5244 CXClientData client_data);
5245
5246namespace {
5247class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 CXToken *Tokens;
5249 CXCursor *Cursors;
5250 unsigned NumTokens;
5251 unsigned TokIdx;
5252 unsigned PreprocessingTokIdx;
5253 CursorVisitor AnnotateVis;
5254 SourceManager &SrcMgr;
5255 bool HasContextSensitiveKeywords;
5256
5257 struct PostChildrenInfo {
5258 CXCursor Cursor;
5259 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005260 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005261 unsigned BeforeChildrenTokenIdx;
5262 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005263 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005264
5265 CXToken &getTok(unsigned Idx) {
5266 assert(Idx < NumTokens);
5267 return Tokens[Idx];
5268 }
5269 const CXToken &getTok(unsigned Idx) const {
5270 assert(Idx < NumTokens);
5271 return Tokens[Idx];
5272 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005273 bool MoreTokens() const { return TokIdx < NumTokens; }
5274 unsigned NextToken() const { return TokIdx; }
5275 void AdvanceToken() { ++TokIdx; }
5276 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005277 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 }
5279 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005280 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005281 }
5282 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005283 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 }
5285
5286 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005287 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 SourceRange);
5289
5290public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005291 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005292 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005293 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005295 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 AnnotateTokensVisitor, this,
5297 /*VisitPreprocessorLast=*/true,
5298 /*VisitIncludedEntities=*/false,
5299 RegionOfInterest,
5300 /*VisitDeclsOnly=*/false,
5301 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005302 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 HasContextSensitiveKeywords(false) { }
5304
5305 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5306 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5307 bool postVisitChildren(CXCursor cursor);
5308 void AnnotateTokens();
5309
5310 /// \brief Determine whether the annotator saw any cursors that have
5311 /// context-sensitive keywords.
5312 bool hasContextSensitiveKeywords() const {
5313 return HasContextSensitiveKeywords;
5314 }
5315
5316 ~AnnotateTokensWorker() {
5317 assert(PostChildrenInfos.empty());
5318 }
5319};
5320}
5321
5322void AnnotateTokensWorker::AnnotateTokens() {
5323 // Walk the AST within the region of interest, annotating tokens
5324 // along the way.
5325 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005326}
Guy Benyei11169dd2012-12-18 14:30:41 +00005327
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005328static inline void updateCursorAnnotation(CXCursor &Cursor,
5329 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005330 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005331 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005332 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005333}
5334
5335/// \brief It annotates and advances tokens with a cursor until the comparison
5336//// between the cursor location and the source range is the same as
5337/// \arg compResult.
5338///
5339/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5340/// Pass RangeOverlap to annotate tokens inside a range.
5341void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5342 RangeComparisonResult compResult,
5343 SourceRange range) {
5344 while (MoreTokens()) {
5345 const unsigned I = NextToken();
5346 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005347 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5348 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005349
5350 SourceLocation TokLoc = GetTokenLoc(I);
5351 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005352 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005353 AdvanceToken();
5354 continue;
5355 }
5356 break;
5357 }
5358}
5359
5360/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005361/// \returns true if it advanced beyond all macro tokens, false otherwise.
5362bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005363 CXCursor updateC,
5364 RangeComparisonResult compResult,
5365 SourceRange range) {
5366 assert(MoreTokens());
5367 assert(isFunctionMacroToken(NextToken()) &&
5368 "Should be called only for macro arg tokens");
5369
5370 // This works differently than annotateAndAdvanceTokens; because expanded
5371 // macro arguments can have arbitrary translation-unit source order, we do not
5372 // advance the token index one by one until a token fails the range test.
5373 // We only advance once past all of the macro arg tokens if all of them
5374 // pass the range test. If one of them fails we keep the token index pointing
5375 // at the start of the macro arg tokens so that the failing token will be
5376 // annotated by a subsequent annotation try.
5377
5378 bool atLeastOneCompFail = false;
5379
5380 unsigned I = NextToken();
5381 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5382 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5383 if (TokLoc.isFileID())
5384 continue; // not macro arg token, it's parens or comma.
5385 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5386 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5387 Cursors[I] = updateC;
5388 } else
5389 atLeastOneCompFail = true;
5390 }
5391
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005392 if (atLeastOneCompFail)
5393 return false;
5394
5395 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5396 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005397}
5398
5399enum CXChildVisitResult
5400AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005401 SourceRange cursorRange = getRawCursorExtent(cursor);
5402 if (cursorRange.isInvalid())
5403 return CXChildVisit_Recurse;
5404
5405 if (!HasContextSensitiveKeywords) {
5406 // Objective-C properties can have context-sensitive keywords.
5407 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005408 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005409 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5410 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5411 }
5412 // Objective-C methods can have context-sensitive keywords.
5413 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5414 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005415 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005416 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5417 if (Method->getObjCDeclQualifier())
5418 HasContextSensitiveKeywords = true;
5419 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005420 for (const auto *P : Method->params()) {
5421 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 HasContextSensitiveKeywords = true;
5423 break;
5424 }
5425 }
5426 }
5427 }
5428 }
5429 // C++ methods can have context-sensitive keywords.
5430 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005431 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005432 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5433 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5434 HasContextSensitiveKeywords = true;
5435 }
5436 }
5437 // C++ classes can have context-sensitive keywords.
5438 else if (cursor.kind == CXCursor_StructDecl ||
5439 cursor.kind == CXCursor_ClassDecl ||
5440 cursor.kind == CXCursor_ClassTemplate ||
5441 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005442 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 if (D->hasAttr<FinalAttr>())
5444 HasContextSensitiveKeywords = true;
5445 }
5446 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005447
5448 // Don't override a property annotation with its getter/setter method.
5449 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5450 parent.kind == CXCursor_ObjCPropertyDecl)
5451 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005452
5453 if (clang_isPreprocessing(cursor.kind)) {
5454 // Items in the preprocessing record are kept separate from items in
5455 // declarations, so we keep a separate token index.
5456 unsigned SavedTokIdx = TokIdx;
5457 TokIdx = PreprocessingTokIdx;
5458
5459 // Skip tokens up until we catch up to the beginning of the preprocessing
5460 // entry.
5461 while (MoreTokens()) {
5462 const unsigned I = NextToken();
5463 SourceLocation TokLoc = GetTokenLoc(I);
5464 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5465 case RangeBefore:
5466 AdvanceToken();
5467 continue;
5468 case RangeAfter:
5469 case RangeOverlap:
5470 break;
5471 }
5472 break;
5473 }
5474
5475 // Look at all of the tokens within this range.
5476 while (MoreTokens()) {
5477 const unsigned I = NextToken();
5478 SourceLocation TokLoc = GetTokenLoc(I);
5479 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5480 case RangeBefore:
5481 llvm_unreachable("Infeasible");
5482 case RangeAfter:
5483 break;
5484 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005485 // For macro expansions, just note where the beginning of the macro
5486 // expansion occurs.
5487 if (cursor.kind == CXCursor_MacroExpansion) {
5488 if (TokLoc == cursorRange.getBegin())
5489 Cursors[I] = cursor;
5490 AdvanceToken();
5491 break;
5492 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005493 // We may have already annotated macro names inside macro definitions.
5494 if (Cursors[I].kind != CXCursor_MacroExpansion)
5495 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005496 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 continue;
5498 }
5499 break;
5500 }
5501
5502 // Save the preprocessing token index; restore the non-preprocessing
5503 // token index.
5504 PreprocessingTokIdx = TokIdx;
5505 TokIdx = SavedTokIdx;
5506 return CXChildVisit_Recurse;
5507 }
5508
5509 if (cursorRange.isInvalid())
5510 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005511
5512 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005513 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005514 const enum CXCursorKind K = clang_getCursorKind(parent);
5515 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005516 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5517 // Attributes are annotated out-of-order, skip tokens until we reach it.
5518 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005519 ? clang_getNullCursor() : parent;
5520
5521 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5522
5523 // Avoid having the cursor of an expression "overwrite" the annotation of the
5524 // variable declaration that it belongs to.
5525 // This can happen for C++ constructor expressions whose range generally
5526 // include the variable declaration, e.g.:
5527 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005528 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005529 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005530 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005531 const unsigned I = NextToken();
5532 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5533 E->getLocStart() == D->getLocation() &&
5534 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005535 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005536 AdvanceToken();
5537 }
5538 }
5539 }
5540
5541 // Before recursing into the children keep some state that we are going
5542 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5543 // extra work after the child nodes are visited.
5544 // Note that we don't call VisitChildren here to avoid traversing statements
5545 // code-recursively which can blow the stack.
5546
5547 PostChildrenInfo Info;
5548 Info.Cursor = cursor;
5549 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005550 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005551 Info.BeforeChildrenTokenIdx = NextToken();
5552 PostChildrenInfos.push_back(Info);
5553
5554 return CXChildVisit_Recurse;
5555}
5556
5557bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5558 if (PostChildrenInfos.empty())
5559 return false;
5560 const PostChildrenInfo &Info = PostChildrenInfos.back();
5561 if (!clang_equalCursors(Info.Cursor, cursor))
5562 return false;
5563
5564 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5565 const unsigned AfterChildren = NextToken();
5566 SourceRange cursorRange = Info.CursorRange;
5567
5568 // Scan the tokens that are at the end of the cursor, but are not captured
5569 // but the child cursors.
5570 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5571
5572 // Scan the tokens that are at the beginning of the cursor, but are not
5573 // capture by the child cursors.
5574 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5575 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5576 break;
5577
5578 Cursors[I] = cursor;
5579 }
5580
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005581 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5582 // encountered the attribute cursor.
5583 if (clang_isAttribute(cursor.kind))
5584 TokIdx = Info.BeforeReachingCursorIdx;
5585
Guy Benyei11169dd2012-12-18 14:30:41 +00005586 PostChildrenInfos.pop_back();
5587 return false;
5588}
5589
5590static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5591 CXCursor parent,
5592 CXClientData client_data) {
5593 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5594}
5595
5596static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5597 CXClientData client_data) {
5598 return static_cast<AnnotateTokensWorker*>(client_data)->
5599 postVisitChildren(cursor);
5600}
5601
5602namespace {
5603
5604/// \brief Uses the macro expansions in the preprocessing record to find
5605/// and mark tokens that are macro arguments. This info is used by the
5606/// AnnotateTokensWorker.
5607class MarkMacroArgTokensVisitor {
5608 SourceManager &SM;
5609 CXToken *Tokens;
5610 unsigned NumTokens;
5611 unsigned CurIdx;
5612
5613public:
5614 MarkMacroArgTokensVisitor(SourceManager &SM,
5615 CXToken *tokens, unsigned numTokens)
5616 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5617
5618 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5619 if (cursor.kind != CXCursor_MacroExpansion)
5620 return CXChildVisit_Continue;
5621
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005622 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005623 if (macroRange.getBegin() == macroRange.getEnd())
5624 return CXChildVisit_Continue; // it's not a function macro.
5625
5626 for (; CurIdx < NumTokens; ++CurIdx) {
5627 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5628 macroRange.getBegin()))
5629 break;
5630 }
5631
5632 if (CurIdx == NumTokens)
5633 return CXChildVisit_Break;
5634
5635 for (; CurIdx < NumTokens; ++CurIdx) {
5636 SourceLocation tokLoc = getTokenLoc(CurIdx);
5637 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5638 break;
5639
5640 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5641 }
5642
5643 if (CurIdx == NumTokens)
5644 return CXChildVisit_Break;
5645
5646 return CXChildVisit_Continue;
5647 }
5648
5649private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005650 CXToken &getTok(unsigned Idx) {
5651 assert(Idx < NumTokens);
5652 return Tokens[Idx];
5653 }
5654 const CXToken &getTok(unsigned Idx) const {
5655 assert(Idx < NumTokens);
5656 return Tokens[Idx];
5657 }
5658
Guy Benyei11169dd2012-12-18 14:30:41 +00005659 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005660 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005661 }
5662
5663 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5664 // The third field is reserved and currently not used. Use it here
5665 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005666 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 }
5668};
5669
5670} // end anonymous namespace
5671
5672static CXChildVisitResult
5673MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5674 CXClientData client_data) {
5675 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5676 parent);
5677}
5678
5679namespace {
5680 struct clang_annotateTokens_Data {
5681 CXTranslationUnit TU;
5682 ASTUnit *CXXUnit;
5683 CXToken *Tokens;
5684 unsigned NumTokens;
5685 CXCursor *Cursors;
5686 };
5687}
5688
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005689/// \brief Used by \c annotatePreprocessorTokens.
5690/// \returns true if lexing was finished, false otherwise.
5691static bool lexNext(Lexer &Lex, Token &Tok,
5692 unsigned &NextIdx, unsigned NumTokens) {
5693 if (NextIdx >= NumTokens)
5694 return true;
5695
5696 ++NextIdx;
5697 Lex.LexFromRawLexer(Tok);
5698 if (Tok.is(tok::eof))
5699 return true;
5700
5701 return false;
5702}
5703
Guy Benyei11169dd2012-12-18 14:30:41 +00005704static void annotatePreprocessorTokens(CXTranslationUnit TU,
5705 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005706 CXCursor *Cursors,
5707 CXToken *Tokens,
5708 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005709 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005710
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005711 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005712 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5713 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005714 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005715 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005716 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005717
5718 if (BeginLocInfo.first != EndLocInfo.first)
5719 return;
5720
5721 StringRef Buffer;
5722 bool Invalid = false;
5723 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5724 if (Buffer.empty() || Invalid)
5725 return;
5726
5727 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5728 CXXUnit->getASTContext().getLangOpts(),
5729 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5730 Buffer.end());
5731 Lex.SetCommentRetentionState(true);
5732
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005733 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 // Lex tokens in raw mode until we hit the end of the range, to avoid
5735 // entering #includes or expanding macros.
5736 while (true) {
5737 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005738 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5739 break;
5740 unsigned TokIdx = NextIdx-1;
5741 assert(Tok.getLocation() ==
5742 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005743
5744 reprocess:
5745 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005746 // We have found a preprocessing directive. Annotate the tokens
5747 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005748 //
5749 // FIXME: Some simple tests here could identify macro definitions and
5750 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005751
5752 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005753 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5754 break;
5755
Craig Topper69186e72014-06-08 08:38:04 +00005756 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005757 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005758 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5759 break;
5760
5761 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005762 IdentifierInfo &II =
5763 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005764 SourceLocation MappedTokLoc =
5765 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5766 MI = getMacroInfo(II, MappedTokLoc, TU);
5767 }
5768 }
5769
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005770 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005771 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005772 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5773 finished = true;
5774 break;
5775 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005776 // If we are in a macro definition, check if the token was ever a
5777 // macro name and annotate it if that's the case.
5778 if (MI) {
5779 SourceLocation SaveLoc = Tok.getLocation();
5780 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5781 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5782 Tok.setLocation(SaveLoc);
5783 if (MacroDef)
5784 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5785 Tok.getLocation(), TU);
5786 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005787 } while (!Tok.isAtStartOfLine());
5788
5789 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5790 assert(TokIdx <= LastIdx);
5791 SourceLocation EndLoc =
5792 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5793 CXCursor Cursor =
5794 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5795
5796 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005797 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005798
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005799 if (finished)
5800 break;
5801 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005802 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005803 }
5804}
5805
5806// This gets run a separate thread to avoid stack blowout.
5807static void clang_annotateTokensImpl(void *UserData) {
5808 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5809 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5810 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5811 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5812 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5813
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005814 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005815 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5816 setThreadBackgroundPriority();
5817
5818 // Determine the region of interest, which contains all of the tokens.
5819 SourceRange RegionOfInterest;
5820 RegionOfInterest.setBegin(
5821 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5822 RegionOfInterest.setEnd(
5823 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5824 Tokens[NumTokens-1])));
5825
Guy Benyei11169dd2012-12-18 14:30:41 +00005826 // Relex the tokens within the source range to look for preprocessing
5827 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005828 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005829
5830 // If begin location points inside a macro argument, set it to the expansion
5831 // location so we can have the full context when annotating semantically.
5832 {
5833 SourceManager &SM = CXXUnit->getSourceManager();
5834 SourceLocation Loc =
5835 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5836 if (Loc.isMacroID())
5837 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5838 }
5839
Guy Benyei11169dd2012-12-18 14:30:41 +00005840 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5841 // Search and mark tokens that are macro argument expansions.
5842 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5843 Tokens, NumTokens);
5844 CursorVisitor MacroArgMarker(TU,
5845 MarkMacroArgTokensVisitorDelegate, &Visitor,
5846 /*VisitPreprocessorLast=*/true,
5847 /*VisitIncludedEntities=*/false,
5848 RegionOfInterest);
5849 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5850 }
5851
5852 // Annotate all of the source locations in the region of interest that map to
5853 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005854 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005855
5856 // FIXME: We use a ridiculous stack size here because the data-recursion
5857 // algorithm uses a large stack frame than the non-data recursive version,
5858 // and AnnotationTokensWorker currently transforms the data-recursion
5859 // algorithm back into a traditional recursion by explicitly calling
5860 // VisitChildren(). We will need to remove this explicit recursive call.
5861 W.AnnotateTokens();
5862
5863 // If we ran into any entities that involve context-sensitive keywords,
5864 // take another pass through the tokens to mark them as such.
5865 if (W.hasContextSensitiveKeywords()) {
5866 for (unsigned I = 0; I != NumTokens; ++I) {
5867 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5868 continue;
5869
5870 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5871 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005872 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005873 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5874 if (Property->getPropertyAttributesAsWritten() != 0 &&
5875 llvm::StringSwitch<bool>(II->getName())
5876 .Case("readonly", true)
5877 .Case("assign", true)
5878 .Case("unsafe_unretained", true)
5879 .Case("readwrite", true)
5880 .Case("retain", true)
5881 .Case("copy", true)
5882 .Case("nonatomic", true)
5883 .Case("atomic", true)
5884 .Case("getter", true)
5885 .Case("setter", true)
5886 .Case("strong", true)
5887 .Case("weak", true)
5888 .Default(false))
5889 Tokens[I].int_data[0] = CXToken_Keyword;
5890 }
5891 continue;
5892 }
5893
5894 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5895 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5896 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5897 if (llvm::StringSwitch<bool>(II->getName())
5898 .Case("in", true)
5899 .Case("out", true)
5900 .Case("inout", true)
5901 .Case("oneway", true)
5902 .Case("bycopy", true)
5903 .Case("byref", true)
5904 .Default(false))
5905 Tokens[I].int_data[0] = CXToken_Keyword;
5906 continue;
5907 }
5908
5909 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5910 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5911 Tokens[I].int_data[0] = CXToken_Keyword;
5912 continue;
5913 }
5914 }
5915 }
5916}
5917
5918extern "C" {
5919
5920void clang_annotateTokens(CXTranslationUnit TU,
5921 CXToken *Tokens, unsigned NumTokens,
5922 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005923 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005924 LOG_BAD_TU(TU);
5925 return;
5926 }
5927 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005928 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005929 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005930 }
5931
5932 LOG_FUNC_SECTION {
5933 *Log << TU << ' ';
5934 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5935 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5936 *Log << clang_getRange(bloc, eloc);
5937 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005938
5939 // Any token we don't specifically annotate will have a NULL cursor.
5940 CXCursor C = clang_getNullCursor();
5941 for (unsigned I = 0; I != NumTokens; ++I)
5942 Cursors[I] = C;
5943
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005944 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005945 if (!CXXUnit)
5946 return;
5947
5948 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5949
5950 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5951 llvm::CrashRecoveryContext CRC;
5952 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5953 GetSafetyThreadStackSize() * 2)) {
5954 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5955 }
5956}
5957
5958} // end: extern "C"
5959
5960//===----------------------------------------------------------------------===//
5961// Operations for querying linkage of a cursor.
5962//===----------------------------------------------------------------------===//
5963
5964extern "C" {
5965CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5966 if (!clang_isDeclaration(cursor.kind))
5967 return CXLinkage_Invalid;
5968
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005969 const Decl *D = cxcursor::getCursorDecl(cursor);
5970 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005971 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005972 case NoLinkage:
5973 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005974 case InternalLinkage: return CXLinkage_Internal;
5975 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5976 case ExternalLinkage: return CXLinkage_External;
5977 };
5978
5979 return CXLinkage_Invalid;
5980}
5981} // end: extern "C"
5982
5983//===----------------------------------------------------------------------===//
5984// Operations for querying language of a cursor.
5985//===----------------------------------------------------------------------===//
5986
5987static CXLanguageKind getDeclLanguage(const Decl *D) {
5988 if (!D)
5989 return CXLanguage_C;
5990
5991 switch (D->getKind()) {
5992 default:
5993 break;
5994 case Decl::ImplicitParam:
5995 case Decl::ObjCAtDefsField:
5996 case Decl::ObjCCategory:
5997 case Decl::ObjCCategoryImpl:
5998 case Decl::ObjCCompatibleAlias:
5999 case Decl::ObjCImplementation:
6000 case Decl::ObjCInterface:
6001 case Decl::ObjCIvar:
6002 case Decl::ObjCMethod:
6003 case Decl::ObjCProperty:
6004 case Decl::ObjCPropertyImpl:
6005 case Decl::ObjCProtocol:
6006 return CXLanguage_ObjC;
6007 case Decl::CXXConstructor:
6008 case Decl::CXXConversion:
6009 case Decl::CXXDestructor:
6010 case Decl::CXXMethod:
6011 case Decl::CXXRecord:
6012 case Decl::ClassTemplate:
6013 case Decl::ClassTemplatePartialSpecialization:
6014 case Decl::ClassTemplateSpecialization:
6015 case Decl::Friend:
6016 case Decl::FriendTemplate:
6017 case Decl::FunctionTemplate:
6018 case Decl::LinkageSpec:
6019 case Decl::Namespace:
6020 case Decl::NamespaceAlias:
6021 case Decl::NonTypeTemplateParm:
6022 case Decl::StaticAssert:
6023 case Decl::TemplateTemplateParm:
6024 case Decl::TemplateTypeParm:
6025 case Decl::UnresolvedUsingTypename:
6026 case Decl::UnresolvedUsingValue:
6027 case Decl::Using:
6028 case Decl::UsingDirective:
6029 case Decl::UsingShadow:
6030 return CXLanguage_CPlusPlus;
6031 }
6032
6033 return CXLanguage_C;
6034}
6035
6036extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006037
6038static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6039 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6040 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006041
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006042 switch (D->getAvailability()) {
6043 case AR_Available:
6044 case AR_NotYetIntroduced:
6045 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006046 return getCursorAvailabilityForDecl(
6047 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006048 return CXAvailability_Available;
6049
6050 case AR_Deprecated:
6051 return CXAvailability_Deprecated;
6052
6053 case AR_Unavailable:
6054 return CXAvailability_NotAvailable;
6055 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006056
6057 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006058}
6059
Guy Benyei11169dd2012-12-18 14:30:41 +00006060enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6061 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006062 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6063 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006064
6065 return CXAvailability_Available;
6066}
6067
6068static CXVersion convertVersion(VersionTuple In) {
6069 CXVersion Out = { -1, -1, -1 };
6070 if (In.empty())
6071 return Out;
6072
6073 Out.Major = In.getMajor();
6074
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006075 Optional<unsigned> Minor = In.getMinor();
6076 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006077 Out.Minor = *Minor;
6078 else
6079 return Out;
6080
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006081 Optional<unsigned> Subminor = In.getSubminor();
6082 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006083 Out.Subminor = *Subminor;
6084
6085 return Out;
6086}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006087
6088static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6089 int *always_deprecated,
6090 CXString *deprecated_message,
6091 int *always_unavailable,
6092 CXString *unavailable_message,
6093 CXPlatformAvailability *availability,
6094 int availability_size) {
6095 bool HadAvailAttr = false;
6096 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006097 for (auto A : D->attrs()) {
6098 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006099 HadAvailAttr = true;
6100 if (always_deprecated)
6101 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006102 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006103 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006104 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006105 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006106 continue;
6107 }
6108
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006109 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006110 HadAvailAttr = true;
6111 if (always_unavailable)
6112 *always_unavailable = 1;
6113 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006114 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006115 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6116 }
6117 continue;
6118 }
6119
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006120 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006121 HadAvailAttr = true;
6122 if (N < availability_size) {
6123 availability[N].Platform
6124 = cxstring::createDup(Avail->getPlatform()->getName());
6125 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6126 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6127 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6128 availability[N].Unavailable = Avail->getUnavailable();
6129 availability[N].Message = cxstring::createDup(Avail->getMessage());
6130 }
6131 ++N;
6132 }
6133 }
6134
6135 if (!HadAvailAttr)
6136 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6137 return getCursorPlatformAvailabilityForDecl(
6138 cast<Decl>(EnumConst->getDeclContext()),
6139 always_deprecated,
6140 deprecated_message,
6141 always_unavailable,
6142 unavailable_message,
6143 availability,
6144 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006145
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006146 return N;
6147}
6148
Guy Benyei11169dd2012-12-18 14:30:41 +00006149int clang_getCursorPlatformAvailability(CXCursor cursor,
6150 int *always_deprecated,
6151 CXString *deprecated_message,
6152 int *always_unavailable,
6153 CXString *unavailable_message,
6154 CXPlatformAvailability *availability,
6155 int availability_size) {
6156 if (always_deprecated)
6157 *always_deprecated = 0;
6158 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006159 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006160 if (always_unavailable)
6161 *always_unavailable = 0;
6162 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006163 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006164
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 if (!clang_isDeclaration(cursor.kind))
6166 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006167
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006168 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006169 if (!D)
6170 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006171
6172 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6173 deprecated_message,
6174 always_unavailable,
6175 unavailable_message,
6176 availability,
6177 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006178}
6179
6180void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6181 clang_disposeString(availability->Platform);
6182 clang_disposeString(availability->Message);
6183}
6184
6185CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6186 if (clang_isDeclaration(cursor.kind))
6187 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6188
6189 return CXLanguage_Invalid;
6190}
6191
6192 /// \brief If the given cursor is the "templated" declaration
6193 /// descibing a class or function template, return the class or
6194 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006195static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006196 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006197 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006198
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006199 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006200 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6201 return FunTmpl;
6202
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006203 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006204 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6205 return ClassTmpl;
6206
6207 return D;
6208}
6209
6210CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6211 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006212 if (const Decl *D = getCursorDecl(cursor)) {
6213 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006214 if (!DC)
6215 return clang_getNullCursor();
6216
6217 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6218 getCursorTU(cursor));
6219 }
6220 }
6221
6222 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006223 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006224 return MakeCXCursor(D, getCursorTU(cursor));
6225 }
6226
6227 return clang_getNullCursor();
6228}
6229
6230CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6231 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006232 if (const Decl *D = getCursorDecl(cursor)) {
6233 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006234 if (!DC)
6235 return clang_getNullCursor();
6236
6237 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6238 getCursorTU(cursor));
6239 }
6240 }
6241
6242 // FIXME: Note that we can't easily compute the lexical context of a
6243 // statement or expression, so we return nothing.
6244 return clang_getNullCursor();
6245}
6246
6247CXFile clang_getIncludedFile(CXCursor cursor) {
6248 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006249 return nullptr;
6250
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006251 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006252 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006253}
6254
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006255unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6256 if (C.kind != CXCursor_ObjCPropertyDecl)
6257 return CXObjCPropertyAttr_noattr;
6258
6259 unsigned Result = CXObjCPropertyAttr_noattr;
6260 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6261 ObjCPropertyDecl::PropertyAttributeKind Attr =
6262 PD->getPropertyAttributesAsWritten();
6263
6264#define SET_CXOBJCPROP_ATTR(A) \
6265 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6266 Result |= CXObjCPropertyAttr_##A
6267 SET_CXOBJCPROP_ATTR(readonly);
6268 SET_CXOBJCPROP_ATTR(getter);
6269 SET_CXOBJCPROP_ATTR(assign);
6270 SET_CXOBJCPROP_ATTR(readwrite);
6271 SET_CXOBJCPROP_ATTR(retain);
6272 SET_CXOBJCPROP_ATTR(copy);
6273 SET_CXOBJCPROP_ATTR(nonatomic);
6274 SET_CXOBJCPROP_ATTR(setter);
6275 SET_CXOBJCPROP_ATTR(atomic);
6276 SET_CXOBJCPROP_ATTR(weak);
6277 SET_CXOBJCPROP_ATTR(strong);
6278 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6279#undef SET_CXOBJCPROP_ATTR
6280
6281 return Result;
6282}
6283
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006284unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6285 if (!clang_isDeclaration(C.kind))
6286 return CXObjCDeclQualifier_None;
6287
6288 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6289 const Decl *D = getCursorDecl(C);
6290 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6291 QT = MD->getObjCDeclQualifier();
6292 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6293 QT = PD->getObjCDeclQualifier();
6294 if (QT == Decl::OBJC_TQ_None)
6295 return CXObjCDeclQualifier_None;
6296
6297 unsigned Result = CXObjCDeclQualifier_None;
6298 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6299 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6300 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6301 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6302 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6303 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6304
6305 return Result;
6306}
6307
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006308unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6309 if (!clang_isDeclaration(C.kind))
6310 return 0;
6311
6312 const Decl *D = getCursorDecl(C);
6313 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6314 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6315 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6316 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6317
6318 return 0;
6319}
6320
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006321unsigned clang_Cursor_isVariadic(CXCursor C) {
6322 if (!clang_isDeclaration(C.kind))
6323 return 0;
6324
6325 const Decl *D = getCursorDecl(C);
6326 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6327 return FD->isVariadic();
6328 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6329 return MD->isVariadic();
6330
6331 return 0;
6332}
6333
Guy Benyei11169dd2012-12-18 14:30:41 +00006334CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6335 if (!clang_isDeclaration(C.kind))
6336 return clang_getNullRange();
6337
6338 const Decl *D = getCursorDecl(C);
6339 ASTContext &Context = getCursorContext(C);
6340 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6341 if (!RC)
6342 return clang_getNullRange();
6343
6344 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6345}
6346
6347CXString clang_Cursor_getRawCommentText(CXCursor C) {
6348 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006349 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006350
6351 const Decl *D = getCursorDecl(C);
6352 ASTContext &Context = getCursorContext(C);
6353 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6354 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6355 StringRef();
6356
6357 // Don't duplicate the string because RawText points directly into source
6358 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006359 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006360}
6361
6362CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6363 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006364 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006365
6366 const Decl *D = getCursorDecl(C);
6367 const ASTContext &Context = getCursorContext(C);
6368 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6369
6370 if (RC) {
6371 StringRef BriefText = RC->getBriefText(Context);
6372
6373 // Don't duplicate the string because RawComment ensures that this memory
6374 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006375 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006376 }
6377
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006378 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006379}
6380
Guy Benyei11169dd2012-12-18 14:30:41 +00006381CXModule clang_Cursor_getModule(CXCursor C) {
6382 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006383 if (const ImportDecl *ImportD =
6384 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006385 return ImportD->getImportedModule();
6386 }
6387
Craig Topper69186e72014-06-08 08:38:04 +00006388 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006389}
6390
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006391CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6392 if (isNotUsableTU(TU)) {
6393 LOG_BAD_TU(TU);
6394 return nullptr;
6395 }
6396 if (!File)
6397 return nullptr;
6398 FileEntry *FE = static_cast<FileEntry *>(File);
6399
6400 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6401 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6402 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6403
6404 if (Module *Mod = Header.getModule()) {
6405 if (Header.getRole() != ModuleMap::ExcludedHeader)
6406 return Mod;
6407 }
6408 return nullptr;
6409}
6410
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006411CXFile clang_Module_getASTFile(CXModule CXMod) {
6412 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006413 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006414 Module *Mod = static_cast<Module*>(CXMod);
6415 return const_cast<FileEntry *>(Mod->getASTFile());
6416}
6417
Guy Benyei11169dd2012-12-18 14:30:41 +00006418CXModule clang_Module_getParent(CXModule CXMod) {
6419 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006420 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 Module *Mod = static_cast<Module*>(CXMod);
6422 return Mod->Parent;
6423}
6424
6425CXString clang_Module_getName(CXModule CXMod) {
6426 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006427 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006428 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006429 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006430}
6431
6432CXString clang_Module_getFullName(CXModule CXMod) {
6433 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006434 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006435 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006436 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006437}
6438
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006439int clang_Module_isSystem(CXModule CXMod) {
6440 if (!CXMod)
6441 return 0;
6442 Module *Mod = static_cast<Module*>(CXMod);
6443 return Mod->IsSystem;
6444}
6445
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006446unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6447 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006448 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006449 LOG_BAD_TU(TU);
6450 return 0;
6451 }
6452 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 return 0;
6454 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006455 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6456 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6457 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006458}
6459
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006460CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6461 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006462 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006463 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006464 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006465 }
6466 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006467 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006468 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006469 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006470
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006471 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6472 if (Index < TopHeaders.size())
6473 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006474
Craig Topper69186e72014-06-08 08:38:04 +00006475 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006476}
6477
6478} // end: extern "C"
6479
6480//===----------------------------------------------------------------------===//
6481// C++ AST instrospection.
6482//===----------------------------------------------------------------------===//
6483
6484extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006485unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6486 if (!clang_isDeclaration(C.kind))
6487 return 0;
6488
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006489 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006490 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006491 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006492 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6493}
6494
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006495unsigned clang_CXXMethod_isConst(CXCursor C) {
6496 if (!clang_isDeclaration(C.kind))
6497 return 0;
6498
6499 const Decl *D = cxcursor::getCursorDecl(C);
6500 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006501 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006502 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6503}
6504
Guy Benyei11169dd2012-12-18 14:30:41 +00006505unsigned clang_CXXMethod_isStatic(CXCursor C) {
6506 if (!clang_isDeclaration(C.kind))
6507 return 0;
6508
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006509 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006510 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006511 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006512 return (Method && Method->isStatic()) ? 1 : 0;
6513}
6514
6515unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6516 if (!clang_isDeclaration(C.kind))
6517 return 0;
6518
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006519 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006520 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006521 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006522 return (Method && Method->isVirtual()) ? 1 : 0;
6523}
6524} // end: extern "C"
6525
6526//===----------------------------------------------------------------------===//
6527// Attribute introspection.
6528//===----------------------------------------------------------------------===//
6529
6530extern "C" {
6531CXType clang_getIBOutletCollectionType(CXCursor C) {
6532 if (C.kind != CXCursor_IBOutletCollectionAttr)
6533 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6534
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006535 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006536 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6537
6538 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6539}
6540} // end: extern "C"
6541
6542//===----------------------------------------------------------------------===//
6543// Inspecting memory usage.
6544//===----------------------------------------------------------------------===//
6545
6546typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6547
6548static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6549 enum CXTUResourceUsageKind k,
6550 unsigned long amount) {
6551 CXTUResourceUsageEntry entry = { k, amount };
6552 entries.push_back(entry);
6553}
6554
6555extern "C" {
6556
6557const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6558 const char *str = "";
6559 switch (kind) {
6560 case CXTUResourceUsage_AST:
6561 str = "ASTContext: expressions, declarations, and types";
6562 break;
6563 case CXTUResourceUsage_Identifiers:
6564 str = "ASTContext: identifiers";
6565 break;
6566 case CXTUResourceUsage_Selectors:
6567 str = "ASTContext: selectors";
6568 break;
6569 case CXTUResourceUsage_GlobalCompletionResults:
6570 str = "Code completion: cached global results";
6571 break;
6572 case CXTUResourceUsage_SourceManagerContentCache:
6573 str = "SourceManager: content cache allocator";
6574 break;
6575 case CXTUResourceUsage_AST_SideTables:
6576 str = "ASTContext: side tables";
6577 break;
6578 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6579 str = "SourceManager: malloc'ed memory buffers";
6580 break;
6581 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6582 str = "SourceManager: mmap'ed memory buffers";
6583 break;
6584 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6585 str = "ExternalASTSource: malloc'ed memory buffers";
6586 break;
6587 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6588 str = "ExternalASTSource: mmap'ed memory buffers";
6589 break;
6590 case CXTUResourceUsage_Preprocessor:
6591 str = "Preprocessor: malloc'ed memory";
6592 break;
6593 case CXTUResourceUsage_PreprocessingRecord:
6594 str = "Preprocessor: PreprocessingRecord";
6595 break;
6596 case CXTUResourceUsage_SourceManager_DataStructures:
6597 str = "SourceManager: data structures and tables";
6598 break;
6599 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6600 str = "Preprocessor: header search tables";
6601 break;
6602 }
6603 return str;
6604}
6605
6606CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006607 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006608 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006609 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006610 return usage;
6611 }
6612
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006613 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006614 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006615 ASTContext &astContext = astUnit->getASTContext();
6616
6617 // How much memory is used by AST nodes and types?
6618 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6619 (unsigned long) astContext.getASTAllocatedMemory());
6620
6621 // How much memory is used by identifiers?
6622 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6623 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6624
6625 // How much memory is used for selectors?
6626 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6627 (unsigned long) astContext.Selectors.getTotalMemory());
6628
6629 // How much memory is used by ASTContext's side tables?
6630 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6631 (unsigned long) astContext.getSideTableAllocatedMemory());
6632
6633 // How much memory is used for caching global code completion results?
6634 unsigned long completionBytes = 0;
6635 if (GlobalCodeCompletionAllocator *completionAllocator =
6636 astUnit->getCachedCompletionAllocator().getPtr()) {
6637 completionBytes = completionAllocator->getTotalMemory();
6638 }
6639 createCXTUResourceUsageEntry(*entries,
6640 CXTUResourceUsage_GlobalCompletionResults,
6641 completionBytes);
6642
6643 // How much memory is being used by SourceManager's content cache?
6644 createCXTUResourceUsageEntry(*entries,
6645 CXTUResourceUsage_SourceManagerContentCache,
6646 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6647
6648 // How much memory is being used by the MemoryBuffer's in SourceManager?
6649 const SourceManager::MemoryBufferSizes &srcBufs =
6650 astUnit->getSourceManager().getMemoryBufferSizes();
6651
6652 createCXTUResourceUsageEntry(*entries,
6653 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6654 (unsigned long) srcBufs.malloc_bytes);
6655 createCXTUResourceUsageEntry(*entries,
6656 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6657 (unsigned long) srcBufs.mmap_bytes);
6658 createCXTUResourceUsageEntry(*entries,
6659 CXTUResourceUsage_SourceManager_DataStructures,
6660 (unsigned long) astContext.getSourceManager()
6661 .getDataStructureSizes());
6662
6663 // How much memory is being used by the ExternalASTSource?
6664 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6665 const ExternalASTSource::MemoryBufferSizes &sizes =
6666 esrc->getMemoryBufferSizes();
6667
6668 createCXTUResourceUsageEntry(*entries,
6669 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6670 (unsigned long) sizes.malloc_bytes);
6671 createCXTUResourceUsageEntry(*entries,
6672 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6673 (unsigned long) sizes.mmap_bytes);
6674 }
6675
6676 // How much memory is being used by the Preprocessor?
6677 Preprocessor &pp = astUnit->getPreprocessor();
6678 createCXTUResourceUsageEntry(*entries,
6679 CXTUResourceUsage_Preprocessor,
6680 pp.getTotalMemory());
6681
6682 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6683 createCXTUResourceUsageEntry(*entries,
6684 CXTUResourceUsage_PreprocessingRecord,
6685 pRec->getTotalMemory());
6686 }
6687
6688 createCXTUResourceUsageEntry(*entries,
6689 CXTUResourceUsage_Preprocessor_HeaderSearch,
6690 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006691
Guy Benyei11169dd2012-12-18 14:30:41 +00006692 CXTUResourceUsage usage = { (void*) entries.get(),
6693 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006694 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006695 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006696 return usage;
6697}
6698
6699void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6700 if (usage.data)
6701 delete (MemUsageEntries*) usage.data;
6702}
6703
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006704CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6705 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006706 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006707 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006708
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006709 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006710 LOG_BAD_TU(TU);
6711 return skipped;
6712 }
6713
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006714 if (!file)
6715 return skipped;
6716
6717 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6718 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6719 if (!ppRec)
6720 return skipped;
6721
6722 ASTContext &Ctx = astUnit->getASTContext();
6723 SourceManager &sm = Ctx.getSourceManager();
6724 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6725 FileID wantedFileID = sm.translateFile(fileEntry);
6726
6727 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6728 std::vector<SourceRange> wantedRanges;
6729 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6730 i != ei; ++i) {
6731 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6732 wantedRanges.push_back(*i);
6733 }
6734
6735 skipped->count = wantedRanges.size();
6736 skipped->ranges = new CXSourceRange[skipped->count];
6737 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6738 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6739
6740 return skipped;
6741}
6742
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006743void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6744 if (ranges) {
6745 delete[] ranges->ranges;
6746 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006747 }
6748}
6749
Guy Benyei11169dd2012-12-18 14:30:41 +00006750} // end extern "C"
6751
6752void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6753 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6754 for (unsigned I = 0; I != Usage.numEntries; ++I)
6755 fprintf(stderr, " %s: %lu\n",
6756 clang_getTUResourceUsageName(Usage.entries[I].kind),
6757 Usage.entries[I].amount);
6758
6759 clang_disposeCXTUResourceUsage(Usage);
6760}
6761
6762//===----------------------------------------------------------------------===//
6763// Misc. utility functions.
6764//===----------------------------------------------------------------------===//
6765
6766/// Default to using an 8 MB stack size on "safety" threads.
6767static unsigned SafetyStackThreadSize = 8 << 20;
6768
6769namespace clang {
6770
6771bool RunSafely(llvm::CrashRecoveryContext &CRC,
6772 void (*Fn)(void*), void *UserData,
6773 unsigned Size) {
6774 if (!Size)
6775 Size = GetSafetyThreadStackSize();
6776 if (Size)
6777 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6778 return CRC.RunSafely(Fn, UserData);
6779}
6780
6781unsigned GetSafetyThreadStackSize() {
6782 return SafetyStackThreadSize;
6783}
6784
6785void SetSafetyThreadStackSize(unsigned Value) {
6786 SafetyStackThreadSize = Value;
6787}
6788
6789}
6790
6791void clang::setThreadBackgroundPriority() {
6792 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6793 return;
6794
6795 // FIXME: Move to llvm/Support and make it cross-platform.
6796#ifdef __APPLE__
6797 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6798#endif
6799}
6800
6801void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6802 if (!Unit)
6803 return;
6804
6805 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6806 DEnd = Unit->stored_diag_end();
6807 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006808 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006809 CXString Msg = clang_formatDiagnostic(&Diag,
6810 clang_defaultDiagnosticDisplayOptions());
6811 fprintf(stderr, "%s\n", clang_getCString(Msg));
6812 clang_disposeString(Msg);
6813 }
6814#ifdef LLVM_ON_WIN32
6815 // On Windows, force a flush, since there may be multiple copies of
6816 // stderr and stdout in the file system, all with different buffers
6817 // but writing to the same device.
6818 fflush(stderr);
6819#endif
6820}
6821
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006822MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6823 SourceLocation MacroDefLoc,
6824 CXTranslationUnit TU){
6825 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006826 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006827 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006828 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006829
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006830 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006831 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006832 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006833 if (MD) {
6834 for (MacroDirective::DefInfo
6835 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6836 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6837 return Def.getMacroInfo();
6838 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006839 }
6840
Craig Topper69186e72014-06-08 08:38:04 +00006841 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006842}
6843
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006844const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6845 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006846 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006847 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006848 const IdentifierInfo *II = MacroDef->getName();
6849 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006850 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006851
6852 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6853}
6854
6855MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6856 const Token &Tok,
6857 CXTranslationUnit TU) {
6858 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006859 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006860 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006861 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006862
6863 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006864 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006865 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6866 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006867 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006868
6869 // Check that the token is inside the definition and not its argument list.
6870 SourceManager &SM = Unit->getSourceManager();
6871 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006872 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006873 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006874 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006875
6876 Preprocessor &PP = Unit->getPreprocessor();
6877 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6878 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006879 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006880
Alp Toker2d57cea2014-05-17 04:53:25 +00006881 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006882 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006883 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006884
6885 // Check that the identifier is not one of the macro arguments.
6886 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006887 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006888
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006889 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6890 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006891 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006892
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006893 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006894}
6895
6896MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6897 SourceLocation Loc,
6898 CXTranslationUnit TU) {
6899 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006900 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006901
6902 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006903 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006904 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006905 Preprocessor &PP = Unit->getPreprocessor();
6906 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006907 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006908 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6909 Token Tok;
6910 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006911 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006912
6913 return checkForMacroInMacroDefinition(MI, Tok, TU);
6914}
6915
Guy Benyei11169dd2012-12-18 14:30:41 +00006916extern "C" {
6917
6918CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006919 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006920}
6921
6922} // end: extern "C"
6923
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006924Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6925 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006926 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006927 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006928 if (Unit->isMainFileAST())
6929 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006930 return *this;
6931 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006932 } else {
6933 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006934 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006935 return *this;
6936}
6937
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006938Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6939 *this << FE->getName();
6940 return *this;
6941}
6942
6943Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6944 CXString cursorName = clang_getCursorDisplayName(cursor);
6945 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6946 clang_disposeString(cursorName);
6947 return *this;
6948}
6949
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006950Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6951 CXFile File;
6952 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006953 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006954 CXString FileName = clang_getFileName(File);
6955 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6956 clang_disposeString(FileName);
6957 return *this;
6958}
6959
6960Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6961 CXSourceLocation BLoc = clang_getRangeStart(range);
6962 CXSourceLocation ELoc = clang_getRangeEnd(range);
6963
6964 CXFile BFile;
6965 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006966 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006967
6968 CXFile EFile;
6969 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006970 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006971
6972 CXString BFileName = clang_getFileName(BFile);
6973 if (BFile == EFile) {
6974 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6975 BLine, BColumn, ELine, EColumn);
6976 } else {
6977 CXString EFileName = clang_getFileName(EFile);
6978 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6979 BLine, BColumn)
6980 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6981 ELine, EColumn);
6982 clang_disposeString(EFileName);
6983 }
6984 clang_disposeString(BFileName);
6985 return *this;
6986}
6987
6988Logger &cxindex::Logger::operator<<(CXString Str) {
6989 *this << clang_getCString(Str);
6990 return *this;
6991}
6992
6993Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6994 LogOS << Fmt;
6995 return *this;
6996}
6997
6998cxindex::Logger::~Logger() {
6999 LogOS.flush();
7000
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00007001 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007002
7003 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7004
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007005 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007006 OS << "[libclang:" << Name << ':';
7007
7008 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00007009#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007010 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7011 OS << tid << ':';
7012#endif
7013
7014 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7015 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7016 OS << Msg.str() << '\n';
7017
7018 if (Trace) {
7019 llvm::sys::PrintStackTrace(stderr);
7020 OS << "--------------------------------------------------\n";
7021 }
7022}