blob: 787c28b21e25b240b050e4909c47e0a4d4ceb998 [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);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855
Guy Benyei11169dd2012-12-18 14:30:41 +00001856private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001857 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001858 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1859 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1861 void AddStmt(const Stmt *S);
1862 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001863 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001865 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866};
1867} // end anonyous namespace
1868
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001869void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 // 'S' should always be non-null, since it comes from the
1871 // statement we are visiting.
1872 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1873}
1874
1875void
1876EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1877 if (Qualifier)
1878 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1879}
1880
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 if (S)
1883 WL.push_back(StmtVisit(S, Parent));
1884}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 if (D)
1887 WL.push_back(DeclVisit(D, Parent, isFirst));
1888}
1889void EnqueueVisitor::
1890 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1891 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001893}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 if (D)
1896 WL.push_back(MemberRefVisit(D, L, Parent));
1897}
1898void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1899 if (TI)
1900 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1901 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001905 AddStmt(*Child);
1906 }
1907 if (size == WL.size())
1908 return;
1909 // Now reverse the entries we just added. This will match the DFS
1910 // ordering performed by the worklist.
1911 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1912 std::reverse(I, E);
1913}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001914namespace {
1915class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1916 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001917 /// \brief Process clauses with list of variables.
1918 template <typename T>
1919 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001920public:
1921 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1922#define OPENMP_CLAUSE(Name, Class) \
1923 void Visit##Class(const Class *C);
1924#include "clang/Basic/OpenMPKinds.def"
1925};
1926
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001927void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1928 Visitor->AddStmt(C->getCondition());
1929}
1930
Alexey Bataev568a8332014-03-06 06:15:19 +00001931void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1932 Visitor->AddStmt(C->getNumThreads());
1933}
1934
Alexey Bataev62c87d22014-03-21 04:51:18 +00001935void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1936 Visitor->AddStmt(C->getSafelen());
1937}
1938
Alexander Musman8bd31e62014-05-27 15:12:19 +00001939void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1940 Visitor->AddStmt(C->getNumForLoops());
1941}
1942
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001943void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001944
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001945void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1946
Alexey Bataev56dafe82014-06-20 07:16:17 +00001947void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1948 Visitor->AddStmt(C->getChunkSize());
1949}
1950
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001951void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1952
Alexey Bataev236070f2014-06-20 11:19:47 +00001953void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1954
Alexey Bataev756c1962013-09-24 03:17:45 +00001955template<typename T>
1956void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001957 for (const auto *I : Node->varlists())
1958 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001959}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001960
1961void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001962 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001963}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001964void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1965 const OMPFirstprivateClause *C) {
1966 VisitOMPClauseList(C);
1967}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001968void OMPClauseEnqueue::VisitOMPLastprivateClause(
1969 const OMPLastprivateClause *C) {
1970 VisitOMPClauseList(C);
1971}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001972void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001973 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001974}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001975void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1976 VisitOMPClauseList(C);
1977}
Alexander Musman8dba6642014-04-22 13:09:42 +00001978void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1979 VisitOMPClauseList(C);
1980 Visitor->AddStmt(C->getStep());
1981}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001982void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1983 VisitOMPClauseList(C);
1984 Visitor->AddStmt(C->getAlignment());
1985}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001986void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1987 VisitOMPClauseList(C);
1988}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001989}
Alexey Bataev756c1962013-09-24 03:17:45 +00001990
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001991void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1992 unsigned size = WL.size();
1993 OMPClauseEnqueue Visitor(this);
1994 Visitor.Visit(S);
1995 if (size == WL.size())
1996 return;
1997 // Now reverse the entries we just added. This will match the DFS
1998 // ordering performed by the worklist.
1999 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2000 std::reverse(I, E);
2001}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002002void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002003 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2004}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002005void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002006 AddDecl(B->getBlockDecl());
2007}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002008void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002009 EnqueueChildren(E);
2010 AddTypeLoc(E->getTypeSourceInfo());
2011}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002012void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2013 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002014 E = S->body_rend(); I != E; ++I) {
2015 AddStmt(*I);
2016 }
2017}
2018void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002019VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002020 AddStmt(S->getSubStmt());
2021 AddDeclarationNameInfo(S);
2022 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2023 AddNestedNameSpecifierLoc(QualifierLoc);
2024}
2025
2026void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002027VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002028 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2029 AddDeclarationNameInfo(E);
2030 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2031 AddNestedNameSpecifierLoc(QualifierLoc);
2032 if (!E->isImplicitAccess())
2033 AddStmt(E->getBase());
2034}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002035void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002036 // Enqueue the initializer , if any.
2037 AddStmt(E->getInitializer());
2038 // Enqueue the array size, if any.
2039 AddStmt(E->getArraySize());
2040 // Enqueue the allocated type.
2041 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2042 // Enqueue the placement arguments.
2043 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2044 AddStmt(E->getPlacementArg(I-1));
2045}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002046void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002047 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2048 AddStmt(CE->getArg(I-1));
2049 AddStmt(CE->getCallee());
2050 AddStmt(CE->getArg(0));
2051}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2053 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002054 // Visit the name of the type being destroyed.
2055 AddTypeLoc(E->getDestroyedTypeInfo());
2056 // Visit the scope type that looks disturbingly like the nested-name-specifier
2057 // but isn't.
2058 AddTypeLoc(E->getScopeTypeInfo());
2059 // Visit the nested-name-specifier.
2060 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2061 AddNestedNameSpecifierLoc(QualifierLoc);
2062 // Visit base expression.
2063 AddStmt(E->getBase());
2064}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2066 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 AddTypeLoc(E->getTypeSourceInfo());
2068}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2070 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002071 EnqueueChildren(E);
2072 AddTypeLoc(E->getTypeSourceInfo());
2073}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002074void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002075 EnqueueChildren(E);
2076 if (E->isTypeOperand())
2077 AddTypeLoc(E->getTypeOperandSourceInfo());
2078}
2079
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2081 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 EnqueueChildren(E);
2083 AddTypeLoc(E->getTypeSourceInfo());
2084}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002085void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002086 EnqueueChildren(E);
2087 if (E->isTypeOperand())
2088 AddTypeLoc(E->getTypeOperandSourceInfo());
2089}
2090
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002091void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002092 EnqueueChildren(S);
2093 AddDecl(S->getExceptionDecl());
2094}
2095
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 if (DR->hasExplicitTemplateArgs()) {
2098 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2099 }
2100 WL.push_back(DeclRefExprParts(DR, Parent));
2101}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2103 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002104 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2105 AddDeclarationNameInfo(E);
2106 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2107}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002109 unsigned size = WL.size();
2110 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002111 for (const auto *D : S->decls()) {
2112 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 isFirst = false;
2114 }
2115 if (size == WL.size())
2116 return;
2117 // Now reverse the entries we just added. This will match the DFS
2118 // ordering performed by the worklist.
2119 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2120 std::reverse(I, E);
2121}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 D = E->designators_rbegin(), DEnd = E->designators_rend();
2126 D != DEnd; ++D) {
2127 if (D->isFieldDesignator()) {
2128 if (FieldDecl *Field = D->getField())
2129 AddMemberRef(Field, D->getFieldLoc());
2130 continue;
2131 }
2132 if (D->isArrayDesignator()) {
2133 AddStmt(E->getArrayIndex(*D));
2134 continue;
2135 }
2136 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2137 AddStmt(E->getArrayRangeEnd(*D));
2138 AddStmt(E->getArrayRangeStart(*D));
2139 }
2140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 EnqueueChildren(E);
2143 AddTypeLoc(E->getTypeInfoAsWritten());
2144}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002145void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002146 AddStmt(FS->getBody());
2147 AddStmt(FS->getInc());
2148 AddStmt(FS->getCond());
2149 AddDecl(FS->getConditionVariable());
2150 AddStmt(FS->getInit());
2151}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 AddStmt(If->getElse());
2157 AddStmt(If->getThen());
2158 AddStmt(If->getCond());
2159 AddDecl(If->getConditionVariable());
2160}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002162 // We care about the syntactic form of the initializer list, only.
2163 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2164 IE = Syntactic;
2165 EnqueueChildren(IE);
2166}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002167void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002168 WL.push_back(MemberExprParts(M, Parent));
2169
2170 // If the base of the member access expression is an implicit 'this', don't
2171 // visit it.
2172 // FIXME: If we ever want to show these implicit accesses, this will be
2173 // unfortunate. However, clang_getCursor() relies on this behavior.
2174 if (!M->isImplicitAccess())
2175 AddStmt(M->getBase());
2176}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002177void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002178 AddTypeLoc(E->getEncodedTypeSourceInfo());
2179}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 EnqueueChildren(M);
2182 AddTypeLoc(M->getClassReceiverTypeInfo());
2183}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 // Visit the components of the offsetof expression.
2186 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2187 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2188 const OffsetOfNode &Node = E->getComponent(I-1);
2189 switch (Node.getKind()) {
2190 case OffsetOfNode::Array:
2191 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2192 break;
2193 case OffsetOfNode::Field:
2194 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2195 break;
2196 case OffsetOfNode::Identifier:
2197 case OffsetOfNode::Base:
2198 continue;
2199 }
2200 }
2201 // Visit the type into which we're computing the offset.
2202 AddTypeLoc(E->getTypeSourceInfo());
2203}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002205 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2206 WL.push_back(OverloadExprParts(E, Parent));
2207}
2208void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 EnqueueChildren(E);
2211 if (E->isArgumentType())
2212 AddTypeLoc(E->getArgumentTypeInfo());
2213}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 EnqueueChildren(S);
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 AddStmt(S->getBody());
2219 AddStmt(S->getCond());
2220 AddDecl(S->getConditionVariable());
2221}
2222
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002223void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002224 AddStmt(W->getBody());
2225 AddStmt(W->getCond());
2226 AddDecl(W->getConditionVariable());
2227}
2228
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 for (unsigned I = E->getNumArgs(); I > 0; --I)
2231 AddTypeLoc(E->getArg(I-1));
2232}
2233
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 AddTypeLoc(E->getQueriedTypeSourceInfo());
2236}
2237
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 EnqueueChildren(E);
2240}
2241
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 VisitOverloadExpr(U);
2244 if (!U->isImplicitAccess())
2245 AddStmt(U->getBase());
2246}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 AddStmt(E->getSubExpr());
2249 AddTypeLoc(E->getWrittenTypeInfo());
2250}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 WL.push_back(SizeOfPackExprParts(E, Parent));
2253}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002254void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002255 // If the opaque value has a source expression, just transparently
2256 // visit that. This is useful for (e.g.) pseudo-object expressions.
2257 if (Expr *SourceExpr = E->getSourceExpr())
2258 return Visit(SourceExpr);
2259}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 AddStmt(E->getBody());
2262 WL.push_back(LambdaExprParts(E, Parent));
2263}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 // Treat the expression like its syntactic form.
2266 Visit(E->getSyntacticForm());
2267}
2268
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002269void EnqueueVisitor::VisitOMPExecutableDirective(
2270 const OMPExecutableDirective *D) {
2271 EnqueueChildren(D);
2272 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2273 E = D->clauses().end();
2274 I != E; ++I)
2275 EnqueueChildren(*I);
2276}
2277
2278void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2279 VisitOMPExecutableDirective(D);
2280}
2281
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002282void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2283 VisitOMPExecutableDirective(D);
2284}
2285
Alexey Bataevf29276e2014-06-18 04:14:57 +00002286void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2287 VisitOMPExecutableDirective(D);
2288}
2289
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2292}
2293
2294bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2295 if (RegionOfInterest.isValid()) {
2296 SourceRange Range = getRawCursorExtent(C);
2297 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2298 return false;
2299 }
2300 return true;
2301}
2302
2303bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2304 while (!WL.empty()) {
2305 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002306 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002307
2308 // Set the Parent field, then back to its old value once we're done.
2309 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2310
2311 switch (LI.getKind()) {
2312 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 if (!D)
2315 continue;
2316
2317 // For now, perform default visitation for Decls.
2318 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2319 cast<DeclVisit>(&LI)->isFirst())))
2320 return true;
2321
2322 continue;
2323 }
2324 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2325 const ASTTemplateArgumentListInfo *ArgList =
2326 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2327 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2328 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2329 Arg != ArgEnd; ++Arg) {
2330 if (VisitTemplateArgumentLoc(*Arg))
2331 return true;
2332 }
2333 continue;
2334 }
2335 case VisitorJob::TypeLocVisitKind: {
2336 // Perform default visitation for TypeLocs.
2337 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2338 return true;
2339 continue;
2340 }
2341 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002343 if (LabelStmt *stmt = LS->getStmt()) {
2344 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2345 TU))) {
2346 return true;
2347 }
2348 }
2349 continue;
2350 }
2351
2352 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2353 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2354 if (VisitNestedNameSpecifierLoc(V->get()))
2355 return true;
2356 continue;
2357 }
2358
2359 case VisitorJob::DeclarationNameInfoVisitKind: {
2360 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2361 ->get()))
2362 return true;
2363 continue;
2364 }
2365 case VisitorJob::MemberRefVisitKind: {
2366 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2367 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2368 return true;
2369 continue;
2370 }
2371 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002372 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 if (!S)
2374 continue;
2375
2376 // Update the current cursor.
2377 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2378 if (!IsInRegionOfInterest(Cursor))
2379 continue;
2380 switch (Visitor(Cursor, Parent, ClientData)) {
2381 case CXChildVisit_Break: return true;
2382 case CXChildVisit_Continue: break;
2383 case CXChildVisit_Recurse:
2384 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002385 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002386 EnqueueWorkList(WL, S);
2387 break;
2388 }
2389 continue;
2390 }
2391 case VisitorJob::MemberExprPartsKind: {
2392 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002393 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002394
2395 // Visit the nested-name-specifier
2396 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2397 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2398 return true;
2399
2400 // Visit the declaration name.
2401 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2402 return true;
2403
2404 // Visit the explicitly-specified template arguments, if any.
2405 if (M->hasExplicitTemplateArgs()) {
2406 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2407 *ArgEnd = Arg + M->getNumTemplateArgs();
2408 Arg != ArgEnd; ++Arg) {
2409 if (VisitTemplateArgumentLoc(*Arg))
2410 return true;
2411 }
2412 }
2413 continue;
2414 }
2415 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 // Visit nested-name-specifier, if present.
2418 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2419 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2420 return true;
2421 // Visit declaration name.
2422 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2423 return true;
2424 continue;
2425 }
2426 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002427 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002428 // Visit the nested-name-specifier.
2429 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2430 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2431 return true;
2432 // Visit the declaration name.
2433 if (VisitDeclarationNameInfo(O->getNameInfo()))
2434 return true;
2435 // Visit the overloaded declaration reference.
2436 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2437 return true;
2438 continue;
2439 }
2440 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 NamedDecl *Pack = E->getPack();
2443 if (isa<TemplateTypeParmDecl>(Pack)) {
2444 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2445 E->getPackLoc(), TU)))
2446 return true;
2447
2448 continue;
2449 }
2450
2451 if (isa<TemplateTemplateParmDecl>(Pack)) {
2452 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2453 E->getPackLoc(), TU)))
2454 return true;
2455
2456 continue;
2457 }
2458
2459 // Non-type template parameter packs and function parameter packs are
2460 // treated like DeclRefExpr cursors.
2461 continue;
2462 }
2463
2464 case VisitorJob::LambdaExprPartsKind: {
2465 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002466 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002467 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2468 CEnd = E->explicit_capture_end();
2469 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002470 // FIXME: Lambda init-captures.
2471 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002472 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002473
Guy Benyei11169dd2012-12-18 14:30:41 +00002474 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2475 C->getLocation(),
2476 TU)))
2477 return true;
2478 }
2479
2480 // Visit parameters and return type, if present.
2481 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2482 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2483 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2484 // Visit the whole type.
2485 if (Visit(TL))
2486 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002487 } else if (FunctionProtoTypeLoc Proto =
2488 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002489 if (E->hasExplicitParameters()) {
2490 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002491 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2492 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002493 return true;
2494 } else {
2495 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002496 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002497 return true;
2498 }
2499 }
2500 }
2501 break;
2502 }
2503
2504 case VisitorJob::PostChildrenVisitKind:
2505 if (PostChildrenVisitor(Parent, ClientData))
2506 return true;
2507 break;
2508 }
2509 }
2510 return false;
2511}
2512
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002513bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002514 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002515 if (!WorkListFreeList.empty()) {
2516 WL = WorkListFreeList.back();
2517 WL->clear();
2518 WorkListFreeList.pop_back();
2519 }
2520 else {
2521 WL = new VisitorWorkList();
2522 WorkListCache.push_back(WL);
2523 }
2524 EnqueueWorkList(*WL, S);
2525 bool result = RunVisitorWorkList(*WL);
2526 WorkListFreeList.push_back(WL);
2527 return result;
2528}
2529
2530namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002531typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002532RefNamePieces
2533buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2534 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2535 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002536 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2537 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2538 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2539
2540 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2541
2542 RefNamePieces Pieces;
2543
2544 if (WantQualifier && QLoc.isValid())
2545 Pieces.push_back(QLoc);
2546
2547 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2548 Pieces.push_back(NI.getLoc());
2549
2550 if (WantTemplateArgs && TemplateArgs)
2551 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2552 TemplateArgs->RAngleLoc));
2553
2554 if (Kind == DeclarationName::CXXOperatorName) {
2555 Pieces.push_back(SourceLocation::getFromRawEncoding(
2556 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2557 Pieces.push_back(SourceLocation::getFromRawEncoding(
2558 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2559 }
2560
2561 if (WantSinglePiece) {
2562 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2563 Pieces.clear();
2564 Pieces.push_back(R);
2565 }
2566
2567 return Pieces;
2568}
2569}
2570
2571//===----------------------------------------------------------------------===//
2572// Misc. API hooks.
2573//===----------------------------------------------------------------------===//
2574
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00002575static llvm::sys::Mutex EnableMultithreadingMutex;
2576static bool EnabledMultithreading;
Guy Benyei11169dd2012-12-18 14:30:41 +00002577
Chad Rosier05c71aa2013-03-27 18:28:23 +00002578static void fatal_error_handler(void *user_data, const std::string& reason,
2579 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002580 // Write the result out to stderr avoiding errs() because raw_ostreams can
2581 // call report_fatal_error.
2582 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2583 ::abort();
2584}
2585
2586extern "C" {
2587CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2588 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002589 // We use crash recovery to make some of our APIs more reliable, implicitly
2590 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002591 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2592 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002593
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00002594 // Enable support for multithreading in LLVM.
2595 {
2596 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2597 if (!EnabledMultithreading) {
2598 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2599 llvm::llvm_start_multithreaded();
2600 EnabledMultithreading = true;
2601 }
2602 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002603
2604 CIndexer *CIdxr = new CIndexer();
2605 if (excludeDeclarationsFromPCH)
2606 CIdxr->setOnlyLocalDecls();
2607 if (displayDiagnostics)
2608 CIdxr->setDisplayDiagnostics();
2609
2610 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2611 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2612 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2613 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2614 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2615 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2616
2617 return CIdxr;
2618}
2619
2620void clang_disposeIndex(CXIndex CIdx) {
2621 if (CIdx)
2622 delete static_cast<CIndexer *>(CIdx);
2623}
2624
2625void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2626 if (CIdx)
2627 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2628}
2629
2630unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2631 if (CIdx)
2632 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2633 return 0;
2634}
2635
2636void clang_toggleCrashRecovery(unsigned isEnabled) {
2637 if (isEnabled)
2638 llvm::CrashRecoveryContext::Enable();
2639 else
2640 llvm::CrashRecoveryContext::Disable();
2641}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002642
Guy Benyei11169dd2012-12-18 14:30:41 +00002643CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2644 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002645 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002646 enum CXErrorCode Result =
2647 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002648 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002649 assert((TU && Result == CXError_Success) ||
2650 (!TU && Result != CXError_Success));
2651 return TU;
2652}
2653
2654enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2655 const char *ast_filename,
2656 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002657 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002658 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002659
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002660 if (!CIdx || !ast_filename || !out_TU)
2661 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002662
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002663 LOG_FUNC_SECTION {
2664 *Log << ast_filename;
2665 }
2666
Guy Benyei11169dd2012-12-18 14:30:41 +00002667 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2668 FileSystemOptions FileSystemOpts;
2669
2670 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002671 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002672 CXXIdx->getOnlyLocalDecls(), None,
2673 /*CaptureDiagnostics=*/true,
2674 /*AllowPCHWithCompilerErrors=*/true,
2675 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002676 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2677 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002678}
2679
2680unsigned clang_defaultEditingTranslationUnitOptions() {
2681 return CXTranslationUnit_PrecompiledPreamble |
2682 CXTranslationUnit_CacheCompletionResults;
2683}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002684
Guy Benyei11169dd2012-12-18 14:30:41 +00002685CXTranslationUnit
2686clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2687 const char *source_filename,
2688 int num_command_line_args,
2689 const char * const *command_line_args,
2690 unsigned num_unsaved_files,
2691 struct CXUnsavedFile *unsaved_files) {
2692 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2693 return clang_parseTranslationUnit(CIdx, source_filename,
2694 command_line_args, num_command_line_args,
2695 unsaved_files, num_unsaved_files,
2696 Options);
2697}
2698
2699struct ParseTranslationUnitInfo {
2700 CXIndex CIdx;
2701 const char *source_filename;
2702 const char *const *command_line_args;
2703 int num_command_line_args;
2704 struct CXUnsavedFile *unsaved_files;
2705 unsigned num_unsaved_files;
2706 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002707 CXTranslationUnit *out_TU;
2708 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002709};
2710static void clang_parseTranslationUnit_Impl(void *UserData) {
2711 ParseTranslationUnitInfo *PTUI =
2712 static_cast<ParseTranslationUnitInfo*>(UserData);
2713 CXIndex CIdx = PTUI->CIdx;
2714 const char *source_filename = PTUI->source_filename;
2715 const char * const *command_line_args = PTUI->command_line_args;
2716 int num_command_line_args = PTUI->num_command_line_args;
2717 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2718 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2719 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002720 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002721
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002722 // Set up the initial return values.
2723 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002724 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002725 PTUI->result = CXError_Failure;
2726
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002727 // Check arguments.
2728 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002729 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002730 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002731 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002732 }
2733
Guy Benyei11169dd2012-12-18 14:30:41 +00002734 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2735
2736 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2737 setThreadBackgroundPriority();
2738
2739 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2740 // FIXME: Add a flag for modules.
2741 TranslationUnitKind TUKind
2742 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002743 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002744 = options & CXTranslationUnit_CacheCompletionResults;
2745 bool IncludeBriefCommentsInCodeCompletion
2746 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2747 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2748 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2749
2750 // Configure the diagnostics.
2751 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002752 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002753
2754 // Recover resources if we crash before exiting this function.
2755 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2756 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2757 DiagCleanup(Diags.getPtr());
2758
Ahmed Charlesb8984322014-03-07 20:03:18 +00002759 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2760 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002761
2762 // Recover resources if we crash before exiting this function.
2763 llvm::CrashRecoveryContextCleanupRegistrar<
2764 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2765
2766 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2767 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2768 const llvm::MemoryBuffer *Buffer
2769 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2770 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2771 Buffer));
2772 }
2773
Ahmed Charlesb8984322014-03-07 20:03:18 +00002774 std::unique_ptr<std::vector<const char *>> Args(
2775 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002776
2777 // Recover resources if we crash before exiting this method.
2778 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2779 ArgsCleanup(Args.get());
2780
2781 // Since the Clang C library is primarily used by batch tools dealing with
2782 // (often very broken) source code, where spell-checking can have a
2783 // significant negative impact on performance (particularly when
2784 // precompiled headers are involved), we disable it by default.
2785 // Only do this if we haven't found a spell-checking-related argument.
2786 bool FoundSpellCheckingArgument = false;
2787 for (int I = 0; I != num_command_line_args; ++I) {
2788 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2789 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2790 FoundSpellCheckingArgument = true;
2791 break;
2792 }
2793 }
2794 if (!FoundSpellCheckingArgument)
2795 Args->push_back("-fno-spell-checking");
2796
2797 Args->insert(Args->end(), command_line_args,
2798 command_line_args + num_command_line_args);
2799
2800 // The 'source_filename' argument is optional. If the caller does not
2801 // specify it then it is assumed that the source file is specified
2802 // in the actual argument list.
2803 // Put the source file after command_line_args otherwise if '-x' flag is
2804 // present it will be unused.
2805 if (source_filename)
2806 Args->push_back(source_filename);
2807
2808 // Do we need the detailed preprocessing record?
2809 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2810 Args->push_back("-Xclang");
2811 Args->push_back("-detailed-preprocessing-record");
2812 }
2813
2814 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002815 std::unique_ptr<ASTUnit> ErrUnit;
2816 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002817 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002818 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2819 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2820 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2821 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2822 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2823 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002824
2825 if (NumErrors != Diags->getClient()->getNumErrors()) {
2826 // Make sure to check that 'Unit' is non-NULL.
2827 if (CXXIdx->getDisplayDiagnostics())
2828 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2829 }
2830
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002831 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2832 PTUI->result = CXError_ASTReadError;
2833 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002834 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002835 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2836 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002837}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002838
2839CXTranslationUnit
2840clang_parseTranslationUnit(CXIndex CIdx,
2841 const char *source_filename,
2842 const char *const *command_line_args,
2843 int num_command_line_args,
2844 struct CXUnsavedFile *unsaved_files,
2845 unsigned num_unsaved_files,
2846 unsigned options) {
2847 CXTranslationUnit TU;
2848 enum CXErrorCode Result = clang_parseTranslationUnit2(
2849 CIdx, source_filename, command_line_args, num_command_line_args,
2850 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002851 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002852 assert((TU && Result == CXError_Success) ||
2853 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002854 return TU;
2855}
2856
2857enum CXErrorCode clang_parseTranslationUnit2(
2858 CXIndex CIdx,
2859 const char *source_filename,
2860 const char *const *command_line_args,
2861 int num_command_line_args,
2862 struct CXUnsavedFile *unsaved_files,
2863 unsigned num_unsaved_files,
2864 unsigned options,
2865 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002866 LOG_FUNC_SECTION {
2867 *Log << source_filename << ": ";
2868 for (int i = 0; i != num_command_line_args; ++i)
2869 *Log << command_line_args[i] << " ";
2870 }
2871
Guy Benyei11169dd2012-12-18 14:30:41 +00002872 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2873 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002874 num_unsaved_files, options, out_TU,
2875 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002876 llvm::CrashRecoveryContext CRC;
2877
2878 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2879 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2880 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2881 fprintf(stderr, " 'command_line_args' : [");
2882 for (int i = 0; i != num_command_line_args; ++i) {
2883 if (i)
2884 fprintf(stderr, ", ");
2885 fprintf(stderr, "'%s'", command_line_args[i]);
2886 }
2887 fprintf(stderr, "],\n");
2888 fprintf(stderr, " 'unsaved_files' : [");
2889 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2890 if (i)
2891 fprintf(stderr, ", ");
2892 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2893 unsaved_files[i].Length);
2894 }
2895 fprintf(stderr, "],\n");
2896 fprintf(stderr, " 'options' : %d,\n", options);
2897 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002898
2899 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002900 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002901 if (CXTranslationUnit *TU = PTUI.out_TU)
2902 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002903 }
2904
2905 return PTUI.result;
2906}
2907
2908unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2909 return CXSaveTranslationUnit_None;
2910}
2911
2912namespace {
2913
2914struct SaveTranslationUnitInfo {
2915 CXTranslationUnit TU;
2916 const char *FileName;
2917 unsigned options;
2918 CXSaveError result;
2919};
2920
2921}
2922
2923static void clang_saveTranslationUnit_Impl(void *UserData) {
2924 SaveTranslationUnitInfo *STUI =
2925 static_cast<SaveTranslationUnitInfo*>(UserData);
2926
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002927 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002928 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2929 setThreadBackgroundPriority();
2930
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002931 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002932 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2933}
2934
2935int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2936 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002937 LOG_FUNC_SECTION {
2938 *Log << TU << ' ' << FileName;
2939 }
2940
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002941 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002942 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002943 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002944 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002945
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002946 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002947 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2948 if (!CXXUnit->hasSema())
2949 return CXSaveError_InvalidTU;
2950
2951 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2952
2953 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2954 getenv("LIBCLANG_NOTHREADS")) {
2955 clang_saveTranslationUnit_Impl(&STUI);
2956
2957 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2958 PrintLibclangResourceUsage(TU);
2959
2960 return STUI.result;
2961 }
2962
2963 // We have an AST that has invalid nodes due to compiler errors.
2964 // Use a crash recovery thread for protection.
2965
2966 llvm::CrashRecoveryContext CRC;
2967
2968 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2969 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2970 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2971 fprintf(stderr, " 'options' : %d,\n", options);
2972 fprintf(stderr, "}\n");
2973
2974 return CXSaveError_Unknown;
2975
2976 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2977 PrintLibclangResourceUsage(TU);
2978 }
2979
2980 return STUI.result;
2981}
2982
2983void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2984 if (CTUnit) {
2985 // If the translation unit has been marked as unsafe to free, just discard
2986 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002987 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2988 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002989 return;
2990
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002991 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002992 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002993 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2994 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002995 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002996 delete CTUnit;
2997 }
2998}
2999
3000unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3001 return CXReparse_None;
3002}
3003
3004struct ReparseTranslationUnitInfo {
3005 CXTranslationUnit TU;
3006 unsigned num_unsaved_files;
3007 struct CXUnsavedFile *unsaved_files;
3008 unsigned options;
3009 int result;
3010};
3011
3012static void clang_reparseTranslationUnit_Impl(void *UserData) {
3013 ReparseTranslationUnitInfo *RTUI =
3014 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003015 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003016
Guy Benyei11169dd2012-12-18 14:30:41 +00003017 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003018 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3019 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3020 unsigned options = RTUI->options;
3021 (void) options;
3022
3023 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003024 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003025 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003026 RTUI->result = CXError_InvalidArguments;
3027 return;
3028 }
Craig Topper69186e72014-06-08 08:38:04 +00003029 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003030 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003031 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003032 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003033
3034 // Reset the associated diagnostics.
3035 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003036 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003037
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003038 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003039 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3040 setThreadBackgroundPriority();
3041
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003042 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003043 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003044
3045 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3046 new std::vector<ASTUnit::RemappedFile>());
3047
Guy Benyei11169dd2012-12-18 14:30:41 +00003048 // Recover resources if we crash before exiting this function.
3049 llvm::CrashRecoveryContextCleanupRegistrar<
3050 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3051
3052 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3053 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3054 const llvm::MemoryBuffer *Buffer
3055 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3056 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3057 Buffer));
3058 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003059
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003060 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003061 RTUI->result = CXError_Success;
3062 else if (isASTReadError(CXXUnit))
3063 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003064}
3065
3066int clang_reparseTranslationUnit(CXTranslationUnit TU,
3067 unsigned num_unsaved_files,
3068 struct CXUnsavedFile *unsaved_files,
3069 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003070 LOG_FUNC_SECTION {
3071 *Log << TU;
3072 }
3073
Guy Benyei11169dd2012-12-18 14:30:41 +00003074 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003075 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003076
3077 if (getenv("LIBCLANG_NOTHREADS")) {
3078 clang_reparseTranslationUnit_Impl(&RTUI);
3079 return RTUI.result;
3080 }
3081
3082 llvm::CrashRecoveryContext CRC;
3083
3084 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3085 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003086 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003087 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003088 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3089 PrintLibclangResourceUsage(TU);
3090
3091 return RTUI.result;
3092}
3093
3094
3095CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003096 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003097 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003098 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003099 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003100
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003101 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003102 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003103}
3104
3105CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003106 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003107 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003108 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003109 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003110
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003111 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003112 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3113}
3114
3115} // end: extern "C"
3116
3117//===----------------------------------------------------------------------===//
3118// CXFile Operations.
3119//===----------------------------------------------------------------------===//
3120
3121extern "C" {
3122CXString clang_getFileName(CXFile SFile) {
3123 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003124 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003125
3126 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003127 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003128}
3129
3130time_t clang_getFileTime(CXFile SFile) {
3131 if (!SFile)
3132 return 0;
3133
3134 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3135 return FEnt->getModificationTime();
3136}
3137
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003138CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003139 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003140 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003141 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003142 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003143
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003144 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003145
3146 FileManager &FMgr = CXXUnit->getFileManager();
3147 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3148}
3149
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003150unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3151 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003152 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003153 LOG_BAD_TU(TU);
3154 return 0;
3155 }
3156
3157 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 return 0;
3159
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003160 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 FileEntry *FEnt = static_cast<FileEntry *>(file);
3162 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3163 .isFileMultipleIncludeGuarded(FEnt);
3164}
3165
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003166int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3167 if (!file || !outID)
3168 return 1;
3169
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003170 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003171 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3172 outID->data[0] = ID.getDevice();
3173 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003174 outID->data[2] = FEnt->getModificationTime();
3175 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003176}
3177
Guy Benyei11169dd2012-12-18 14:30:41 +00003178} // end: extern "C"
3179
3180//===----------------------------------------------------------------------===//
3181// CXCursor Operations.
3182//===----------------------------------------------------------------------===//
3183
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003184static const Decl *getDeclFromExpr(const Stmt *E) {
3185 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 return getDeclFromExpr(CE->getSubExpr());
3187
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003188 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003190 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003191 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003192 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003193 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003194 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 if (PRE->isExplicitProperty())
3196 return PRE->getExplicitProperty();
3197 // It could be messaging both getter and setter as in:
3198 // ++myobj.myprop;
3199 // in which case prefer to associate the setter since it is less obvious
3200 // from inspecting the source that the setter is going to get called.
3201 if (PRE->isMessagingSetter())
3202 return PRE->getImplicitPropertySetter();
3203 return PRE->getImplicitPropertyGetter();
3204 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003205 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003207 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 if (Expr *Src = OVE->getSourceExpr())
3209 return getDeclFromExpr(Src);
3210
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003211 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003213 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 if (!CE->isElidable())
3215 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003216 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return OME->getMethodDecl();
3218
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003219 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003221 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003222 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3223 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003224 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3226 isa<ParmVarDecl>(SizeOfPack->getPack()))
3227 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003228
3229 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003230}
3231
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003232static SourceLocation getLocationFromExpr(const Expr *E) {
3233 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 return getLocationFromExpr(CE->getSubExpr());
3235
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003236 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003237 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003238 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003239 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003240 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003242 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003244 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003245 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003246 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003247 return PropRef->getLocation();
3248
3249 return E->getLocStart();
3250}
3251
3252extern "C" {
3253
3254unsigned clang_visitChildren(CXCursor parent,
3255 CXCursorVisitor visitor,
3256 CXClientData client_data) {
3257 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3258 /*VisitPreprocessorLast=*/false);
3259 return CursorVis.VisitChildren(parent);
3260}
3261
3262#ifndef __has_feature
3263#define __has_feature(x) 0
3264#endif
3265#if __has_feature(blocks)
3266typedef enum CXChildVisitResult
3267 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3268
3269static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3270 CXClientData client_data) {
3271 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3272 return block(cursor, parent);
3273}
3274#else
3275// If we are compiled with a compiler that doesn't have native blocks support,
3276// define and call the block manually, so the
3277typedef struct _CXChildVisitResult
3278{
3279 void *isa;
3280 int flags;
3281 int reserved;
3282 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3283 CXCursor);
3284} *CXCursorVisitorBlock;
3285
3286static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3287 CXClientData client_data) {
3288 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3289 return block->invoke(block, cursor, parent);
3290}
3291#endif
3292
3293
3294unsigned clang_visitChildrenWithBlock(CXCursor parent,
3295 CXCursorVisitorBlock block) {
3296 return clang_visitChildren(parent, visitWithBlock, block);
3297}
3298
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003299static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003300 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003301 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003302
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003303 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003305 if (const ObjCPropertyImplDecl *PropImpl =
3306 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003308 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003309
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003310 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003312 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003313
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003314 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 }
3316
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003317 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003318 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003319
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003320 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3322 // and returns different names. NamedDecl returns the class name and
3323 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003324 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003325
3326 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003327 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003328
3329 SmallString<1024> S;
3330 llvm::raw_svector_ostream os(S);
3331 ND->printName(os);
3332
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003333 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003334}
3335
3336CXString clang_getCursorSpelling(CXCursor C) {
3337 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003338 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003339
3340 if (clang_isReference(C.kind)) {
3341 switch (C.kind) {
3342 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003343 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003344 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 }
3346 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003347 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003348 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 }
3350 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003351 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003353 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 }
3355 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003356 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003357 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 }
3359 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003360 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 assert(Type && "Missing type decl");
3362
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003363 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 getAsString());
3365 }
3366 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003367 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 assert(Template && "Missing template decl");
3369
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003370 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 }
3372
3373 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003374 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 assert(NS && "Missing namespace decl");
3376
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003377 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 }
3379
3380 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003381 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 assert(Field && "Missing member decl");
3383
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003384 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003385 }
3386
3387 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003388 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 assert(Label && "Missing label");
3390
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003391 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 }
3393
3394 case CXCursor_OverloadedDeclRef: {
3395 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003396 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3397 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003398 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003399 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003401 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003402 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 OverloadedTemplateStorage *Ovl
3404 = Storage.get<OverloadedTemplateStorage*>();
3405 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003406 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003407 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 }
3409
3410 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003411 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 assert(Var && "Missing variable decl");
3413
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003414 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 }
3416
3417 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003418 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 }
3420 }
3421
3422 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003423 const Expr *E = getCursorExpr(C);
3424
3425 if (C.kind == CXCursor_ObjCStringLiteral ||
3426 C.kind == CXCursor_StringLiteral) {
3427 const StringLiteral *SLit;
3428 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3429 SLit = OSL->getString();
3430 } else {
3431 SLit = cast<StringLiteral>(E);
3432 }
3433 SmallString<256> Buf;
3434 llvm::raw_svector_ostream OS(Buf);
3435 SLit->outputString(OS);
3436 return cxstring::createDup(OS.str());
3437 }
3438
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003439 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 if (D)
3441 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003442 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 }
3444
3445 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003446 const Stmt *S = getCursorStmt(C);
3447 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003448 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003449
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003450 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003451 }
3452
3453 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003454 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 ->getNameStart());
3456
3457 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003458 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 ->getNameStart());
3460
3461 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003462 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003463
3464 if (clang_isDeclaration(C.kind))
3465 return getDeclSpelling(getCursorDecl(C));
3466
3467 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003468 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003469 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 }
3471
3472 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003473 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003474 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 }
3476
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003477 if (C.kind == CXCursor_PackedAttr) {
3478 return cxstring::createRef("packed");
3479 }
3480
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003481 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003482}
3483
3484CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3485 unsigned pieceIndex,
3486 unsigned options) {
3487 if (clang_Cursor_isNull(C))
3488 return clang_getNullRange();
3489
3490 ASTContext &Ctx = getCursorContext(C);
3491
3492 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003493 const Stmt *S = getCursorStmt(C);
3494 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 if (pieceIndex > 0)
3496 return clang_getNullRange();
3497 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3498 }
3499
3500 return clang_getNullRange();
3501 }
3502
3503 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003504 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3506 if (pieceIndex >= ME->getNumSelectorLocs())
3507 return clang_getNullRange();
3508 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3509 }
3510 }
3511
3512 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3513 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003514 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003515 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3516 if (pieceIndex >= MD->getNumSelectorLocs())
3517 return clang_getNullRange();
3518 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3519 }
3520 }
3521
3522 if (C.kind == CXCursor_ObjCCategoryDecl ||
3523 C.kind == CXCursor_ObjCCategoryImplDecl) {
3524 if (pieceIndex > 0)
3525 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003526 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3528 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003529 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3531 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3532 }
3533
3534 if (C.kind == CXCursor_ModuleImportDecl) {
3535 if (pieceIndex > 0)
3536 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003537 if (const ImportDecl *ImportD =
3538 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3540 if (!Locs.empty())
3541 return cxloc::translateSourceRange(Ctx,
3542 SourceRange(Locs.front(), Locs.back()));
3543 }
3544 return clang_getNullRange();
3545 }
3546
3547 // FIXME: A CXCursor_InclusionDirective should give the location of the
3548 // filename, but we don't keep track of this.
3549
3550 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3551 // but we don't keep track of this.
3552
3553 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3554 // but we don't keep track of this.
3555
3556 // Default handling, give the location of the cursor.
3557
3558 if (pieceIndex > 0)
3559 return clang_getNullRange();
3560
3561 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3562 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3563 return cxloc::translateSourceRange(Ctx, Loc);
3564}
3565
3566CXString clang_getCursorDisplayName(CXCursor C) {
3567 if (!clang_isDeclaration(C.kind))
3568 return clang_getCursorSpelling(C);
3569
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003570 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003572 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003573
3574 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003575 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 D = FunTmpl->getTemplatedDecl();
3577
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003578 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 SmallString<64> Str;
3580 llvm::raw_svector_ostream OS(Str);
3581 OS << *Function;
3582 if (Function->getPrimaryTemplate())
3583 OS << "<>";
3584 OS << "(";
3585 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3586 if (I)
3587 OS << ", ";
3588 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3589 }
3590
3591 if (Function->isVariadic()) {
3592 if (Function->getNumParams())
3593 OS << ", ";
3594 OS << "...";
3595 }
3596 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003597 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 }
3599
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003600 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 SmallString<64> Str;
3602 llvm::raw_svector_ostream OS(Str);
3603 OS << *ClassTemplate;
3604 OS << "<";
3605 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3606 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3607 if (I)
3608 OS << ", ";
3609
3610 NamedDecl *Param = Params->getParam(I);
3611 if (Param->getIdentifier()) {
3612 OS << Param->getIdentifier()->getName();
3613 continue;
3614 }
3615
3616 // There is no parameter name, which makes this tricky. Try to come up
3617 // with something useful that isn't too long.
3618 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3619 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3620 else if (NonTypeTemplateParmDecl *NTTP
3621 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3622 OS << NTTP->getType().getAsString(Policy);
3623 else
3624 OS << "template<...> class";
3625 }
3626
3627 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003628 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 }
3630
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003631 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3633 // If the type was explicitly written, use that.
3634 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003635 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003636
Benjamin Kramer9170e912013-02-22 15:46:01 +00003637 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 llvm::raw_svector_ostream OS(Str);
3639 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003640 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 ClassSpec->getTemplateArgs().data(),
3642 ClassSpec->getTemplateArgs().size(),
3643 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003644 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 }
3646
3647 return clang_getCursorSpelling(C);
3648}
3649
3650CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3651 switch (Kind) {
3652 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003780 case CXCursor_ObjCSelfExpr:
3781 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003898 case CXCursor_PackedAttr:
3899 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003900 case CXCursor_PureAttr:
3901 return cxstring::createRef("attribute(pure)");
3902 case CXCursor_ConstAttr:
3903 return cxstring::createRef("attribute(const)");
3904 case CXCursor_NoDuplicateAttr:
3905 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003906 case CXCursor_CUDAConstantAttr:
3907 return cxstring::createRef("attribute(constant)");
3908 case CXCursor_CUDADeviceAttr:
3909 return cxstring::createRef("attribute(device)");
3910 case CXCursor_CUDAGlobalAttr:
3911 return cxstring::createRef("attribute(global)");
3912 case CXCursor_CUDAHostAttr:
3913 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003962 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003963 return cxstring::createRef("OMPParallelDirective");
3964 case CXCursor_OMPSimdDirective:
3965 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003966 case CXCursor_OMPForDirective:
3967 return cxstring::createRef("OMPForDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 }
3969
3970 llvm_unreachable("Unhandled CXCursorKind");
3971}
3972
3973struct GetCursorData {
3974 SourceLocation TokenBeginLoc;
3975 bool PointsAtMacroArgExpansion;
3976 bool VisitedObjCPropertyImplDecl;
3977 SourceLocation VisitedDeclaratorDeclStartLoc;
3978 CXCursor &BestCursor;
3979
3980 GetCursorData(SourceManager &SM,
3981 SourceLocation tokenBegin, CXCursor &outputCursor)
3982 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3983 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3984 VisitedObjCPropertyImplDecl = false;
3985 }
3986};
3987
3988static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3989 CXCursor parent,
3990 CXClientData client_data) {
3991 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3992 CXCursor *BestCursor = &Data->BestCursor;
3993
3994 // If we point inside a macro argument we should provide info of what the
3995 // token is so use the actual cursor, don't replace it with a macro expansion
3996 // cursor.
3997 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3998 return CXChildVisit_Recurse;
3999
4000 if (clang_isDeclaration(cursor.kind)) {
4001 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004002 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4004 if (MD->isImplicit())
4005 return CXChildVisit_Break;
4006
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004007 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4009 // Check that when we have multiple @class references in the same line,
4010 // that later ones do not override the previous ones.
4011 // If we have:
4012 // @class Foo, Bar;
4013 // source ranges for both start at '@', so 'Bar' will end up overriding
4014 // 'Foo' even though the cursor location was at 'Foo'.
4015 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4016 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004017 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4019 if (PrevID != ID &&
4020 !PrevID->isThisDeclarationADefinition() &&
4021 !ID->isThisDeclarationADefinition())
4022 return CXChildVisit_Break;
4023 }
4024
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004025 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4027 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4028 // Check that when we have multiple declarators in the same line,
4029 // that later ones do not override the previous ones.
4030 // If we have:
4031 // int Foo, Bar;
4032 // source ranges for both start at 'int', so 'Bar' will end up overriding
4033 // 'Foo' even though the cursor location was at 'Foo'.
4034 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4035 return CXChildVisit_Break;
4036 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4037
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004038 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4040 (void)PropImp;
4041 // Check that when we have multiple @synthesize in the same line,
4042 // that later ones do not override the previous ones.
4043 // If we have:
4044 // @synthesize Foo, Bar;
4045 // source ranges for both start at '@', so 'Bar' will end up overriding
4046 // 'Foo' even though the cursor location was at 'Foo'.
4047 if (Data->VisitedObjCPropertyImplDecl)
4048 return CXChildVisit_Break;
4049 Data->VisitedObjCPropertyImplDecl = true;
4050 }
4051 }
4052
4053 if (clang_isExpression(cursor.kind) &&
4054 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004055 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 // Avoid having the cursor of an expression replace the declaration cursor
4057 // when the expression source range overlaps the declaration range.
4058 // This can happen for C++ constructor expressions whose range generally
4059 // include the variable declaration, e.g.:
4060 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4061 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4062 D->getLocation() == Data->TokenBeginLoc)
4063 return CXChildVisit_Break;
4064 }
4065 }
4066
4067 // If our current best cursor is the construction of a temporary object,
4068 // don't replace that cursor with a type reference, because we want
4069 // clang_getCursor() to point at the constructor.
4070 if (clang_isExpression(BestCursor->kind) &&
4071 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4072 cursor.kind == CXCursor_TypeRef) {
4073 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4074 // as having the actual point on the type reference.
4075 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4076 return CXChildVisit_Recurse;
4077 }
4078
4079 *BestCursor = cursor;
4080 return CXChildVisit_Recurse;
4081}
4082
4083CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004084 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004085 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004087 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004088
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004089 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4091
4092 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4093 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4094
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004095 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 CXFile SearchFile;
4097 unsigned SearchLine, SearchColumn;
4098 CXFile ResultFile;
4099 unsigned ResultLine, ResultColumn;
4100 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4101 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4102 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004103
4104 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4105 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004106 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004107 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 SearchFileName = clang_getFileName(SearchFile);
4109 ResultFileName = clang_getFileName(ResultFile);
4110 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4111 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004112 *Log << llvm::format("(%s:%d:%d) = %s",
4113 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4114 clang_getCString(KindSpelling))
4115 << llvm::format("(%s:%d:%d):%s%s",
4116 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4117 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 clang_disposeString(SearchFileName);
4119 clang_disposeString(ResultFileName);
4120 clang_disposeString(KindSpelling);
4121 clang_disposeString(USR);
4122
4123 CXCursor Definition = clang_getCursorDefinition(Result);
4124 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4125 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4126 CXString DefinitionKindSpelling
4127 = clang_getCursorKindSpelling(Definition.kind);
4128 CXFile DefinitionFile;
4129 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004130 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004131 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004133 *Log << llvm::format(" -> %s(%s:%d:%d)",
4134 clang_getCString(DefinitionKindSpelling),
4135 clang_getCString(DefinitionFileName),
4136 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 clang_disposeString(DefinitionFileName);
4138 clang_disposeString(DefinitionKindSpelling);
4139 }
4140 }
4141
4142 return Result;
4143}
4144
4145CXCursor clang_getNullCursor(void) {
4146 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4147}
4148
4149unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004150 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4151 // can't set consistently. For example, when visiting a DeclStmt we will set
4152 // it but we don't set it on the result of clang_getCursorDefinition for
4153 // a reference of the same declaration.
4154 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4155 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4156 // to provide that kind of info.
4157 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004158 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004159 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004160 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004161
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 return X == Y;
4163}
4164
4165unsigned clang_hashCursor(CXCursor C) {
4166 unsigned Index = 0;
4167 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4168 Index = 1;
4169
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004170 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 std::make_pair(C.kind, C.data[Index]));
4172}
4173
4174unsigned clang_isInvalid(enum CXCursorKind K) {
4175 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4176}
4177
4178unsigned clang_isDeclaration(enum CXCursorKind K) {
4179 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4180 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4181}
4182
4183unsigned clang_isReference(enum CXCursorKind K) {
4184 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4185}
4186
4187unsigned clang_isExpression(enum CXCursorKind K) {
4188 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4189}
4190
4191unsigned clang_isStatement(enum CXCursorKind K) {
4192 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4193}
4194
4195unsigned clang_isAttribute(enum CXCursorKind K) {
4196 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4197}
4198
4199unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4200 return K == CXCursor_TranslationUnit;
4201}
4202
4203unsigned clang_isPreprocessing(enum CXCursorKind K) {
4204 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4205}
4206
4207unsigned clang_isUnexposed(enum CXCursorKind K) {
4208 switch (K) {
4209 case CXCursor_UnexposedDecl:
4210 case CXCursor_UnexposedExpr:
4211 case CXCursor_UnexposedStmt:
4212 case CXCursor_UnexposedAttr:
4213 return true;
4214 default:
4215 return false;
4216 }
4217}
4218
4219CXCursorKind clang_getCursorKind(CXCursor C) {
4220 return C.kind;
4221}
4222
4223CXSourceLocation clang_getCursorLocation(CXCursor C) {
4224 if (clang_isReference(C.kind)) {
4225 switch (C.kind) {
4226 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004227 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 = getCursorObjCSuperClassRef(C);
4229 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4230 }
4231
4232 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004233 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 = getCursorObjCProtocolRef(C);
4235 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4236 }
4237
4238 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004239 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 = getCursorObjCClassRef(C);
4241 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4242 }
4243
4244 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004245 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4247 }
4248
4249 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004250 std::pair<const TemplateDecl *, SourceLocation> P =
4251 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4253 }
4254
4255 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004256 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4258 }
4259
4260 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004261 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4263 }
4264
4265 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004266 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4268 }
4269
4270 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004271 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 if (!BaseSpec)
4273 return clang_getNullLocation();
4274
4275 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4276 return cxloc::translateSourceLocation(getCursorContext(C),
4277 TSInfo->getTypeLoc().getBeginLoc());
4278
4279 return cxloc::translateSourceLocation(getCursorContext(C),
4280 BaseSpec->getLocStart());
4281 }
4282
4283 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004284 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4286 }
4287
4288 case CXCursor_OverloadedDeclRef:
4289 return cxloc::translateSourceLocation(getCursorContext(C),
4290 getCursorOverloadedDeclRef(C).second);
4291
4292 default:
4293 // FIXME: Need a way to enumerate all non-reference cases.
4294 llvm_unreachable("Missed a reference kind");
4295 }
4296 }
4297
4298 if (clang_isExpression(C.kind))
4299 return cxloc::translateSourceLocation(getCursorContext(C),
4300 getLocationFromExpr(getCursorExpr(C)));
4301
4302 if (clang_isStatement(C.kind))
4303 return cxloc::translateSourceLocation(getCursorContext(C),
4304 getCursorStmt(C)->getLocStart());
4305
4306 if (C.kind == CXCursor_PreprocessingDirective) {
4307 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4308 return cxloc::translateSourceLocation(getCursorContext(C), L);
4309 }
4310
4311 if (C.kind == CXCursor_MacroExpansion) {
4312 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004313 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004314 return cxloc::translateSourceLocation(getCursorContext(C), L);
4315 }
4316
4317 if (C.kind == CXCursor_MacroDefinition) {
4318 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4319 return cxloc::translateSourceLocation(getCursorContext(C), L);
4320 }
4321
4322 if (C.kind == CXCursor_InclusionDirective) {
4323 SourceLocation L
4324 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4325 return cxloc::translateSourceLocation(getCursorContext(C), L);
4326 }
4327
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004328 if (clang_isAttribute(C.kind)) {
4329 SourceLocation L
4330 = cxcursor::getCursorAttr(C)->getLocation();
4331 return cxloc::translateSourceLocation(getCursorContext(C), L);
4332 }
4333
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 if (!clang_isDeclaration(C.kind))
4335 return clang_getNullLocation();
4336
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004337 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 if (!D)
4339 return clang_getNullLocation();
4340
4341 SourceLocation Loc = D->getLocation();
4342 // FIXME: Multiple variables declared in a single declaration
4343 // currently lack the information needed to correctly determine their
4344 // ranges when accounting for the type-specifier. We use context
4345 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4346 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004347 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004348 if (!cxcursor::isFirstInDeclGroup(C))
4349 Loc = VD->getLocation();
4350 }
4351
4352 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004353 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 Loc = MD->getSelectorStartLoc();
4355
4356 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4357}
4358
4359} // end extern "C"
4360
4361CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4362 assert(TU);
4363
4364 // Guard against an invalid SourceLocation, or we may assert in one
4365 // of the following calls.
4366 if (SLoc.isInvalid())
4367 return clang_getNullCursor();
4368
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004369 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004370
4371 // Translate the given source location to make it point at the beginning of
4372 // the token under the cursor.
4373 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4374 CXXUnit->getASTContext().getLangOpts());
4375
4376 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4377 if (SLoc.isValid()) {
4378 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4379 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4380 /*VisitPreprocessorLast=*/true,
4381 /*VisitIncludedEntities=*/false,
4382 SourceLocation(SLoc));
4383 CursorVis.visitFileRegion();
4384 }
4385
4386 return Result;
4387}
4388
4389static SourceRange getRawCursorExtent(CXCursor C) {
4390 if (clang_isReference(C.kind)) {
4391 switch (C.kind) {
4392 case CXCursor_ObjCSuperClassRef:
4393 return getCursorObjCSuperClassRef(C).second;
4394
4395 case CXCursor_ObjCProtocolRef:
4396 return getCursorObjCProtocolRef(C).second;
4397
4398 case CXCursor_ObjCClassRef:
4399 return getCursorObjCClassRef(C).second;
4400
4401 case CXCursor_TypeRef:
4402 return getCursorTypeRef(C).second;
4403
4404 case CXCursor_TemplateRef:
4405 return getCursorTemplateRef(C).second;
4406
4407 case CXCursor_NamespaceRef:
4408 return getCursorNamespaceRef(C).second;
4409
4410 case CXCursor_MemberRef:
4411 return getCursorMemberRef(C).second;
4412
4413 case CXCursor_CXXBaseSpecifier:
4414 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4415
4416 case CXCursor_LabelRef:
4417 return getCursorLabelRef(C).second;
4418
4419 case CXCursor_OverloadedDeclRef:
4420 return getCursorOverloadedDeclRef(C).second;
4421
4422 case CXCursor_VariableRef:
4423 return getCursorVariableRef(C).second;
4424
4425 default:
4426 // FIXME: Need a way to enumerate all non-reference cases.
4427 llvm_unreachable("Missed a reference kind");
4428 }
4429 }
4430
4431 if (clang_isExpression(C.kind))
4432 return getCursorExpr(C)->getSourceRange();
4433
4434 if (clang_isStatement(C.kind))
4435 return getCursorStmt(C)->getSourceRange();
4436
4437 if (clang_isAttribute(C.kind))
4438 return getCursorAttr(C)->getRange();
4439
4440 if (C.kind == CXCursor_PreprocessingDirective)
4441 return cxcursor::getCursorPreprocessingDirective(C);
4442
4443 if (C.kind == CXCursor_MacroExpansion) {
4444 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004445 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 return TU->mapRangeFromPreamble(Range);
4447 }
4448
4449 if (C.kind == CXCursor_MacroDefinition) {
4450 ASTUnit *TU = getCursorASTUnit(C);
4451 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4452 return TU->mapRangeFromPreamble(Range);
4453 }
4454
4455 if (C.kind == CXCursor_InclusionDirective) {
4456 ASTUnit *TU = getCursorASTUnit(C);
4457 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4458 return TU->mapRangeFromPreamble(Range);
4459 }
4460
4461 if (C.kind == CXCursor_TranslationUnit) {
4462 ASTUnit *TU = getCursorASTUnit(C);
4463 FileID MainID = TU->getSourceManager().getMainFileID();
4464 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4465 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4466 return SourceRange(Start, End);
4467 }
4468
4469 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004470 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 if (!D)
4472 return SourceRange();
4473
4474 SourceRange R = D->getSourceRange();
4475 // FIXME: Multiple variables declared in a single declaration
4476 // currently lack the information needed to correctly determine their
4477 // ranges when accounting for the type-specifier. We use context
4478 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4479 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004480 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 if (!cxcursor::isFirstInDeclGroup(C))
4482 R.setBegin(VD->getLocation());
4483 }
4484 return R;
4485 }
4486 return SourceRange();
4487}
4488
4489/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4490/// the decl-specifier-seq for declarations.
4491static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4492 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004493 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 if (!D)
4495 return SourceRange();
4496
4497 SourceRange R = D->getSourceRange();
4498
4499 // Adjust the start of the location for declarations preceded by
4500 // declaration specifiers.
4501 SourceLocation StartLoc;
4502 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4503 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4504 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004505 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4507 StartLoc = TI->getTypeLoc().getLocStart();
4508 }
4509
4510 if (StartLoc.isValid() && R.getBegin().isValid() &&
4511 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4512 R.setBegin(StartLoc);
4513
4514 // FIXME: Multiple variables declared in a single declaration
4515 // currently lack the information needed to correctly determine their
4516 // ranges when accounting for the type-specifier. We use context
4517 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4518 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004519 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004520 if (!cxcursor::isFirstInDeclGroup(C))
4521 R.setBegin(VD->getLocation());
4522 }
4523
4524 return R;
4525 }
4526
4527 return getRawCursorExtent(C);
4528}
4529
4530extern "C" {
4531
4532CXSourceRange clang_getCursorExtent(CXCursor C) {
4533 SourceRange R = getRawCursorExtent(C);
4534 if (R.isInvalid())
4535 return clang_getNullRange();
4536
4537 return cxloc::translateSourceRange(getCursorContext(C), R);
4538}
4539
4540CXCursor clang_getCursorReferenced(CXCursor C) {
4541 if (clang_isInvalid(C.kind))
4542 return clang_getNullCursor();
4543
4544 CXTranslationUnit tu = getCursorTU(C);
4545 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004546 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 if (!D)
4548 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004549 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004551 if (const ObjCPropertyImplDecl *PropImpl =
4552 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4554 return MakeCXCursor(Property, tu);
4555
4556 return C;
4557 }
4558
4559 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004560 const Expr *E = getCursorExpr(C);
4561 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 if (D) {
4563 CXCursor declCursor = MakeCXCursor(D, tu);
4564 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4565 declCursor);
4566 return declCursor;
4567 }
4568
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004569 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 return MakeCursorOverloadedDeclRef(Ovl, tu);
4571
4572 return clang_getNullCursor();
4573 }
4574
4575 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004576 const Stmt *S = getCursorStmt(C);
4577 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 if (LabelDecl *label = Goto->getLabel())
4579 if (LabelStmt *labelS = label->getStmt())
4580 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4581
4582 return clang_getNullCursor();
4583 }
4584
4585 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004586 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 return MakeMacroDefinitionCursor(Def, tu);
4588 }
4589
4590 if (!clang_isReference(C.kind))
4591 return clang_getNullCursor();
4592
4593 switch (C.kind) {
4594 case CXCursor_ObjCSuperClassRef:
4595 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4596
4597 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004598 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4599 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 return MakeCXCursor(Def, tu);
4601
4602 return MakeCXCursor(Prot, tu);
4603 }
4604
4605 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004606 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4607 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 return MakeCXCursor(Def, tu);
4609
4610 return MakeCXCursor(Class, tu);
4611 }
4612
4613 case CXCursor_TypeRef:
4614 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4615
4616 case CXCursor_TemplateRef:
4617 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4618
4619 case CXCursor_NamespaceRef:
4620 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4621
4622 case CXCursor_MemberRef:
4623 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4624
4625 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004626 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4628 tu ));
4629 }
4630
4631 case CXCursor_LabelRef:
4632 // FIXME: We end up faking the "parent" declaration here because we
4633 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004634 return MakeCXCursor(getCursorLabelRef(C).first,
4635 cxtu::getASTUnit(tu)->getASTContext()
4636 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 tu);
4638
4639 case CXCursor_OverloadedDeclRef:
4640 return C;
4641
4642 case CXCursor_VariableRef:
4643 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4644
4645 default:
4646 // We would prefer to enumerate all non-reference cursor kinds here.
4647 llvm_unreachable("Unhandled reference cursor kind");
4648 }
4649}
4650
4651CXCursor clang_getCursorDefinition(CXCursor C) {
4652 if (clang_isInvalid(C.kind))
4653 return clang_getNullCursor();
4654
4655 CXTranslationUnit TU = getCursorTU(C);
4656
4657 bool WasReference = false;
4658 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4659 C = clang_getCursorReferenced(C);
4660 WasReference = true;
4661 }
4662
4663 if (C.kind == CXCursor_MacroExpansion)
4664 return clang_getCursorReferenced(C);
4665
4666 if (!clang_isDeclaration(C.kind))
4667 return clang_getNullCursor();
4668
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004669 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 if (!D)
4671 return clang_getNullCursor();
4672
4673 switch (D->getKind()) {
4674 // Declaration kinds that don't really separate the notions of
4675 // declaration and definition.
4676 case Decl::Namespace:
4677 case Decl::Typedef:
4678 case Decl::TypeAlias:
4679 case Decl::TypeAliasTemplate:
4680 case Decl::TemplateTypeParm:
4681 case Decl::EnumConstant:
4682 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004683 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 case Decl::IndirectField:
4685 case Decl::ObjCIvar:
4686 case Decl::ObjCAtDefsField:
4687 case Decl::ImplicitParam:
4688 case Decl::ParmVar:
4689 case Decl::NonTypeTemplateParm:
4690 case Decl::TemplateTemplateParm:
4691 case Decl::ObjCCategoryImpl:
4692 case Decl::ObjCImplementation:
4693 case Decl::AccessSpec:
4694 case Decl::LinkageSpec:
4695 case Decl::ObjCPropertyImpl:
4696 case Decl::FileScopeAsm:
4697 case Decl::StaticAssert:
4698 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004699 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004700 case Decl::Label: // FIXME: Is this right??
4701 case Decl::ClassScopeFunctionSpecialization:
4702 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004703 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004704 return C;
4705
4706 // Declaration kinds that don't make any sense here, but are
4707 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004708 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 case Decl::TranslationUnit:
4710 break;
4711
4712 // Declaration kinds for which the definition is not resolvable.
4713 case Decl::UnresolvedUsingTypename:
4714 case Decl::UnresolvedUsingValue:
4715 break;
4716
4717 case Decl::UsingDirective:
4718 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4719 TU);
4720
4721 case Decl::NamespaceAlias:
4722 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4723
4724 case Decl::Enum:
4725 case Decl::Record:
4726 case Decl::CXXRecord:
4727 case Decl::ClassTemplateSpecialization:
4728 case Decl::ClassTemplatePartialSpecialization:
4729 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4730 return MakeCXCursor(Def, TU);
4731 return clang_getNullCursor();
4732
4733 case Decl::Function:
4734 case Decl::CXXMethod:
4735 case Decl::CXXConstructor:
4736 case Decl::CXXDestructor:
4737 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004738 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004740 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 return clang_getNullCursor();
4742 }
4743
Larisse Voufo39a1e502013-08-06 01:03:05 +00004744 case Decl::Var:
4745 case Decl::VarTemplateSpecialization:
4746 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004748 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 return MakeCXCursor(Def, TU);
4750 return clang_getNullCursor();
4751 }
4752
4753 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004754 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4756 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4757 return clang_getNullCursor();
4758 }
4759
4760 case Decl::ClassTemplate: {
4761 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4762 ->getDefinition())
4763 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4764 TU);
4765 return clang_getNullCursor();
4766 }
4767
Larisse Voufo39a1e502013-08-06 01:03:05 +00004768 case Decl::VarTemplate: {
4769 if (VarDecl *Def =
4770 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4771 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4772 return clang_getNullCursor();
4773 }
4774
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 case Decl::Using:
4776 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4777 D->getLocation(), TU);
4778
4779 case Decl::UsingShadow:
4780 return clang_getCursorDefinition(
4781 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4782 TU));
4783
4784 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004785 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 if (Method->isThisDeclarationADefinition())
4787 return C;
4788
4789 // Dig out the method definition in the associated
4790 // @implementation, if we have it.
4791 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004792 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4794 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4795 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4796 Method->isInstanceMethod()))
4797 if (Def->isThisDeclarationADefinition())
4798 return MakeCXCursor(Def, TU);
4799
4800 return clang_getNullCursor();
4801 }
4802
4803 case Decl::ObjCCategory:
4804 if (ObjCCategoryImplDecl *Impl
4805 = cast<ObjCCategoryDecl>(D)->getImplementation())
4806 return MakeCXCursor(Impl, TU);
4807 return clang_getNullCursor();
4808
4809 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004810 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004811 return MakeCXCursor(Def, TU);
4812 return clang_getNullCursor();
4813
4814 case Decl::ObjCInterface: {
4815 // There are two notions of a "definition" for an Objective-C
4816 // class: the interface and its implementation. When we resolved a
4817 // reference to an Objective-C class, produce the @interface as
4818 // the definition; when we were provided with the interface,
4819 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004820 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004821 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004822 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 return MakeCXCursor(Def, TU);
4824 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4825 return MakeCXCursor(Impl, TU);
4826 return clang_getNullCursor();
4827 }
4828
4829 case Decl::ObjCProperty:
4830 // FIXME: We don't really know where to find the
4831 // ObjCPropertyImplDecls that implement this property.
4832 return clang_getNullCursor();
4833
4834 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004835 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004836 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004837 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 return MakeCXCursor(Def, TU);
4839
4840 return clang_getNullCursor();
4841
4842 case Decl::Friend:
4843 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4844 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4845 return clang_getNullCursor();
4846
4847 case Decl::FriendTemplate:
4848 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4849 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4850 return clang_getNullCursor();
4851 }
4852
4853 return clang_getNullCursor();
4854}
4855
4856unsigned clang_isCursorDefinition(CXCursor C) {
4857 if (!clang_isDeclaration(C.kind))
4858 return 0;
4859
4860 return clang_getCursorDefinition(C) == C;
4861}
4862
4863CXCursor clang_getCanonicalCursor(CXCursor C) {
4864 if (!clang_isDeclaration(C.kind))
4865 return C;
4866
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004867 if (const Decl *D = getCursorDecl(C)) {
4868 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4870 return MakeCXCursor(CatD, getCursorTU(C));
4871
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004872 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4873 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004874 return MakeCXCursor(IFD, getCursorTU(C));
4875
4876 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4877 }
4878
4879 return C;
4880}
4881
4882int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4883 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4884}
4885
4886unsigned clang_getNumOverloadedDecls(CXCursor C) {
4887 if (C.kind != CXCursor_OverloadedDeclRef)
4888 return 0;
4889
4890 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004891 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004892 return E->getNumDecls();
4893
4894 if (OverloadedTemplateStorage *S
4895 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4896 return S->size();
4897
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004898 const Decl *D = Storage.get<const Decl *>();
4899 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004900 return Using->shadow_size();
4901
4902 return 0;
4903}
4904
4905CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4906 if (cursor.kind != CXCursor_OverloadedDeclRef)
4907 return clang_getNullCursor();
4908
4909 if (index >= clang_getNumOverloadedDecls(cursor))
4910 return clang_getNullCursor();
4911
4912 CXTranslationUnit TU = getCursorTU(cursor);
4913 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004914 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 return MakeCXCursor(E->decls_begin()[index], TU);
4916
4917 if (OverloadedTemplateStorage *S
4918 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4919 return MakeCXCursor(S->begin()[index], TU);
4920
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004921 const Decl *D = Storage.get<const Decl *>();
4922 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 // FIXME: This is, unfortunately, linear time.
4924 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4925 std::advance(Pos, index);
4926 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4927 }
4928
4929 return clang_getNullCursor();
4930}
4931
4932void clang_getDefinitionSpellingAndExtent(CXCursor C,
4933 const char **startBuf,
4934 const char **endBuf,
4935 unsigned *startLine,
4936 unsigned *startColumn,
4937 unsigned *endLine,
4938 unsigned *endColumn) {
4939 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004940 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004941 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4942
4943 SourceManager &SM = FD->getASTContext().getSourceManager();
4944 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4945 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4946 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4947 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4948 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4949 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4950}
4951
4952
4953CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4954 unsigned PieceIndex) {
4955 RefNamePieces Pieces;
4956
4957 switch (C.kind) {
4958 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004959 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004960 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4961 E->getQualifierLoc().getSourceRange());
4962 break;
4963
4964 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004965 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004966 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4967 E->getQualifierLoc().getSourceRange(),
4968 E->getOptionalExplicitTemplateArgs());
4969 break;
4970
4971 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004972 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004973 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004974 const Expr *Callee = OCE->getCallee();
4975 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004976 Callee = ICE->getSubExpr();
4977
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004978 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004979 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4980 DRE->getQualifierLoc().getSourceRange());
4981 }
4982 break;
4983
4984 default:
4985 break;
4986 }
4987
4988 if (Pieces.empty()) {
4989 if (PieceIndex == 0)
4990 return clang_getCursorExtent(C);
4991 } else if (PieceIndex < Pieces.size()) {
4992 SourceRange R = Pieces[PieceIndex];
4993 if (R.isValid())
4994 return cxloc::translateSourceRange(getCursorContext(C), R);
4995 }
4996
4997 return clang_getNullRange();
4998}
4999
5000void clang_enableStackTraces(void) {
5001 llvm::sys::PrintStackTraceOnErrorSignal();
5002}
5003
5004void clang_executeOnThread(void (*fn)(void*), void *user_data,
5005 unsigned stack_size) {
5006 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5007}
5008
5009} // end: extern "C"
5010
5011//===----------------------------------------------------------------------===//
5012// Token-based Operations.
5013//===----------------------------------------------------------------------===//
5014
5015/* CXToken layout:
5016 * int_data[0]: a CXTokenKind
5017 * int_data[1]: starting token location
5018 * int_data[2]: token length
5019 * int_data[3]: reserved
5020 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5021 * otherwise unused.
5022 */
5023extern "C" {
5024
5025CXTokenKind clang_getTokenKind(CXToken CXTok) {
5026 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5027}
5028
5029CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5030 switch (clang_getTokenKind(CXTok)) {
5031 case CXToken_Identifier:
5032 case CXToken_Keyword:
5033 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005034 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005035 ->getNameStart());
5036
5037 case CXToken_Literal: {
5038 // We have stashed the starting pointer in the ptr_data field. Use it.
5039 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005040 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005041 }
5042
5043 case CXToken_Punctuation:
5044 case CXToken_Comment:
5045 break;
5046 }
5047
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005048 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005049 LOG_BAD_TU(TU);
5050 return cxstring::createEmpty();
5051 }
5052
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 // We have to find the starting buffer pointer the hard way, by
5054 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005055 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005057 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005058
5059 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5060 std::pair<FileID, unsigned> LocInfo
5061 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5062 bool Invalid = false;
5063 StringRef Buffer
5064 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5065 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005066 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005067
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005068 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005069}
5070
5071CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005072 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005073 LOG_BAD_TU(TU);
5074 return clang_getNullLocation();
5075 }
5076
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005077 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005078 if (!CXXUnit)
5079 return clang_getNullLocation();
5080
5081 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5082 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5083}
5084
5085CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005086 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005087 LOG_BAD_TU(TU);
5088 return clang_getNullRange();
5089 }
5090
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005091 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 if (!CXXUnit)
5093 return clang_getNullRange();
5094
5095 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5096 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5097}
5098
5099static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5100 SmallVectorImpl<CXToken> &CXTokens) {
5101 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5102 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005103 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005104 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005105 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005106
5107 // Cannot tokenize across files.
5108 if (BeginLocInfo.first != EndLocInfo.first)
5109 return;
5110
5111 // Create a lexer
5112 bool Invalid = false;
5113 StringRef Buffer
5114 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5115 if (Invalid)
5116 return;
5117
5118 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5119 CXXUnit->getASTContext().getLangOpts(),
5120 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5121 Lex.SetCommentRetentionState(true);
5122
5123 // Lex tokens until we hit the end of the range.
5124 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5125 Token Tok;
5126 bool previousWasAt = false;
5127 do {
5128 // Lex the next token
5129 Lex.LexFromRawLexer(Tok);
5130 if (Tok.is(tok::eof))
5131 break;
5132
5133 // Initialize the CXToken.
5134 CXToken CXTok;
5135
5136 // - Common fields
5137 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5138 CXTok.int_data[2] = Tok.getLength();
5139 CXTok.int_data[3] = 0;
5140
5141 // - Kind-specific fields
5142 if (Tok.isLiteral()) {
5143 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005144 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 } else if (Tok.is(tok::raw_identifier)) {
5146 // Lookup the identifier to determine whether we have a keyword.
5147 IdentifierInfo *II
5148 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5149
5150 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5151 CXTok.int_data[0] = CXToken_Keyword;
5152 }
5153 else {
5154 CXTok.int_data[0] = Tok.is(tok::identifier)
5155 ? CXToken_Identifier
5156 : CXToken_Keyword;
5157 }
5158 CXTok.ptr_data = II;
5159 } else if (Tok.is(tok::comment)) {
5160 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005161 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 } else {
5163 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005164 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005165 }
5166 CXTokens.push_back(CXTok);
5167 previousWasAt = Tok.is(tok::at);
5168 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5169}
5170
5171void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5172 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005173 LOG_FUNC_SECTION {
5174 *Log << TU << ' ' << Range;
5175 }
5176
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005178 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005179 if (NumTokens)
5180 *NumTokens = 0;
5181
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005182 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005183 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005184 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005185 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005186
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005187 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 if (!CXXUnit || !Tokens || !NumTokens)
5189 return;
5190
5191 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5192
5193 SourceRange R = cxloc::translateCXSourceRange(Range);
5194 if (R.isInvalid())
5195 return;
5196
5197 SmallVector<CXToken, 32> CXTokens;
5198 getTokens(CXXUnit, R, CXTokens);
5199
5200 if (CXTokens.empty())
5201 return;
5202
5203 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5204 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5205 *NumTokens = CXTokens.size();
5206}
5207
5208void clang_disposeTokens(CXTranslationUnit TU,
5209 CXToken *Tokens, unsigned NumTokens) {
5210 free(Tokens);
5211}
5212
5213} // end: extern "C"
5214
5215//===----------------------------------------------------------------------===//
5216// Token annotation APIs.
5217//===----------------------------------------------------------------------===//
5218
Guy Benyei11169dd2012-12-18 14:30:41 +00005219static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5220 CXCursor parent,
5221 CXClientData client_data);
5222static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5223 CXClientData client_data);
5224
5225namespace {
5226class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 CXToken *Tokens;
5228 CXCursor *Cursors;
5229 unsigned NumTokens;
5230 unsigned TokIdx;
5231 unsigned PreprocessingTokIdx;
5232 CursorVisitor AnnotateVis;
5233 SourceManager &SrcMgr;
5234 bool HasContextSensitiveKeywords;
5235
5236 struct PostChildrenInfo {
5237 CXCursor Cursor;
5238 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005239 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 unsigned BeforeChildrenTokenIdx;
5241 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005242 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005243
5244 CXToken &getTok(unsigned Idx) {
5245 assert(Idx < NumTokens);
5246 return Tokens[Idx];
5247 }
5248 const CXToken &getTok(unsigned Idx) const {
5249 assert(Idx < NumTokens);
5250 return Tokens[Idx];
5251 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 bool MoreTokens() const { return TokIdx < NumTokens; }
5253 unsigned NextToken() const { return TokIdx; }
5254 void AdvanceToken() { ++TokIdx; }
5255 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005256 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005257 }
5258 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005259 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 }
5261 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005262 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005263 }
5264
5265 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005266 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005267 SourceRange);
5268
5269public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005270 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005271 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005272 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005273 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005274 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 AnnotateTokensVisitor, this,
5276 /*VisitPreprocessorLast=*/true,
5277 /*VisitIncludedEntities=*/false,
5278 RegionOfInterest,
5279 /*VisitDeclsOnly=*/false,
5280 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005281 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 HasContextSensitiveKeywords(false) { }
5283
5284 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5285 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5286 bool postVisitChildren(CXCursor cursor);
5287 void AnnotateTokens();
5288
5289 /// \brief Determine whether the annotator saw any cursors that have
5290 /// context-sensitive keywords.
5291 bool hasContextSensitiveKeywords() const {
5292 return HasContextSensitiveKeywords;
5293 }
5294
5295 ~AnnotateTokensWorker() {
5296 assert(PostChildrenInfos.empty());
5297 }
5298};
5299}
5300
5301void AnnotateTokensWorker::AnnotateTokens() {
5302 // Walk the AST within the region of interest, annotating tokens
5303 // along the way.
5304 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005305}
Guy Benyei11169dd2012-12-18 14:30:41 +00005306
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005307static inline void updateCursorAnnotation(CXCursor &Cursor,
5308 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005309 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005311 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005312}
5313
5314/// \brief It annotates and advances tokens with a cursor until the comparison
5315//// between the cursor location and the source range is the same as
5316/// \arg compResult.
5317///
5318/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5319/// Pass RangeOverlap to annotate tokens inside a range.
5320void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5321 RangeComparisonResult compResult,
5322 SourceRange range) {
5323 while (MoreTokens()) {
5324 const unsigned I = NextToken();
5325 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005326 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5327 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005328
5329 SourceLocation TokLoc = GetTokenLoc(I);
5330 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005331 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 AdvanceToken();
5333 continue;
5334 }
5335 break;
5336 }
5337}
5338
5339/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005340/// \returns true if it advanced beyond all macro tokens, false otherwise.
5341bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 CXCursor updateC,
5343 RangeComparisonResult compResult,
5344 SourceRange range) {
5345 assert(MoreTokens());
5346 assert(isFunctionMacroToken(NextToken()) &&
5347 "Should be called only for macro arg tokens");
5348
5349 // This works differently than annotateAndAdvanceTokens; because expanded
5350 // macro arguments can have arbitrary translation-unit source order, we do not
5351 // advance the token index one by one until a token fails the range test.
5352 // We only advance once past all of the macro arg tokens if all of them
5353 // pass the range test. If one of them fails we keep the token index pointing
5354 // at the start of the macro arg tokens so that the failing token will be
5355 // annotated by a subsequent annotation try.
5356
5357 bool atLeastOneCompFail = false;
5358
5359 unsigned I = NextToken();
5360 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5361 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5362 if (TokLoc.isFileID())
5363 continue; // not macro arg token, it's parens or comma.
5364 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5365 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5366 Cursors[I] = updateC;
5367 } else
5368 atLeastOneCompFail = true;
5369 }
5370
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005371 if (atLeastOneCompFail)
5372 return false;
5373
5374 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5375 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005376}
5377
5378enum CXChildVisitResult
5379AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 SourceRange cursorRange = getRawCursorExtent(cursor);
5381 if (cursorRange.isInvalid())
5382 return CXChildVisit_Recurse;
5383
5384 if (!HasContextSensitiveKeywords) {
5385 // Objective-C properties can have context-sensitive keywords.
5386 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005387 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005388 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5389 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5390 }
5391 // Objective-C methods can have context-sensitive keywords.
5392 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5393 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005394 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5396 if (Method->getObjCDeclQualifier())
5397 HasContextSensitiveKeywords = true;
5398 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005399 for (const auto *P : Method->params()) {
5400 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005401 HasContextSensitiveKeywords = true;
5402 break;
5403 }
5404 }
5405 }
5406 }
5407 }
5408 // C++ methods can have context-sensitive keywords.
5409 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005410 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005411 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5412 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5413 HasContextSensitiveKeywords = true;
5414 }
5415 }
5416 // C++ classes can have context-sensitive keywords.
5417 else if (cursor.kind == CXCursor_StructDecl ||
5418 cursor.kind == CXCursor_ClassDecl ||
5419 cursor.kind == CXCursor_ClassTemplate ||
5420 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005421 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 if (D->hasAttr<FinalAttr>())
5423 HasContextSensitiveKeywords = true;
5424 }
5425 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005426
5427 // Don't override a property annotation with its getter/setter method.
5428 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5429 parent.kind == CXCursor_ObjCPropertyDecl)
5430 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005431
5432 if (clang_isPreprocessing(cursor.kind)) {
5433 // Items in the preprocessing record are kept separate from items in
5434 // declarations, so we keep a separate token index.
5435 unsigned SavedTokIdx = TokIdx;
5436 TokIdx = PreprocessingTokIdx;
5437
5438 // Skip tokens up until we catch up to the beginning of the preprocessing
5439 // entry.
5440 while (MoreTokens()) {
5441 const unsigned I = NextToken();
5442 SourceLocation TokLoc = GetTokenLoc(I);
5443 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5444 case RangeBefore:
5445 AdvanceToken();
5446 continue;
5447 case RangeAfter:
5448 case RangeOverlap:
5449 break;
5450 }
5451 break;
5452 }
5453
5454 // Look at all of the tokens within this range.
5455 while (MoreTokens()) {
5456 const unsigned I = NextToken();
5457 SourceLocation TokLoc = GetTokenLoc(I);
5458 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5459 case RangeBefore:
5460 llvm_unreachable("Infeasible");
5461 case RangeAfter:
5462 break;
5463 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005464 // For macro expansions, just note where the beginning of the macro
5465 // expansion occurs.
5466 if (cursor.kind == CXCursor_MacroExpansion) {
5467 if (TokLoc == cursorRange.getBegin())
5468 Cursors[I] = cursor;
5469 AdvanceToken();
5470 break;
5471 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005472 // We may have already annotated macro names inside macro definitions.
5473 if (Cursors[I].kind != CXCursor_MacroExpansion)
5474 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 continue;
5477 }
5478 break;
5479 }
5480
5481 // Save the preprocessing token index; restore the non-preprocessing
5482 // token index.
5483 PreprocessingTokIdx = TokIdx;
5484 TokIdx = SavedTokIdx;
5485 return CXChildVisit_Recurse;
5486 }
5487
5488 if (cursorRange.isInvalid())
5489 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005490
5491 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005492 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005493 const enum CXCursorKind K = clang_getCursorKind(parent);
5494 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005495 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5496 // Attributes are annotated out-of-order, skip tokens until we reach it.
5497 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005498 ? clang_getNullCursor() : parent;
5499
5500 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5501
5502 // Avoid having the cursor of an expression "overwrite" the annotation of the
5503 // variable declaration that it belongs to.
5504 // This can happen for C++ constructor expressions whose range generally
5505 // include the variable declaration, e.g.:
5506 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005507 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005508 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005509 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005510 const unsigned I = NextToken();
5511 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5512 E->getLocStart() == D->getLocation() &&
5513 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005514 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 AdvanceToken();
5516 }
5517 }
5518 }
5519
5520 // Before recursing into the children keep some state that we are going
5521 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5522 // extra work after the child nodes are visited.
5523 // Note that we don't call VisitChildren here to avoid traversing statements
5524 // code-recursively which can blow the stack.
5525
5526 PostChildrenInfo Info;
5527 Info.Cursor = cursor;
5528 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005529 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005530 Info.BeforeChildrenTokenIdx = NextToken();
5531 PostChildrenInfos.push_back(Info);
5532
5533 return CXChildVisit_Recurse;
5534}
5535
5536bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5537 if (PostChildrenInfos.empty())
5538 return false;
5539 const PostChildrenInfo &Info = PostChildrenInfos.back();
5540 if (!clang_equalCursors(Info.Cursor, cursor))
5541 return false;
5542
5543 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5544 const unsigned AfterChildren = NextToken();
5545 SourceRange cursorRange = Info.CursorRange;
5546
5547 // Scan the tokens that are at the end of the cursor, but are not captured
5548 // but the child cursors.
5549 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5550
5551 // Scan the tokens that are at the beginning of the cursor, but are not
5552 // capture by the child cursors.
5553 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5554 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5555 break;
5556
5557 Cursors[I] = cursor;
5558 }
5559
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005560 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5561 // encountered the attribute cursor.
5562 if (clang_isAttribute(cursor.kind))
5563 TokIdx = Info.BeforeReachingCursorIdx;
5564
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 PostChildrenInfos.pop_back();
5566 return false;
5567}
5568
5569static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5570 CXCursor parent,
5571 CXClientData client_data) {
5572 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5573}
5574
5575static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5576 CXClientData client_data) {
5577 return static_cast<AnnotateTokensWorker*>(client_data)->
5578 postVisitChildren(cursor);
5579}
5580
5581namespace {
5582
5583/// \brief Uses the macro expansions in the preprocessing record to find
5584/// and mark tokens that are macro arguments. This info is used by the
5585/// AnnotateTokensWorker.
5586class MarkMacroArgTokensVisitor {
5587 SourceManager &SM;
5588 CXToken *Tokens;
5589 unsigned NumTokens;
5590 unsigned CurIdx;
5591
5592public:
5593 MarkMacroArgTokensVisitor(SourceManager &SM,
5594 CXToken *tokens, unsigned numTokens)
5595 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5596
5597 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5598 if (cursor.kind != CXCursor_MacroExpansion)
5599 return CXChildVisit_Continue;
5600
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005601 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005602 if (macroRange.getBegin() == macroRange.getEnd())
5603 return CXChildVisit_Continue; // it's not a function macro.
5604
5605 for (; CurIdx < NumTokens; ++CurIdx) {
5606 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5607 macroRange.getBegin()))
5608 break;
5609 }
5610
5611 if (CurIdx == NumTokens)
5612 return CXChildVisit_Break;
5613
5614 for (; CurIdx < NumTokens; ++CurIdx) {
5615 SourceLocation tokLoc = getTokenLoc(CurIdx);
5616 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5617 break;
5618
5619 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5620 }
5621
5622 if (CurIdx == NumTokens)
5623 return CXChildVisit_Break;
5624
5625 return CXChildVisit_Continue;
5626 }
5627
5628private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005629 CXToken &getTok(unsigned Idx) {
5630 assert(Idx < NumTokens);
5631 return Tokens[Idx];
5632 }
5633 const CXToken &getTok(unsigned Idx) const {
5634 assert(Idx < NumTokens);
5635 return Tokens[Idx];
5636 }
5637
Guy Benyei11169dd2012-12-18 14:30:41 +00005638 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005639 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 }
5641
5642 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5643 // The third field is reserved and currently not used. Use it here
5644 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005645 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 }
5647};
5648
5649} // end anonymous namespace
5650
5651static CXChildVisitResult
5652MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5653 CXClientData client_data) {
5654 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5655 parent);
5656}
5657
5658namespace {
5659 struct clang_annotateTokens_Data {
5660 CXTranslationUnit TU;
5661 ASTUnit *CXXUnit;
5662 CXToken *Tokens;
5663 unsigned NumTokens;
5664 CXCursor *Cursors;
5665 };
5666}
5667
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005668/// \brief Used by \c annotatePreprocessorTokens.
5669/// \returns true if lexing was finished, false otherwise.
5670static bool lexNext(Lexer &Lex, Token &Tok,
5671 unsigned &NextIdx, unsigned NumTokens) {
5672 if (NextIdx >= NumTokens)
5673 return true;
5674
5675 ++NextIdx;
5676 Lex.LexFromRawLexer(Tok);
5677 if (Tok.is(tok::eof))
5678 return true;
5679
5680 return false;
5681}
5682
Guy Benyei11169dd2012-12-18 14:30:41 +00005683static void annotatePreprocessorTokens(CXTranslationUnit TU,
5684 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005685 CXCursor *Cursors,
5686 CXToken *Tokens,
5687 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005688 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005689
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005690 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5692 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005693 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005694 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005695 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005696
5697 if (BeginLocInfo.first != EndLocInfo.first)
5698 return;
5699
5700 StringRef Buffer;
5701 bool Invalid = false;
5702 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5703 if (Buffer.empty() || Invalid)
5704 return;
5705
5706 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5707 CXXUnit->getASTContext().getLangOpts(),
5708 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5709 Buffer.end());
5710 Lex.SetCommentRetentionState(true);
5711
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005712 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005713 // Lex tokens in raw mode until we hit the end of the range, to avoid
5714 // entering #includes or expanding macros.
5715 while (true) {
5716 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005717 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5718 break;
5719 unsigned TokIdx = NextIdx-1;
5720 assert(Tok.getLocation() ==
5721 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005722
5723 reprocess:
5724 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005725 // We have found a preprocessing directive. Annotate the tokens
5726 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005727 //
5728 // FIXME: Some simple tests here could identify macro definitions and
5729 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005730
5731 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005732 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5733 break;
5734
Craig Topper69186e72014-06-08 08:38:04 +00005735 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005736 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005737 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5738 break;
5739
5740 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005741 IdentifierInfo &II =
5742 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005743 SourceLocation MappedTokLoc =
5744 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5745 MI = getMacroInfo(II, MappedTokLoc, TU);
5746 }
5747 }
5748
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005749 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005751 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5752 finished = true;
5753 break;
5754 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005755 // If we are in a macro definition, check if the token was ever a
5756 // macro name and annotate it if that's the case.
5757 if (MI) {
5758 SourceLocation SaveLoc = Tok.getLocation();
5759 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5760 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5761 Tok.setLocation(SaveLoc);
5762 if (MacroDef)
5763 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5764 Tok.getLocation(), TU);
5765 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005766 } while (!Tok.isAtStartOfLine());
5767
5768 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5769 assert(TokIdx <= LastIdx);
5770 SourceLocation EndLoc =
5771 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5772 CXCursor Cursor =
5773 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5774
5775 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005776 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005777
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005778 if (finished)
5779 break;
5780 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005781 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005782 }
5783}
5784
5785// This gets run a separate thread to avoid stack blowout.
5786static void clang_annotateTokensImpl(void *UserData) {
5787 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5788 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5789 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5790 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5791 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5792
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005793 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005794 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5795 setThreadBackgroundPriority();
5796
5797 // Determine the region of interest, which contains all of the tokens.
5798 SourceRange RegionOfInterest;
5799 RegionOfInterest.setBegin(
5800 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5801 RegionOfInterest.setEnd(
5802 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5803 Tokens[NumTokens-1])));
5804
Guy Benyei11169dd2012-12-18 14:30:41 +00005805 // Relex the tokens within the source range to look for preprocessing
5806 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005807 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005808
5809 // If begin location points inside a macro argument, set it to the expansion
5810 // location so we can have the full context when annotating semantically.
5811 {
5812 SourceManager &SM = CXXUnit->getSourceManager();
5813 SourceLocation Loc =
5814 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5815 if (Loc.isMacroID())
5816 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5817 }
5818
Guy Benyei11169dd2012-12-18 14:30:41 +00005819 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5820 // Search and mark tokens that are macro argument expansions.
5821 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5822 Tokens, NumTokens);
5823 CursorVisitor MacroArgMarker(TU,
5824 MarkMacroArgTokensVisitorDelegate, &Visitor,
5825 /*VisitPreprocessorLast=*/true,
5826 /*VisitIncludedEntities=*/false,
5827 RegionOfInterest);
5828 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5829 }
5830
5831 // Annotate all of the source locations in the region of interest that map to
5832 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005833 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005834
5835 // FIXME: We use a ridiculous stack size here because the data-recursion
5836 // algorithm uses a large stack frame than the non-data recursive version,
5837 // and AnnotationTokensWorker currently transforms the data-recursion
5838 // algorithm back into a traditional recursion by explicitly calling
5839 // VisitChildren(). We will need to remove this explicit recursive call.
5840 W.AnnotateTokens();
5841
5842 // If we ran into any entities that involve context-sensitive keywords,
5843 // take another pass through the tokens to mark them as such.
5844 if (W.hasContextSensitiveKeywords()) {
5845 for (unsigned I = 0; I != NumTokens; ++I) {
5846 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5847 continue;
5848
5849 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5850 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005851 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005852 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5853 if (Property->getPropertyAttributesAsWritten() != 0 &&
5854 llvm::StringSwitch<bool>(II->getName())
5855 .Case("readonly", true)
5856 .Case("assign", true)
5857 .Case("unsafe_unretained", true)
5858 .Case("readwrite", true)
5859 .Case("retain", true)
5860 .Case("copy", true)
5861 .Case("nonatomic", true)
5862 .Case("atomic", true)
5863 .Case("getter", true)
5864 .Case("setter", true)
5865 .Case("strong", true)
5866 .Case("weak", true)
5867 .Default(false))
5868 Tokens[I].int_data[0] = CXToken_Keyword;
5869 }
5870 continue;
5871 }
5872
5873 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5874 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5875 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5876 if (llvm::StringSwitch<bool>(II->getName())
5877 .Case("in", true)
5878 .Case("out", true)
5879 .Case("inout", true)
5880 .Case("oneway", true)
5881 .Case("bycopy", true)
5882 .Case("byref", true)
5883 .Default(false))
5884 Tokens[I].int_data[0] = CXToken_Keyword;
5885 continue;
5886 }
5887
5888 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5889 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5890 Tokens[I].int_data[0] = CXToken_Keyword;
5891 continue;
5892 }
5893 }
5894 }
5895}
5896
5897extern "C" {
5898
5899void clang_annotateTokens(CXTranslationUnit TU,
5900 CXToken *Tokens, unsigned NumTokens,
5901 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005902 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005903 LOG_BAD_TU(TU);
5904 return;
5905 }
5906 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005907 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005908 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005909 }
5910
5911 LOG_FUNC_SECTION {
5912 *Log << TU << ' ';
5913 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5914 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5915 *Log << clang_getRange(bloc, eloc);
5916 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005917
5918 // Any token we don't specifically annotate will have a NULL cursor.
5919 CXCursor C = clang_getNullCursor();
5920 for (unsigned I = 0; I != NumTokens; ++I)
5921 Cursors[I] = C;
5922
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005923 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 if (!CXXUnit)
5925 return;
5926
5927 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5928
5929 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5930 llvm::CrashRecoveryContext CRC;
5931 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5932 GetSafetyThreadStackSize() * 2)) {
5933 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5934 }
5935}
5936
5937} // end: extern "C"
5938
5939//===----------------------------------------------------------------------===//
5940// Operations for querying linkage of a cursor.
5941//===----------------------------------------------------------------------===//
5942
5943extern "C" {
5944CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5945 if (!clang_isDeclaration(cursor.kind))
5946 return CXLinkage_Invalid;
5947
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005948 const Decl *D = cxcursor::getCursorDecl(cursor);
5949 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005950 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005951 case NoLinkage:
5952 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005953 case InternalLinkage: return CXLinkage_Internal;
5954 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5955 case ExternalLinkage: return CXLinkage_External;
5956 };
5957
5958 return CXLinkage_Invalid;
5959}
5960} // end: extern "C"
5961
5962//===----------------------------------------------------------------------===//
5963// Operations for querying language of a cursor.
5964//===----------------------------------------------------------------------===//
5965
5966static CXLanguageKind getDeclLanguage(const Decl *D) {
5967 if (!D)
5968 return CXLanguage_C;
5969
5970 switch (D->getKind()) {
5971 default:
5972 break;
5973 case Decl::ImplicitParam:
5974 case Decl::ObjCAtDefsField:
5975 case Decl::ObjCCategory:
5976 case Decl::ObjCCategoryImpl:
5977 case Decl::ObjCCompatibleAlias:
5978 case Decl::ObjCImplementation:
5979 case Decl::ObjCInterface:
5980 case Decl::ObjCIvar:
5981 case Decl::ObjCMethod:
5982 case Decl::ObjCProperty:
5983 case Decl::ObjCPropertyImpl:
5984 case Decl::ObjCProtocol:
5985 return CXLanguage_ObjC;
5986 case Decl::CXXConstructor:
5987 case Decl::CXXConversion:
5988 case Decl::CXXDestructor:
5989 case Decl::CXXMethod:
5990 case Decl::CXXRecord:
5991 case Decl::ClassTemplate:
5992 case Decl::ClassTemplatePartialSpecialization:
5993 case Decl::ClassTemplateSpecialization:
5994 case Decl::Friend:
5995 case Decl::FriendTemplate:
5996 case Decl::FunctionTemplate:
5997 case Decl::LinkageSpec:
5998 case Decl::Namespace:
5999 case Decl::NamespaceAlias:
6000 case Decl::NonTypeTemplateParm:
6001 case Decl::StaticAssert:
6002 case Decl::TemplateTemplateParm:
6003 case Decl::TemplateTypeParm:
6004 case Decl::UnresolvedUsingTypename:
6005 case Decl::UnresolvedUsingValue:
6006 case Decl::Using:
6007 case Decl::UsingDirective:
6008 case Decl::UsingShadow:
6009 return CXLanguage_CPlusPlus;
6010 }
6011
6012 return CXLanguage_C;
6013}
6014
6015extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006016
6017static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6018 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6019 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006020
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006021 switch (D->getAvailability()) {
6022 case AR_Available:
6023 case AR_NotYetIntroduced:
6024 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006025 return getCursorAvailabilityForDecl(
6026 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006027 return CXAvailability_Available;
6028
6029 case AR_Deprecated:
6030 return CXAvailability_Deprecated;
6031
6032 case AR_Unavailable:
6033 return CXAvailability_NotAvailable;
6034 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006035
6036 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006037}
6038
Guy Benyei11169dd2012-12-18 14:30:41 +00006039enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6040 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006041 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6042 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006043
6044 return CXAvailability_Available;
6045}
6046
6047static CXVersion convertVersion(VersionTuple In) {
6048 CXVersion Out = { -1, -1, -1 };
6049 if (In.empty())
6050 return Out;
6051
6052 Out.Major = In.getMajor();
6053
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006054 Optional<unsigned> Minor = In.getMinor();
6055 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006056 Out.Minor = *Minor;
6057 else
6058 return Out;
6059
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006060 Optional<unsigned> Subminor = In.getSubminor();
6061 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006062 Out.Subminor = *Subminor;
6063
6064 return Out;
6065}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006066
6067static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6068 int *always_deprecated,
6069 CXString *deprecated_message,
6070 int *always_unavailable,
6071 CXString *unavailable_message,
6072 CXPlatformAvailability *availability,
6073 int availability_size) {
6074 bool HadAvailAttr = false;
6075 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006076 for (auto A : D->attrs()) {
6077 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006078 HadAvailAttr = true;
6079 if (always_deprecated)
6080 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006081 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006082 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006083 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006084 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006085 continue;
6086 }
6087
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006088 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006089 HadAvailAttr = true;
6090 if (always_unavailable)
6091 *always_unavailable = 1;
6092 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006093 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006094 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6095 }
6096 continue;
6097 }
6098
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006099 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006100 HadAvailAttr = true;
6101 if (N < availability_size) {
6102 availability[N].Platform
6103 = cxstring::createDup(Avail->getPlatform()->getName());
6104 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6105 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6106 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6107 availability[N].Unavailable = Avail->getUnavailable();
6108 availability[N].Message = cxstring::createDup(Avail->getMessage());
6109 }
6110 ++N;
6111 }
6112 }
6113
6114 if (!HadAvailAttr)
6115 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6116 return getCursorPlatformAvailabilityForDecl(
6117 cast<Decl>(EnumConst->getDeclContext()),
6118 always_deprecated,
6119 deprecated_message,
6120 always_unavailable,
6121 unavailable_message,
6122 availability,
6123 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006124
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006125 return N;
6126}
6127
Guy Benyei11169dd2012-12-18 14:30:41 +00006128int clang_getCursorPlatformAvailability(CXCursor cursor,
6129 int *always_deprecated,
6130 CXString *deprecated_message,
6131 int *always_unavailable,
6132 CXString *unavailable_message,
6133 CXPlatformAvailability *availability,
6134 int availability_size) {
6135 if (always_deprecated)
6136 *always_deprecated = 0;
6137 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006138 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 if (always_unavailable)
6140 *always_unavailable = 0;
6141 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006142 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006143
Guy Benyei11169dd2012-12-18 14:30:41 +00006144 if (!clang_isDeclaration(cursor.kind))
6145 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006146
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006147 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006148 if (!D)
6149 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006150
6151 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6152 deprecated_message,
6153 always_unavailable,
6154 unavailable_message,
6155 availability,
6156 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006157}
6158
6159void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6160 clang_disposeString(availability->Platform);
6161 clang_disposeString(availability->Message);
6162}
6163
6164CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6165 if (clang_isDeclaration(cursor.kind))
6166 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6167
6168 return CXLanguage_Invalid;
6169}
6170
6171 /// \brief If the given cursor is the "templated" declaration
6172 /// descibing a class or function template, return the class or
6173 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006174static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006175 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006176 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006177
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006178 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006179 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6180 return FunTmpl;
6181
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006182 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006183 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6184 return ClassTmpl;
6185
6186 return D;
6187}
6188
6189CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6190 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006191 if (const Decl *D = getCursorDecl(cursor)) {
6192 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006193 if (!DC)
6194 return clang_getNullCursor();
6195
6196 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6197 getCursorTU(cursor));
6198 }
6199 }
6200
6201 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006202 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006203 return MakeCXCursor(D, getCursorTU(cursor));
6204 }
6205
6206 return clang_getNullCursor();
6207}
6208
6209CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6210 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006211 if (const Decl *D = getCursorDecl(cursor)) {
6212 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006213 if (!DC)
6214 return clang_getNullCursor();
6215
6216 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6217 getCursorTU(cursor));
6218 }
6219 }
6220
6221 // FIXME: Note that we can't easily compute the lexical context of a
6222 // statement or expression, so we return nothing.
6223 return clang_getNullCursor();
6224}
6225
6226CXFile clang_getIncludedFile(CXCursor cursor) {
6227 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006228 return nullptr;
6229
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006230 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006231 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006232}
6233
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006234unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6235 if (C.kind != CXCursor_ObjCPropertyDecl)
6236 return CXObjCPropertyAttr_noattr;
6237
6238 unsigned Result = CXObjCPropertyAttr_noattr;
6239 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6240 ObjCPropertyDecl::PropertyAttributeKind Attr =
6241 PD->getPropertyAttributesAsWritten();
6242
6243#define SET_CXOBJCPROP_ATTR(A) \
6244 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6245 Result |= CXObjCPropertyAttr_##A
6246 SET_CXOBJCPROP_ATTR(readonly);
6247 SET_CXOBJCPROP_ATTR(getter);
6248 SET_CXOBJCPROP_ATTR(assign);
6249 SET_CXOBJCPROP_ATTR(readwrite);
6250 SET_CXOBJCPROP_ATTR(retain);
6251 SET_CXOBJCPROP_ATTR(copy);
6252 SET_CXOBJCPROP_ATTR(nonatomic);
6253 SET_CXOBJCPROP_ATTR(setter);
6254 SET_CXOBJCPROP_ATTR(atomic);
6255 SET_CXOBJCPROP_ATTR(weak);
6256 SET_CXOBJCPROP_ATTR(strong);
6257 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6258#undef SET_CXOBJCPROP_ATTR
6259
6260 return Result;
6261}
6262
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006263unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6264 if (!clang_isDeclaration(C.kind))
6265 return CXObjCDeclQualifier_None;
6266
6267 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6268 const Decl *D = getCursorDecl(C);
6269 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6270 QT = MD->getObjCDeclQualifier();
6271 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6272 QT = PD->getObjCDeclQualifier();
6273 if (QT == Decl::OBJC_TQ_None)
6274 return CXObjCDeclQualifier_None;
6275
6276 unsigned Result = CXObjCDeclQualifier_None;
6277 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6278 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6279 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6280 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6281 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6282 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6283
6284 return Result;
6285}
6286
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006287unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6288 if (!clang_isDeclaration(C.kind))
6289 return 0;
6290
6291 const Decl *D = getCursorDecl(C);
6292 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6293 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6294 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6295 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6296
6297 return 0;
6298}
6299
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006300unsigned clang_Cursor_isVariadic(CXCursor C) {
6301 if (!clang_isDeclaration(C.kind))
6302 return 0;
6303
6304 const Decl *D = getCursorDecl(C);
6305 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6306 return FD->isVariadic();
6307 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6308 return MD->isVariadic();
6309
6310 return 0;
6311}
6312
Guy Benyei11169dd2012-12-18 14:30:41 +00006313CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6314 if (!clang_isDeclaration(C.kind))
6315 return clang_getNullRange();
6316
6317 const Decl *D = getCursorDecl(C);
6318 ASTContext &Context = getCursorContext(C);
6319 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6320 if (!RC)
6321 return clang_getNullRange();
6322
6323 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6324}
6325
6326CXString clang_Cursor_getRawCommentText(CXCursor C) {
6327 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006328 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006329
6330 const Decl *D = getCursorDecl(C);
6331 ASTContext &Context = getCursorContext(C);
6332 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6333 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6334 StringRef();
6335
6336 // Don't duplicate the string because RawText points directly into source
6337 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006338 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006339}
6340
6341CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6342 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006343 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006344
6345 const Decl *D = getCursorDecl(C);
6346 const ASTContext &Context = getCursorContext(C);
6347 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6348
6349 if (RC) {
6350 StringRef BriefText = RC->getBriefText(Context);
6351
6352 // Don't duplicate the string because RawComment ensures that this memory
6353 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006354 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006355 }
6356
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006357 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006358}
6359
Guy Benyei11169dd2012-12-18 14:30:41 +00006360CXModule clang_Cursor_getModule(CXCursor C) {
6361 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006362 if (const ImportDecl *ImportD =
6363 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006364 return ImportD->getImportedModule();
6365 }
6366
Craig Topper69186e72014-06-08 08:38:04 +00006367 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006368}
6369
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006370CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6371 if (isNotUsableTU(TU)) {
6372 LOG_BAD_TU(TU);
6373 return nullptr;
6374 }
6375 if (!File)
6376 return nullptr;
6377 FileEntry *FE = static_cast<FileEntry *>(File);
6378
6379 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6380 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6381 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6382
6383 if (Module *Mod = Header.getModule()) {
6384 if (Header.getRole() != ModuleMap::ExcludedHeader)
6385 return Mod;
6386 }
6387 return nullptr;
6388}
6389
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006390CXFile clang_Module_getASTFile(CXModule CXMod) {
6391 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006392 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006393 Module *Mod = static_cast<Module*>(CXMod);
6394 return const_cast<FileEntry *>(Mod->getASTFile());
6395}
6396
Guy Benyei11169dd2012-12-18 14:30:41 +00006397CXModule clang_Module_getParent(CXModule CXMod) {
6398 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006399 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006400 Module *Mod = static_cast<Module*>(CXMod);
6401 return Mod->Parent;
6402}
6403
6404CXString clang_Module_getName(CXModule CXMod) {
6405 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006406 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006407 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006408 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006409}
6410
6411CXString clang_Module_getFullName(CXModule CXMod) {
6412 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006413 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006415 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006416}
6417
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006418int clang_Module_isSystem(CXModule CXMod) {
6419 if (!CXMod)
6420 return 0;
6421 Module *Mod = static_cast<Module*>(CXMod);
6422 return Mod->IsSystem;
6423}
6424
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006425unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6426 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006427 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006428 LOG_BAD_TU(TU);
6429 return 0;
6430 }
6431 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006432 return 0;
6433 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006434 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6435 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6436 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006437}
6438
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006439CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6440 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006441 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006442 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006443 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006444 }
6445 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006446 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006447 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006448 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006449
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006450 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6451 if (Index < TopHeaders.size())
6452 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006453
Craig Topper69186e72014-06-08 08:38:04 +00006454 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006455}
6456
6457} // end: extern "C"
6458
6459//===----------------------------------------------------------------------===//
6460// C++ AST instrospection.
6461//===----------------------------------------------------------------------===//
6462
6463extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006464unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6465 if (!clang_isDeclaration(C.kind))
6466 return 0;
6467
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006468 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006469 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006470 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006471 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6472}
6473
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006474unsigned clang_CXXMethod_isConst(CXCursor C) {
6475 if (!clang_isDeclaration(C.kind))
6476 return 0;
6477
6478 const Decl *D = cxcursor::getCursorDecl(C);
6479 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006480 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006481 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6482}
6483
Guy Benyei11169dd2012-12-18 14:30:41 +00006484unsigned clang_CXXMethod_isStatic(CXCursor C) {
6485 if (!clang_isDeclaration(C.kind))
6486 return 0;
6487
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006488 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006489 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006490 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006491 return (Method && Method->isStatic()) ? 1 : 0;
6492}
6493
6494unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6495 if (!clang_isDeclaration(C.kind))
6496 return 0;
6497
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006498 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006499 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006500 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006501 return (Method && Method->isVirtual()) ? 1 : 0;
6502}
6503} // end: extern "C"
6504
6505//===----------------------------------------------------------------------===//
6506// Attribute introspection.
6507//===----------------------------------------------------------------------===//
6508
6509extern "C" {
6510CXType clang_getIBOutletCollectionType(CXCursor C) {
6511 if (C.kind != CXCursor_IBOutletCollectionAttr)
6512 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6513
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006514 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006515 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6516
6517 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6518}
6519} // end: extern "C"
6520
6521//===----------------------------------------------------------------------===//
6522// Inspecting memory usage.
6523//===----------------------------------------------------------------------===//
6524
6525typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6526
6527static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6528 enum CXTUResourceUsageKind k,
6529 unsigned long amount) {
6530 CXTUResourceUsageEntry entry = { k, amount };
6531 entries.push_back(entry);
6532}
6533
6534extern "C" {
6535
6536const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6537 const char *str = "";
6538 switch (kind) {
6539 case CXTUResourceUsage_AST:
6540 str = "ASTContext: expressions, declarations, and types";
6541 break;
6542 case CXTUResourceUsage_Identifiers:
6543 str = "ASTContext: identifiers";
6544 break;
6545 case CXTUResourceUsage_Selectors:
6546 str = "ASTContext: selectors";
6547 break;
6548 case CXTUResourceUsage_GlobalCompletionResults:
6549 str = "Code completion: cached global results";
6550 break;
6551 case CXTUResourceUsage_SourceManagerContentCache:
6552 str = "SourceManager: content cache allocator";
6553 break;
6554 case CXTUResourceUsage_AST_SideTables:
6555 str = "ASTContext: side tables";
6556 break;
6557 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6558 str = "SourceManager: malloc'ed memory buffers";
6559 break;
6560 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6561 str = "SourceManager: mmap'ed memory buffers";
6562 break;
6563 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6564 str = "ExternalASTSource: malloc'ed memory buffers";
6565 break;
6566 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6567 str = "ExternalASTSource: mmap'ed memory buffers";
6568 break;
6569 case CXTUResourceUsage_Preprocessor:
6570 str = "Preprocessor: malloc'ed memory";
6571 break;
6572 case CXTUResourceUsage_PreprocessingRecord:
6573 str = "Preprocessor: PreprocessingRecord";
6574 break;
6575 case CXTUResourceUsage_SourceManager_DataStructures:
6576 str = "SourceManager: data structures and tables";
6577 break;
6578 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6579 str = "Preprocessor: header search tables";
6580 break;
6581 }
6582 return str;
6583}
6584
6585CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006586 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006587 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006588 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006589 return usage;
6590 }
6591
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006592 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006593 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006594 ASTContext &astContext = astUnit->getASTContext();
6595
6596 // How much memory is used by AST nodes and types?
6597 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6598 (unsigned long) astContext.getASTAllocatedMemory());
6599
6600 // How much memory is used by identifiers?
6601 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6602 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6603
6604 // How much memory is used for selectors?
6605 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6606 (unsigned long) astContext.Selectors.getTotalMemory());
6607
6608 // How much memory is used by ASTContext's side tables?
6609 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6610 (unsigned long) astContext.getSideTableAllocatedMemory());
6611
6612 // How much memory is used for caching global code completion results?
6613 unsigned long completionBytes = 0;
6614 if (GlobalCodeCompletionAllocator *completionAllocator =
6615 astUnit->getCachedCompletionAllocator().getPtr()) {
6616 completionBytes = completionAllocator->getTotalMemory();
6617 }
6618 createCXTUResourceUsageEntry(*entries,
6619 CXTUResourceUsage_GlobalCompletionResults,
6620 completionBytes);
6621
6622 // How much memory is being used by SourceManager's content cache?
6623 createCXTUResourceUsageEntry(*entries,
6624 CXTUResourceUsage_SourceManagerContentCache,
6625 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6626
6627 // How much memory is being used by the MemoryBuffer's in SourceManager?
6628 const SourceManager::MemoryBufferSizes &srcBufs =
6629 astUnit->getSourceManager().getMemoryBufferSizes();
6630
6631 createCXTUResourceUsageEntry(*entries,
6632 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6633 (unsigned long) srcBufs.malloc_bytes);
6634 createCXTUResourceUsageEntry(*entries,
6635 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6636 (unsigned long) srcBufs.mmap_bytes);
6637 createCXTUResourceUsageEntry(*entries,
6638 CXTUResourceUsage_SourceManager_DataStructures,
6639 (unsigned long) astContext.getSourceManager()
6640 .getDataStructureSizes());
6641
6642 // How much memory is being used by the ExternalASTSource?
6643 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6644 const ExternalASTSource::MemoryBufferSizes &sizes =
6645 esrc->getMemoryBufferSizes();
6646
6647 createCXTUResourceUsageEntry(*entries,
6648 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6649 (unsigned long) sizes.malloc_bytes);
6650 createCXTUResourceUsageEntry(*entries,
6651 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6652 (unsigned long) sizes.mmap_bytes);
6653 }
6654
6655 // How much memory is being used by the Preprocessor?
6656 Preprocessor &pp = astUnit->getPreprocessor();
6657 createCXTUResourceUsageEntry(*entries,
6658 CXTUResourceUsage_Preprocessor,
6659 pp.getTotalMemory());
6660
6661 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6662 createCXTUResourceUsageEntry(*entries,
6663 CXTUResourceUsage_PreprocessingRecord,
6664 pRec->getTotalMemory());
6665 }
6666
6667 createCXTUResourceUsageEntry(*entries,
6668 CXTUResourceUsage_Preprocessor_HeaderSearch,
6669 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006670
Guy Benyei11169dd2012-12-18 14:30:41 +00006671 CXTUResourceUsage usage = { (void*) entries.get(),
6672 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006673 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006674 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006675 return usage;
6676}
6677
6678void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6679 if (usage.data)
6680 delete (MemUsageEntries*) usage.data;
6681}
6682
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006683CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6684 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006685 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006686 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006687
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006688 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006689 LOG_BAD_TU(TU);
6690 return skipped;
6691 }
6692
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006693 if (!file)
6694 return skipped;
6695
6696 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6697 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6698 if (!ppRec)
6699 return skipped;
6700
6701 ASTContext &Ctx = astUnit->getASTContext();
6702 SourceManager &sm = Ctx.getSourceManager();
6703 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6704 FileID wantedFileID = sm.translateFile(fileEntry);
6705
6706 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6707 std::vector<SourceRange> wantedRanges;
6708 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6709 i != ei; ++i) {
6710 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6711 wantedRanges.push_back(*i);
6712 }
6713
6714 skipped->count = wantedRanges.size();
6715 skipped->ranges = new CXSourceRange[skipped->count];
6716 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6717 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6718
6719 return skipped;
6720}
6721
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006722void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6723 if (ranges) {
6724 delete[] ranges->ranges;
6725 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006726 }
6727}
6728
Guy Benyei11169dd2012-12-18 14:30:41 +00006729} // end extern "C"
6730
6731void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6732 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6733 for (unsigned I = 0; I != Usage.numEntries; ++I)
6734 fprintf(stderr, " %s: %lu\n",
6735 clang_getTUResourceUsageName(Usage.entries[I].kind),
6736 Usage.entries[I].amount);
6737
6738 clang_disposeCXTUResourceUsage(Usage);
6739}
6740
6741//===----------------------------------------------------------------------===//
6742// Misc. utility functions.
6743//===----------------------------------------------------------------------===//
6744
6745/// Default to using an 8 MB stack size on "safety" threads.
6746static unsigned SafetyStackThreadSize = 8 << 20;
6747
6748namespace clang {
6749
6750bool RunSafely(llvm::CrashRecoveryContext &CRC,
6751 void (*Fn)(void*), void *UserData,
6752 unsigned Size) {
6753 if (!Size)
6754 Size = GetSafetyThreadStackSize();
6755 if (Size)
6756 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6757 return CRC.RunSafely(Fn, UserData);
6758}
6759
6760unsigned GetSafetyThreadStackSize() {
6761 return SafetyStackThreadSize;
6762}
6763
6764void SetSafetyThreadStackSize(unsigned Value) {
6765 SafetyStackThreadSize = Value;
6766}
6767
6768}
6769
6770void clang::setThreadBackgroundPriority() {
6771 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6772 return;
6773
6774 // FIXME: Move to llvm/Support and make it cross-platform.
6775#ifdef __APPLE__
6776 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6777#endif
6778}
6779
6780void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6781 if (!Unit)
6782 return;
6783
6784 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6785 DEnd = Unit->stored_diag_end();
6786 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006787 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006788 CXString Msg = clang_formatDiagnostic(&Diag,
6789 clang_defaultDiagnosticDisplayOptions());
6790 fprintf(stderr, "%s\n", clang_getCString(Msg));
6791 clang_disposeString(Msg);
6792 }
6793#ifdef LLVM_ON_WIN32
6794 // On Windows, force a flush, since there may be multiple copies of
6795 // stderr and stdout in the file system, all with different buffers
6796 // but writing to the same device.
6797 fflush(stderr);
6798#endif
6799}
6800
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006801MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6802 SourceLocation MacroDefLoc,
6803 CXTranslationUnit TU){
6804 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006805 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006806 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006807 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006808
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006809 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006810 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006811 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006812 if (MD) {
6813 for (MacroDirective::DefInfo
6814 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6815 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6816 return Def.getMacroInfo();
6817 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006818 }
6819
Craig Topper69186e72014-06-08 08:38:04 +00006820 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006821}
6822
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006823const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6824 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006825 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006826 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006827 const IdentifierInfo *II = MacroDef->getName();
6828 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006829 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006830
6831 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6832}
6833
6834MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6835 const Token &Tok,
6836 CXTranslationUnit TU) {
6837 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006838 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006839 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006840 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006841
6842 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006843 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006844 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6845 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006846 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006847
6848 // Check that the token is inside the definition and not its argument list.
6849 SourceManager &SM = Unit->getSourceManager();
6850 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006851 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006852 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006853 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006854
6855 Preprocessor &PP = Unit->getPreprocessor();
6856 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6857 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006858 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006859
Alp Toker2d57cea2014-05-17 04:53:25 +00006860 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006861 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006862 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006863
6864 // Check that the identifier is not one of the macro arguments.
6865 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006866 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006867
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006868 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6869 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006870 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006871
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006872 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006873}
6874
6875MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6876 SourceLocation Loc,
6877 CXTranslationUnit TU) {
6878 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006879 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006880
6881 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006882 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006883 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006884 Preprocessor &PP = Unit->getPreprocessor();
6885 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006886 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006887 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6888 Token Tok;
6889 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006890 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006891
6892 return checkForMacroInMacroDefinition(MI, Tok, TU);
6893}
6894
Guy Benyei11169dd2012-12-18 14:30:41 +00006895extern "C" {
6896
6897CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006898 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006899}
6900
6901} // end: extern "C"
6902
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006903Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6904 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006905 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006906 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006907 if (Unit->isMainFileAST())
6908 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006909 return *this;
6910 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006911 } else {
6912 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006913 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006914 return *this;
6915}
6916
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006917Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6918 *this << FE->getName();
6919 return *this;
6920}
6921
6922Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6923 CXString cursorName = clang_getCursorDisplayName(cursor);
6924 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6925 clang_disposeString(cursorName);
6926 return *this;
6927}
6928
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006929Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6930 CXFile File;
6931 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006932 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006933 CXString FileName = clang_getFileName(File);
6934 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6935 clang_disposeString(FileName);
6936 return *this;
6937}
6938
6939Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6940 CXSourceLocation BLoc = clang_getRangeStart(range);
6941 CXSourceLocation ELoc = clang_getRangeEnd(range);
6942
6943 CXFile BFile;
6944 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006945 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006946
6947 CXFile EFile;
6948 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006949 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006950
6951 CXString BFileName = clang_getFileName(BFile);
6952 if (BFile == EFile) {
6953 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6954 BLine, BColumn, ELine, EColumn);
6955 } else {
6956 CXString EFileName = clang_getFileName(EFile);
6957 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6958 BLine, BColumn)
6959 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6960 ELine, EColumn);
6961 clang_disposeString(EFileName);
6962 }
6963 clang_disposeString(BFileName);
6964 return *this;
6965}
6966
6967Logger &cxindex::Logger::operator<<(CXString Str) {
6968 *this << clang_getCString(Str);
6969 return *this;
6970}
6971
6972Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6973 LogOS << Fmt;
6974 return *this;
6975}
6976
6977cxindex::Logger::~Logger() {
6978 LogOS.flush();
6979
NAKAMURA Takumi8068b6a2014-06-24 13:50:01 +00006980 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006981
6982 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6983
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006984 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006985 OS << "[libclang:" << Name << ':';
6986
6987 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00006988#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006989 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6990 OS << tid << ':';
6991#endif
6992
6993 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6994 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6995 OS << Msg.str() << '\n';
6996
6997 if (Trace) {
6998 llvm::sys::PrintStackTrace(stderr);
6999 OS << "--------------------------------------------------\n";
7000 }
7001}