blob: 1d6258b0cbf441785c4836ba5009d945b53e4f07 [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"
Chandler Carruth37ad2582014-06-27 15:14:39 +000046#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
Alp Toker1d257e12014-06-04 03:28:55 +000056#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000057#include <pthread.h>
58#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000059
60using namespace clang;
61using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000062using namespace clang::cxtu;
63using namespace clang::cxindex;
64
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000065CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
66 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000067 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000068 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000069 CXTranslationUnit D = new CXTranslationUnitImpl();
70 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000072 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000073 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000074 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000075 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000076 return D;
77}
78
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000079bool cxtu::isASTReadError(ASTUnit *AU) {
80 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
81 DEnd = AU->stored_diag_end();
82 D != DEnd; ++D) {
83 if (D->getLevel() >= DiagnosticsEngine::Error &&
84 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
85 diag::DiagCat_AST_Deserialization_Issue)
86 return true;
87 }
88 return false;
89}
90
Guy Benyei11169dd2012-12-18 14:30:41 +000091cxtu::CXTUOwner::~CXTUOwner() {
92 if (TU)
93 clang_disposeTranslationUnit(TU);
94}
95
96/// \brief Compare two source ranges to determine their relative position in
97/// the translation unit.
98static RangeComparisonResult RangeCompare(SourceManager &SM,
99 SourceRange R1,
100 SourceRange R2) {
101 assert(R1.isValid() && "First range is invalid?");
102 assert(R2.isValid() && "Second range is invalid?");
103 if (R1.getEnd() != R2.getBegin() &&
104 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
105 return RangeBefore;
106 if (R2.getEnd() != R1.getBegin() &&
107 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Determine if a source location falls within, before, or after a
113/// a given source range.
114static RangeComparisonResult LocationCompare(SourceManager &SM,
115 SourceLocation L, SourceRange R) {
116 assert(R.isValid() && "First range is invalid?");
117 assert(L.isValid() && "Second range is invalid?");
118 if (L == R.getBegin() || L == R.getEnd())
119 return RangeOverlap;
120 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
121 return RangeBefore;
122 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
123 return RangeAfter;
124 return RangeOverlap;
125}
126
127/// \brief Translate a Clang source range into a CIndex source range.
128///
129/// Clang internally represents ranges where the end location points to the
130/// start of the token at the end. However, for external clients it is more
131/// useful to have a CXSourceRange be a proper half-open interval. This routine
132/// does the appropriate translation.
133CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
134 const LangOptions &LangOpts,
135 const CharSourceRange &R) {
136 // We want the last character in this location, so we will adjust the
137 // location accordingly.
138 SourceLocation EndLoc = R.getEnd();
139 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
140 EndLoc = SM.getExpansionRange(EndLoc).second;
141 if (R.isTokenRange() && !EndLoc.isInvalid()) {
142 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
143 SM, LangOpts);
144 EndLoc = EndLoc.getLocWithOffset(Length);
145 }
146
Bill Wendlingeade3622013-01-23 08:25:41 +0000147 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000148 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000149 R.getBegin().getRawEncoding(),
150 EndLoc.getRawEncoding()
151 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000152 return Result;
153}
154
155//===----------------------------------------------------------------------===//
156// Cursor visitor.
157//===----------------------------------------------------------------------===//
158
159static SourceRange getRawCursorExtent(CXCursor C);
160static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
161
162
163RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
164 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
165}
166
167/// \brief Visit the given cursor and, if requested by the visitor,
168/// its children.
169///
170/// \param Cursor the cursor to visit.
171///
172/// \param CheckedRegionOfInterest if true, then the caller already checked
173/// that this cursor is within the region of interest.
174///
175/// \returns true if the visitation should be aborted, false if it
176/// should continue.
177bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
178 if (clang_isInvalid(Cursor.kind))
179 return false;
180
181 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000182 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000183 if (!D) {
184 assert(0 && "Invalid declaration cursor");
185 return true; // abort.
186 }
187
188 // Ignore implicit declarations, unless it's an objc method because
189 // currently we should report implicit methods for properties when indexing.
190 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
191 return false;
192 }
193
194 // If we have a range of interest, and this cursor doesn't intersect with it,
195 // we're done.
196 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
197 SourceRange Range = getRawCursorExtent(Cursor);
198 if (Range.isInvalid() || CompareRegionOfInterest(Range))
199 return false;
200 }
201
202 switch (Visitor(Cursor, Parent, ClientData)) {
203 case CXChildVisit_Break:
204 return true;
205
206 case CXChildVisit_Continue:
207 return false;
208
209 case CXChildVisit_Recurse: {
210 bool ret = VisitChildren(Cursor);
211 if (PostChildrenVisitor)
212 if (PostChildrenVisitor(Cursor, ClientData))
213 return true;
214 return ret;
215 }
216 }
217
218 llvm_unreachable("Invalid CXChildVisitResult!");
219}
220
221static bool visitPreprocessedEntitiesInRange(SourceRange R,
222 PreprocessingRecord &PPRec,
223 CursorVisitor &Visitor) {
224 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
225 FileID FID;
226
227 if (!Visitor.shouldVisitIncludedEntities()) {
228 // If the begin/end of the range lie in the same FileID, do the optimization
229 // where we skip preprocessed entities that do not come from the same FileID.
230 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
231 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
232 FID = FileID();
233 }
234
235 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
236 Entities = PPRec.getPreprocessedEntitiesInRange(R);
237 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
238 PPRec, FID);
239}
240
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000241bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000243 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000244
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000245 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 SourceManager &SM = Unit->getSourceManager();
247
248 std::pair<FileID, unsigned>
249 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
250 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
251
252 if (End.first != Begin.first) {
253 // If the end does not reside in the same file, try to recover by
254 // picking the end of the file of begin location.
255 End.first = Begin.first;
256 End.second = SM.getFileIDSize(Begin.first);
257 }
258
259 assert(Begin.first == End.first);
260 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 FileID File = Begin.first;
264 unsigned Offset = Begin.second;
265 unsigned Length = End.second - Begin.second;
266
267 if (!VisitDeclsOnly && !VisitPreprocessorLast)
268 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000271 if (visitDeclsFromFileRegion(File, Offset, Length))
272 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000273
274 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 return visitPreprocessedEntitiesInRegion();
276
277 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000278}
279
280static bool isInLexicalContext(Decl *D, DeclContext *DC) {
281 if (!DC)
282 return false;
283
284 for (DeclContext *DeclDC = D->getLexicalDeclContext();
285 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
286 if (DeclDC == DC)
287 return true;
288 }
289 return false;
290}
291
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000292bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000293 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000294 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000295 SourceManager &SM = Unit->getSourceManager();
296 SourceRange Range = RegionOfInterest;
297
298 SmallVector<Decl *, 16> Decls;
299 Unit->findFileRegionDecls(File, Offset, Length, Decls);
300
301 // If we didn't find any file level decls for the file, try looking at the
302 // file that it was included from.
303 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
304 bool Invalid = false;
305 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
306 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000307 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000308
309 SourceLocation Outer;
310 if (SLEntry.isFile())
311 Outer = SLEntry.getFile().getIncludeLoc();
312 else
313 Outer = SLEntry.getExpansion().getExpansionLocStart();
314 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000317 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000318 Length = 0;
319 Unit->findFileRegionDecls(File, Offset, Length, Decls);
320 }
321
322 assert(!Decls.empty());
323
324 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000325 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000326 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
327 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000328 Decl *D = *DIt;
329 if (D->getSourceRange().isInvalid())
330 continue;
331
332 if (isInLexicalContext(D, CurDC))
333 continue;
334
335 CurDC = dyn_cast<DeclContext>(D);
336
337 if (TagDecl *TD = dyn_cast<TagDecl>(D))
338 if (!TD->isFreeStanding())
339 continue;
340
341 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
342 if (CompRes == RangeBefore)
343 continue;
344 if (CompRes == RangeAfter)
345 break;
346
347 assert(CompRes == RangeOverlap);
348 VisitedAtLeastOnce = true;
349
350 if (isa<ObjCContainerDecl>(D)) {
351 FileDI_current = &DIt;
352 FileDE_current = DE;
353 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000354 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000355 }
356
357 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000358 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363
364 // No Decls overlapped with the range. Move up the lexical context until there
365 // is a context that contains the range or we reach the translation unit
366 // level.
367 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
368 : (*(DIt-1))->getLexicalDeclContext();
369
370 while (DC && !DC->isTranslationUnit()) {
371 Decl *D = cast<Decl>(DC);
372 SourceRange CurDeclRange = D->getSourceRange();
373 if (CurDeclRange.isInvalid())
374 break;
375
376 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000379 }
380
381 DC = D->getLexicalDeclContext();
382 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000383
384 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000385}
386
387bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
388 if (!AU->getPreprocessor().getPreprocessingRecord())
389 return false;
390
391 PreprocessingRecord &PPRec
392 = *AU->getPreprocessor().getPreprocessingRecord();
393 SourceManager &SM = AU->getSourceManager();
394
395 if (RegionOfInterest.isValid()) {
396 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
397 SourceLocation B = MappedRange.getBegin();
398 SourceLocation E = MappedRange.getEnd();
399
400 if (AU->isInPreambleFileID(B)) {
401 if (SM.isLoadedSourceLocation(E))
402 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
403 PPRec, *this);
404
405 // Beginning of range lies in the preamble but it also extends beyond
406 // it into the main file. Split the range into 2 parts, one covering
407 // the preamble and another covering the main file. This allows subsequent
408 // calls to visitPreprocessedEntitiesInRange to accept a source range that
409 // lies in the same FileID, allowing it to skip preprocessed entities that
410 // do not come from the same FileID.
411 bool breaked =
412 visitPreprocessedEntitiesInRange(
413 SourceRange(B, AU->getEndOfPreambleFileID()),
414 PPRec, *this);
415 if (breaked) return true;
416 return visitPreprocessedEntitiesInRange(
417 SourceRange(AU->getStartOfMainFileID(), E),
418 PPRec, *this);
419 }
420
421 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
422 }
423
424 bool OnlyLocalDecls
425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls)
428 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
429 PPRec);
430
431 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
432}
433
434template<typename InputIterator>
435bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
436 InputIterator Last,
437 PreprocessingRecord &PPRec,
438 FileID FID) {
439 for (; First != Last; ++First) {
440 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
441 continue;
442
443 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000444 if (!PPE)
445 continue;
446
Guy Benyei11169dd2012-12-18 14:30:41 +0000447 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
448 if (Visit(MakeMacroExpansionCursor(ME, TU)))
449 return true;
450
451 continue;
452 }
453
454 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
455 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
462 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
463 return true;
464
465 continue;
466 }
467 }
468
469 return false;
470}
471
472/// \brief Visit the children of the given cursor.
473///
474/// \returns true if the visitation should be aborted, false if it
475/// should continue.
476bool CursorVisitor::VisitChildren(CXCursor Cursor) {
477 if (clang_isReference(Cursor.kind) &&
478 Cursor.kind != CXCursor_CXXBaseSpecifier) {
479 // By definition, references have no children.
480 return false;
481 }
482
483 // Set the Parent field to Cursor, then back to its old value once we're
484 // done.
485 SetParentRAII SetParent(Parent, StmtParent, Cursor);
486
487 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000488 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000489 if (!D)
490 return false;
491
492 return VisitAttributes(D) || Visit(D);
493 }
494
495 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000496 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 return Visit(S);
498
499 return false;
500 }
501
502 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(E);
505
506 return false;
507 }
508
509 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000510 CXTranslationUnit TU = getCursorTU(Cursor);
511 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000512
513 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
514 for (unsigned I = 0; I != 2; ++I) {
515 if (VisitOrder[I]) {
516 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
517 RegionOfInterest.isInvalid()) {
518 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
519 TLEnd = CXXUnit->top_level_end();
520 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000521 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000522 return true;
523 }
524 } else if (VisitDeclContext(
525 CXXUnit->getASTContext().getTranslationUnitDecl()))
526 return true;
527 continue;
528 }
529
530 // Walk the preprocessing record.
531 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
532 visitPreprocessedEntitiesInRegion();
533 }
534
535 return false;
536 }
537
538 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000539 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000540 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
541 return Visit(BaseTSInfo->getTypeLoc());
542 }
543 }
544 }
545
546 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000547 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000549 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000550 return Visit(cxcursor::MakeCursorObjCClassRef(
551 ObjT->getInterface(),
552 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 }
554
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000555 // If pointing inside a macro definition, check if the token is an identifier
556 // that was ever defined as a macro. In such a case, create a "pseudo" macro
557 // expansion cursor for that token.
558 SourceLocation BeginLoc = RegionOfInterest.getBegin();
559 if (Cursor.kind == CXCursor_MacroDefinition &&
560 BeginLoc == RegionOfInterest.getEnd()) {
561 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000562 const MacroInfo *MI =
563 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 if (MacroDefinition *MacroDef =
565 checkForMacroInMacroDefinition(MI, Loc, TU))
566 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
567 }
568
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 // Nothing to visit at the moment.
570 return false;
571}
572
573bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
574 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
575 if (Visit(TSInfo->getTypeLoc()))
576 return true;
577
578 if (Stmt *Body = B->getBody())
579 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
580
581 return false;
582}
583
Ted Kremenek03325582013-02-21 01:29:01 +0000584Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000585 if (RegionOfInterest.isValid()) {
586 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
587 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000588 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 switch (CompareRegionOfInterest(Range)) {
591 case RangeBefore:
592 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 case RangeAfter:
596 // This declaration comes after the region of interest; we're done.
597 return false;
598
599 case RangeOverlap:
600 // This declaration overlaps the region of interest; visit it.
601 break;
602 }
603 }
604 return true;
605}
606
607bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
608 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
609
610 // FIXME: Eventually remove. This part of a hack to support proper
611 // iteration over all Decls contained lexically within an ObjC container.
612 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
613 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
614
615 for ( ; I != E; ++I) {
616 Decl *D = *I;
617 if (D->getLexicalDeclContext() != DC)
618 continue;
619 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
620
621 // Ignore synthesized ivars here, otherwise if we have something like:
622 // @synthesize prop = _prop;
623 // and '_prop' is not declared, we will encounter a '_prop' ivar before
624 // encountering the 'prop' synthesize declaration and we will think that
625 // we passed the region-of-interest.
626 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
627 if (ivarD->getSynthesize())
628 continue;
629 }
630
631 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
632 // declarations is a mismatch with the compiler semantics.
633 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
634 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
635 if (!ID->isThisDeclarationADefinition())
636 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
637
638 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
639 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
640 if (!PD->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
642 }
643
Ted Kremenek03325582013-02-21 01:29:01 +0000644 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000645 if (!V.hasValue())
646 continue;
647 if (!V.getValue())
648 return false;
649 if (Visit(Cursor, true))
650 return true;
651 }
652 return false;
653}
654
655bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
656 llvm_unreachable("Translation units are visited directly by Visit()");
657}
658
659bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
660 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
661 return Visit(TSInfo->getTypeLoc());
662
663 return false;
664}
665
666bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTagDecl(TagDecl *D) {
674 return VisitDeclContext(D);
675}
676
677bool CursorVisitor::VisitClassTemplateSpecializationDecl(
678 ClassTemplateSpecializationDecl *D) {
679 bool ShouldVisitBody = false;
680 switch (D->getSpecializationKind()) {
681 case TSK_Undeclared:
682 case TSK_ImplicitInstantiation:
683 // Nothing to visit
684 return false;
685
686 case TSK_ExplicitInstantiationDeclaration:
687 case TSK_ExplicitInstantiationDefinition:
688 break;
689
690 case TSK_ExplicitSpecialization:
691 ShouldVisitBody = true;
692 break;
693 }
694
695 // Visit the template arguments used in the specialization.
696 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
697 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000698 if (TemplateSpecializationTypeLoc TSTLoc =
699 TL.getAs<TemplateSpecializationTypeLoc>()) {
700 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000702 return true;
703 }
704 }
705
706 if (ShouldVisitBody && VisitCXXRecordDecl(D))
707 return true;
708
709 return false;
710}
711
712bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
713 ClassTemplatePartialSpecializationDecl *D) {
714 // FIXME: Visit the "outer" template parameter lists on the TagDecl
715 // before visiting these template parameters.
716 if (VisitTemplateParameters(D->getTemplateParameters()))
717 return true;
718
719 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000720 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
721 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
722 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000723 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
724 return true;
725
726 return VisitCXXRecordDecl(D);
727}
728
729bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
730 // Visit the default argument.
731 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
732 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
733 if (Visit(DefArg->getTypeLoc()))
734 return true;
735
736 return false;
737}
738
739bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
740 if (Expr *Init = D->getInitExpr())
741 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
742 return false;
743}
744
745bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000746 unsigned NumParamList = DD->getNumTemplateParameterLists();
747 for (unsigned i = 0; i < NumParamList; i++) {
748 TemplateParameterList* Params = DD->getTemplateParameterList(i);
749 if (VisitTemplateParameters(Params))
750 return true;
751 }
752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
754 if (Visit(TSInfo->getTypeLoc()))
755 return true;
756
757 // Visit the nested-name-specifier, if present.
758 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
759 if (VisitNestedNameSpecifierLoc(QualifierLoc))
760 return true;
761
762 return false;
763}
764
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000765/// \brief Compare two base or member initializers based on their source order.
766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
769}
770
Guy Benyei11169dd2012-12-18 14:30:41 +0000771bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000772 unsigned NumParamList = ND->getNumTemplateParameterLists();
773 for (unsigned i = 0; i < NumParamList; i++) {
774 TemplateParameterList* Params = ND->getTemplateParameterList(i);
775 if (VisitTemplateParameters(Params))
776 return true;
777 }
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
780 // Visit the function declaration's syntactic components in the order
781 // written. This requires a bit of work.
782 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000783 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000784
785 // If we have a function declared directly (without the use of a typedef),
786 // visit just the return type. Otherwise, just visit the function's type
787 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000788 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 (!FTL && Visit(TL)))
790 return true;
791
792 // Visit the nested-name-specifier, if present.
793 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
794 if (VisitNestedNameSpecifierLoc(QualifierLoc))
795 return true;
796
797 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000798 if (!isa<CXXDestructorDecl>(ND))
799 if (VisitDeclarationNameInfo(ND->getNameInfo()))
800 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000801
802 // FIXME: Visit explicitly-specified template arguments!
803
804 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000805 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000806 return true;
807
Bill Wendling44426052012-12-20 19:22:21 +0000808 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000809 }
810
811 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
812 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
813 // Find the initializers that were written in the source.
814 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000815 for (auto *I : Constructor->inits()) {
816 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 continue;
818
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000820 }
821
822 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000823 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
824 &CompareCXXCtorInitializers);
825
Guy Benyei11169dd2012-12-18 14:30:41 +0000826 // Visit the initializers in source order
827 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
828 CXXCtorInitializer *Init = WrittenInits[I];
829 if (Init->isAnyMemberInitializer()) {
830 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
831 Init->getMemberLocation(), TU)))
832 return true;
833 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
834 if (Visit(TInfo->getTypeLoc()))
835 return true;
836 }
837
838 // Visit the initializer value.
839 if (Expr *Initializer = Init->getInit())
840 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
841 return true;
842 }
843 }
844
845 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
846 return true;
847 }
848
849 return false;
850}
851
852bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
853 if (VisitDeclaratorDecl(D))
854 return true;
855
856 if (Expr *BitWidth = D->getBitWidth())
857 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
858
859 return false;
860}
861
862bool CursorVisitor::VisitVarDecl(VarDecl *D) {
863 if (VisitDeclaratorDecl(D))
864 return true;
865
866 if (Expr *Init = D->getInit())
867 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
868
869 return false;
870}
871
872bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
873 if (VisitDeclaratorDecl(D))
874 return true;
875
876 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
877 if (Expr *DefArg = D->getDefaultArgument())
878 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
879
880 return false;
881}
882
883bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
884 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
885 // before visiting these template parameters.
886 if (VisitTemplateParameters(D->getTemplateParameters()))
887 return true;
888
889 return VisitFunctionDecl(D->getTemplatedDecl());
890}
891
892bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
893 // FIXME: Visit the "outer" template parameter lists on the TagDecl
894 // before visiting these template parameters.
895 if (VisitTemplateParameters(D->getTemplateParameters()))
896 return true;
897
898 return VisitCXXRecordDecl(D->getTemplatedDecl());
899}
900
901bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
906 VisitTemplateArgumentLoc(D->getDefaultArgument()))
907 return true;
908
909 return false;
910}
911
912bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000913 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000914 if (Visit(TSInfo->getTypeLoc()))
915 return true;
916
Aaron Ballman43b68be2014-03-07 17:50:17 +0000917 for (const auto *P : ND->params()) {
918 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000919 return true;
920 }
921
922 if (ND->isThisDeclarationADefinition() &&
923 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
924 return true;
925
926 return false;
927}
928
929template <typename DeclIt>
930static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
931 SourceManager &SM, SourceLocation EndLoc,
932 SmallVectorImpl<Decl *> &Decls) {
933 DeclIt next = *DI_current;
934 while (++next != DE_current) {
935 Decl *D_next = *next;
936 if (!D_next)
937 break;
938 SourceLocation L = D_next->getLocStart();
939 if (!L.isValid())
940 break;
941 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
942 *DI_current = next;
943 Decls.push_back(D_next);
944 continue;
945 }
946 break;
947 }
948}
949
Guy Benyei11169dd2012-12-18 14:30:41 +0000950bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
951 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
952 // an @implementation can lexically contain Decls that are not properly
953 // nested in the AST. When we identify such cases, we need to retrofit
954 // this nesting here.
955 if (!DI_current && !FileDI_current)
956 return VisitDeclContext(D);
957
958 // Scan the Decls that immediately come after the container
959 // in the current DeclContext. If any fall within the
960 // container's lexical region, stash them into a vector
961 // for later processing.
962 SmallVector<Decl *, 24> DeclsInContainer;
963 SourceLocation EndLoc = D->getSourceRange().getEnd();
964 SourceManager &SM = AU->getSourceManager();
965 if (EndLoc.isValid()) {
966 if (DI_current) {
967 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
968 DeclsInContainer);
969 } else {
970 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
971 DeclsInContainer);
972 }
973 }
974
975 // The common case.
976 if (DeclsInContainer.empty())
977 return VisitDeclContext(D);
978
979 // Get all the Decls in the DeclContext, and sort them with the
980 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000981 for (auto *SubDecl : D->decls()) {
982 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
983 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000984 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000986 }
987
988 // Now sort the Decls so that they appear in lexical order.
989 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000990 [&SM](Decl *A, Decl *B) {
991 SourceLocation L_A = A->getLocStart();
992 SourceLocation L_B = B->getLocStart();
993 assert(L_A.isValid() && L_B.isValid());
994 return SM.isBeforeInTranslationUnit(L_A, L_B);
995 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000996
997 // Now visit the decls.
998 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
999 E = DeclsInContainer.end(); I != E; ++I) {
1000 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001001 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001002 if (!V.hasValue())
1003 continue;
1004 if (!V.getValue())
1005 return false;
1006 if (Visit(Cursor, true))
1007 return true;
1008 }
1009 return false;
1010}
1011
1012bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1013 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1014 TU)))
1015 return true;
1016
1017 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1018 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1019 E = ND->protocol_end(); I != E; ++I, ++PL)
1020 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1021 return true;
1022
1023 return VisitObjCContainerDecl(ND);
1024}
1025
1026bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1027 if (!PID->isThisDeclarationADefinition())
1028 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1029
1030 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1031 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1032 E = PID->protocol_end(); I != E; ++I, ++PL)
1033 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1034 return true;
1035
1036 return VisitObjCContainerDecl(PID);
1037}
1038
1039bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1040 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1041 return true;
1042
1043 // FIXME: This implements a workaround with @property declarations also being
1044 // installed in the DeclContext for the @interface. Eventually this code
1045 // should be removed.
1046 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1047 if (!CDecl || !CDecl->IsClassExtension())
1048 return false;
1049
1050 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1051 if (!ID)
1052 return false;
1053
1054 IdentifierInfo *PropertyId = PD->getIdentifier();
1055 ObjCPropertyDecl *prevDecl =
1056 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1057
1058 if (!prevDecl)
1059 return false;
1060
1061 // Visit synthesized methods since they will be skipped when visiting
1062 // the @interface.
1063 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1064 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1065 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1066 return true;
1067
1068 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1069 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1070 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1071 return true;
1072
1073 return false;
1074}
1075
1076bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1077 if (!D->isThisDeclarationADefinition()) {
1078 // Forward declaration is treated like a reference.
1079 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1080 }
1081
1082 // Issue callbacks for super class.
1083 if (D->getSuperClass() &&
1084 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1085 D->getSuperClassLoc(),
1086 TU)))
1087 return true;
1088
1089 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1090 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1091 E = D->protocol_end(); I != E; ++I, ++PL)
1092 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1093 return true;
1094
1095 return VisitObjCContainerDecl(D);
1096}
1097
1098bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1103 // 'ID' could be null when dealing with invalid code.
1104 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1105 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1106 return true;
1107
1108 return VisitObjCImplDecl(D);
1109}
1110
1111bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1112#if 0
1113 // Issue callbacks for super class.
1114 // FIXME: No source location information!
1115 if (D->getSuperClass() &&
1116 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1117 D->getSuperClassLoc(),
1118 TU)))
1119 return true;
1120#endif
1121
1122 return VisitObjCImplDecl(D);
1123}
1124
1125bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1126 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1127 if (PD->isIvarNameSpecified())
1128 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1129
1130 return false;
1131}
1132
1133bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1134 return VisitDeclContext(D);
1135}
1136
1137bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1138 // Visit nested-name-specifier.
1139 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1140 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1141 return true;
1142
1143 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1144 D->getTargetNameLoc(), TU));
1145}
1146
1147bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1148 // Visit nested-name-specifier.
1149 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1150 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1151 return true;
1152 }
1153
1154 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1155 return true;
1156
1157 return VisitDeclarationNameInfo(D->getNameInfo());
1158}
1159
1160bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1161 // Visit nested-name-specifier.
1162 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1163 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1164 return true;
1165
1166 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1167 D->getIdentLocation(), TU));
1168}
1169
1170bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1171 // Visit nested-name-specifier.
1172 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1173 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1174 return true;
1175 }
1176
1177 return VisitDeclarationNameInfo(D->getNameInfo());
1178}
1179
1180bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1181 UnresolvedUsingTypenameDecl *D) {
1182 // Visit nested-name-specifier.
1183 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1185 return true;
1186
1187 return false;
1188}
1189
1190bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1191 switch (Name.getName().getNameKind()) {
1192 case clang::DeclarationName::Identifier:
1193 case clang::DeclarationName::CXXLiteralOperatorName:
1194 case clang::DeclarationName::CXXOperatorName:
1195 case clang::DeclarationName::CXXUsingDirective:
1196 return false;
1197
1198 case clang::DeclarationName::CXXConstructorName:
1199 case clang::DeclarationName::CXXDestructorName:
1200 case clang::DeclarationName::CXXConversionFunctionName:
1201 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1202 return Visit(TSInfo->getTypeLoc());
1203 return false;
1204
1205 case clang::DeclarationName::ObjCZeroArgSelector:
1206 case clang::DeclarationName::ObjCOneArgSelector:
1207 case clang::DeclarationName::ObjCMultiArgSelector:
1208 // FIXME: Per-identifier location info?
1209 return false;
1210 }
1211
1212 llvm_unreachable("Invalid DeclarationName::Kind!");
1213}
1214
1215bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1216 SourceRange Range) {
1217 // FIXME: This whole routine is a hack to work around the lack of proper
1218 // source information in nested-name-specifiers (PR5791). Since we do have
1219 // a beginning source location, we can visit the first component of the
1220 // nested-name-specifier, if it's a single-token component.
1221 if (!NNS)
1222 return false;
1223
1224 // Get the first component in the nested-name-specifier.
1225 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1226 NNS = Prefix;
1227
1228 switch (NNS->getKind()) {
1229 case NestedNameSpecifier::Namespace:
1230 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1231 TU));
1232
1233 case NestedNameSpecifier::NamespaceAlias:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1235 Range.getBegin(), TU));
1236
1237 case NestedNameSpecifier::TypeSpec: {
1238 // If the type has a form where we know that the beginning of the source
1239 // range matches up with a reference cursor. Visit the appropriate reference
1240 // cursor.
1241 const Type *T = NNS->getAsType();
1242 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1243 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1244 if (const TagType *Tag = dyn_cast<TagType>(T))
1245 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1246 if (const TemplateSpecializationType *TST
1247 = dyn_cast<TemplateSpecializationType>(T))
1248 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1249 break;
1250 }
1251
1252 case NestedNameSpecifier::TypeSpecWithTemplate:
1253 case NestedNameSpecifier::Global:
1254 case NestedNameSpecifier::Identifier:
1255 break;
1256 }
1257
1258 return false;
1259}
1260
1261bool
1262CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1263 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1264 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1265 Qualifiers.push_back(Qualifier);
1266
1267 while (!Qualifiers.empty()) {
1268 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1269 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1270 switch (NNS->getKind()) {
1271 case NestedNameSpecifier::Namespace:
1272 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1273 Q.getLocalBeginLoc(),
1274 TU)))
1275 return true;
1276
1277 break;
1278
1279 case NestedNameSpecifier::NamespaceAlias:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::TypeSpec:
1288 case NestedNameSpecifier::TypeSpecWithTemplate:
1289 if (Visit(Q.getTypeLoc()))
1290 return true;
1291
1292 break;
1293
1294 case NestedNameSpecifier::Global:
1295 case NestedNameSpecifier::Identifier:
1296 break;
1297 }
1298 }
1299
1300 return false;
1301}
1302
1303bool CursorVisitor::VisitTemplateParameters(
1304 const TemplateParameterList *Params) {
1305 if (!Params)
1306 return false;
1307
1308 for (TemplateParameterList::const_iterator P = Params->begin(),
1309 PEnd = Params->end();
1310 P != PEnd; ++P) {
1311 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1312 return true;
1313 }
1314
1315 return false;
1316}
1317
1318bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1319 switch (Name.getKind()) {
1320 case TemplateName::Template:
1321 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1322
1323 case TemplateName::OverloadedTemplate:
1324 // Visit the overloaded template set.
1325 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1326 return true;
1327
1328 return false;
1329
1330 case TemplateName::DependentTemplate:
1331 // FIXME: Visit nested-name-specifier.
1332 return false;
1333
1334 case TemplateName::QualifiedTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return Visit(MakeCursorTemplateRef(
1337 Name.getAsQualifiedTemplateName()->getDecl(),
1338 Loc, TU));
1339
1340 case TemplateName::SubstTemplateTemplateParm:
1341 return Visit(MakeCursorTemplateRef(
1342 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1343 Loc, TU));
1344
1345 case TemplateName::SubstTemplateTemplateParmPack:
1346 return Visit(MakeCursorTemplateRef(
1347 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1348 Loc, TU));
1349 }
1350
1351 llvm_unreachable("Invalid TemplateName::Kind!");
1352}
1353
1354bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1355 switch (TAL.getArgument().getKind()) {
1356 case TemplateArgument::Null:
1357 case TemplateArgument::Integral:
1358 case TemplateArgument::Pack:
1359 return false;
1360
1361 case TemplateArgument::Type:
1362 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1363 return Visit(TSInfo->getTypeLoc());
1364 return false;
1365
1366 case TemplateArgument::Declaration:
1367 if (Expr *E = TAL.getSourceDeclExpression())
1368 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1369 return false;
1370
1371 case TemplateArgument::NullPtr:
1372 if (Expr *E = TAL.getSourceNullPtrExpression())
1373 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1374 return false;
1375
1376 case TemplateArgument::Expression:
1377 if (Expr *E = TAL.getSourceExpression())
1378 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379 return false;
1380
1381 case TemplateArgument::Template:
1382 case TemplateArgument::TemplateExpansion:
1383 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1384 return true;
1385
1386 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1387 TAL.getTemplateNameLoc());
1388 }
1389
1390 llvm_unreachable("Invalid TemplateArgument::Kind!");
1391}
1392
1393bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1394 return VisitDeclContext(D);
1395}
1396
1397bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1398 return Visit(TL.getUnqualifiedLoc());
1399}
1400
1401bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1402 ASTContext &Context = AU->getASTContext();
1403
1404 // Some builtin types (such as Objective-C's "id", "sel", and
1405 // "Class") have associated declarations. Create cursors for those.
1406 QualType VisitType;
1407 switch (TL.getTypePtr()->getKind()) {
1408
1409 case BuiltinType::Void:
1410 case BuiltinType::NullPtr:
1411 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001412 case BuiltinType::OCLImage1d:
1413 case BuiltinType::OCLImage1dArray:
1414 case BuiltinType::OCLImage1dBuffer:
1415 case BuiltinType::OCLImage2d:
1416 case BuiltinType::OCLImage2dArray:
1417 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001418 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001419 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001420#define BUILTIN_TYPE(Id, SingletonId)
1421#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1425#include "clang/AST/BuiltinTypes.def"
1426 break;
1427
1428 case BuiltinType::ObjCId:
1429 VisitType = Context.getObjCIdType();
1430 break;
1431
1432 case BuiltinType::ObjCClass:
1433 VisitType = Context.getObjCClassType();
1434 break;
1435
1436 case BuiltinType::ObjCSel:
1437 VisitType = Context.getObjCSelType();
1438 break;
1439 }
1440
1441 if (!VisitType.isNull()) {
1442 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1443 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1444 TU));
1445 }
1446
1447 return false;
1448}
1449
1450bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1451 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1452}
1453
1454bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1459 if (TL.isDefinition())
1460 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1461
1462 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1463}
1464
1465bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1470 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1471 return true;
1472
1473 return false;
1474}
1475
1476bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1477 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1478 return true;
1479
1480 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1481 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1482 TU)))
1483 return true;
1484 }
1485
1486 return false;
1487}
1488
1489bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1490 return Visit(TL.getPointeeLoc());
1491}
1492
1493bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1494 return Visit(TL.getInnerLoc());
1495}
1496
1497bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1518 return Visit(TL.getModifiedLoc());
1519}
1520
1521bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1522 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001523 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001524 return true;
1525
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001526 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1527 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1529 return true;
1530
1531 return false;
1532}
1533
1534bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1535 if (Visit(TL.getElementLoc()))
1536 return true;
1537
1538 if (Expr *Size = TL.getSizeExpr())
1539 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1540
1541 return false;
1542}
1543
Reid Kleckner8a365022013-06-24 17:51:48 +00001544bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1545 return Visit(TL.getOriginalLoc());
1546}
1547
Reid Kleckner0503a872013-12-05 01:23:43 +00001548bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Guy Benyei11169dd2012-12-18 14:30:41 +00001552bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1553 TemplateSpecializationTypeLoc TL) {
1554 // Visit the template name.
1555 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1556 TL.getTemplateNameLoc()))
1557 return true;
1558
1559 // Visit the template arguments.
1560 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1561 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1562 return true;
1563
1564 return false;
1565}
1566
1567bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1568 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1569}
1570
1571bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1572 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1573 return Visit(TSInfo->getTypeLoc());
1574
1575 return false;
1576}
1577
1578bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1579 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1580 return Visit(TSInfo->getTypeLoc());
1581
1582 return false;
1583}
1584
1585bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1586 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1587 return true;
1588
1589 return false;
1590}
1591
1592bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1593 DependentTemplateSpecializationTypeLoc TL) {
1594 // Visit the nested-name-specifier, if there is one.
1595 if (TL.getQualifierLoc() &&
1596 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1597 return true;
1598
1599 // Visit the template arguments.
1600 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1601 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1602 return true;
1603
1604 return false;
1605}
1606
1607bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1608 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1609 return true;
1610
1611 return Visit(TL.getNamedTypeLoc());
1612}
1613
1614bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1615 return Visit(TL.getPatternLoc());
1616}
1617
1618bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1619 if (Expr *E = TL.getUnderlyingExpr())
1620 return Visit(MakeCXCursor(E, StmtParent, TU));
1621
1622 return false;
1623}
1624
1625bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1626 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1627}
1628
1629bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1630 return Visit(TL.getValueLoc());
1631}
1632
1633#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1634bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1635 return Visit##PARENT##Loc(TL); \
1636}
1637
1638DEFAULT_TYPELOC_IMPL(Complex, Type)
1639DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1641DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1644DEFAULT_TYPELOC_IMPL(Vector, Type)
1645DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1646DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1647DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1648DEFAULT_TYPELOC_IMPL(Record, TagType)
1649DEFAULT_TYPELOC_IMPL(Enum, TagType)
1650DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1651DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1652DEFAULT_TYPELOC_IMPL(Auto, Type)
1653
1654bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1655 // Visit the nested-name-specifier, if present.
1656 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1657 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1658 return true;
1659
1660 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001661 for (const auto &I : D->bases()) {
1662 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001663 return true;
1664 }
1665 }
1666
1667 return VisitTagDecl(D);
1668}
1669
1670bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001671 for (const auto *I : D->attrs())
1672 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001673 return true;
1674
1675 return false;
1676}
1677
1678//===----------------------------------------------------------------------===//
1679// Data-recursive visitor methods.
1680//===----------------------------------------------------------------------===//
1681
1682namespace {
1683#define DEF_JOB(NAME, DATA, KIND)\
1684class NAME : public VisitorJob {\
1685public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001686 NAME(const DATA *d, CXCursor parent) : \
1687 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001688 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001689 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001690};
1691
1692DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1693DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1694DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1695DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1696DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1697 ExplicitTemplateArgsVisitKind)
1698DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1699DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1700DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1701#undef DEF_JOB
1702
1703class DeclVisit : public VisitorJob {
1704public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001705 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001706 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001707 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001708 static bool classof(const VisitorJob *VJ) {
1709 return VJ->getKind() == DeclVisitKind;
1710 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001711 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 bool isFirst() const { return data[1] ? true : false; }
1713};
1714class TypeLocVisit : public VisitorJob {
1715public:
1716 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1717 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1718 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1719
1720 static bool classof(const VisitorJob *VJ) {
1721 return VJ->getKind() == TypeLocVisitKind;
1722 }
1723
1724 TypeLoc get() const {
1725 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001726 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001727 }
1728};
1729
1730class LabelRefVisit : public VisitorJob {
1731public:
1732 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1733 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1734 labelLoc.getPtrEncoding()) {}
1735
1736 static bool classof(const VisitorJob *VJ) {
1737 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1738 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001739 const LabelDecl *get() const {
1740 return static_cast<const LabelDecl *>(data[0]);
1741 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001742 SourceLocation getLoc() const {
1743 return SourceLocation::getFromPtrEncoding(data[1]); }
1744};
1745
1746class NestedNameSpecifierLocVisit : public VisitorJob {
1747public:
1748 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1749 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1750 Qualifier.getNestedNameSpecifier(),
1751 Qualifier.getOpaqueData()) { }
1752
1753 static bool classof(const VisitorJob *VJ) {
1754 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1755 }
1756
1757 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001758 return NestedNameSpecifierLoc(
1759 const_cast<NestedNameSpecifier *>(
1760 static_cast<const NestedNameSpecifier *>(data[0])),
1761 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001762 }
1763};
1764
1765class DeclarationNameInfoVisit : public VisitorJob {
1766public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001768 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 static bool classof(const VisitorJob *VJ) {
1770 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1771 }
1772 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001774 switch (S->getStmtClass()) {
1775 default:
1776 llvm_unreachable("Unhandled Stmt");
1777 case clang::Stmt::MSDependentExistsStmtClass:
1778 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1779 case Stmt::CXXDependentScopeMemberExprClass:
1780 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1781 case Stmt::DependentScopeDeclRefExprClass:
1782 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1783 }
1784 }
1785};
1786class MemberRefVisit : public VisitorJob {
1787public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001788 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1790 L.getPtrEncoding()) {}
1791 static bool classof(const VisitorJob *VJ) {
1792 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1793 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 const FieldDecl *get() const {
1795 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001796 }
1797 SourceLocation getLoc() const {
1798 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1799 }
1800};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001802 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001803 VisitorWorkList &WL;
1804 CXCursor Parent;
1805public:
1806 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1807 : WL(wl), Parent(parent) {}
1808
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001809 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1810 void VisitBlockExpr(const BlockExpr *B);
1811 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1812 void VisitCompoundStmt(const CompoundStmt *S);
1813 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1814 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1815 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1816 void VisitCXXNewExpr(const CXXNewExpr *E);
1817 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1818 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1819 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1820 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1821 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1822 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1823 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1824 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1825 void VisitDeclRefExpr(const DeclRefExpr *D);
1826 void VisitDeclStmt(const DeclStmt *S);
1827 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1828 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1829 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1830 void VisitForStmt(const ForStmt *FS);
1831 void VisitGotoStmt(const GotoStmt *GS);
1832 void VisitIfStmt(const IfStmt *If);
1833 void VisitInitListExpr(const InitListExpr *IE);
1834 void VisitMemberExpr(const MemberExpr *M);
1835 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1836 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1837 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1838 void VisitOverloadExpr(const OverloadExpr *E);
1839 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1840 void VisitStmt(const Stmt *S);
1841 void VisitSwitchStmt(const SwitchStmt *S);
1842 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001843 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1844 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1845 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1846 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1847 void VisitVAArgExpr(const VAArgExpr *E);
1848 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1849 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1850 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1851 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001852 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1853 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001854 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001855 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001856 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001857 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001858 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859
Guy Benyei11169dd2012-12-18 14:30:41 +00001860private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001861 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001862 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1863 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1865 void AddStmt(const Stmt *S);
1866 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001867 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001869 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001870};
1871} // end anonyous namespace
1872
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001874 // 'S' should always be non-null, since it comes from the
1875 // statement we are visiting.
1876 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1877}
1878
1879void
1880EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1881 if (Qualifier)
1882 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1883}
1884
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 if (S)
1887 WL.push_back(StmtVisit(S, Parent));
1888}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 if (D)
1891 WL.push_back(DeclVisit(D, Parent, isFirst));
1892}
1893void EnqueueVisitor::
1894 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1895 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001897}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001898void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001899 if (D)
1900 WL.push_back(MemberRefVisit(D, L, Parent));
1901}
1902void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1903 if (TI)
1904 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1905 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001909 AddStmt(*Child);
1910 }
1911 if (size == WL.size())
1912 return;
1913 // Now reverse the entries we just added. This will match the DFS
1914 // ordering performed by the worklist.
1915 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1916 std::reverse(I, E);
1917}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001918namespace {
1919class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1920 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001921 /// \brief Process clauses with list of variables.
1922 template <typename T>
1923 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001924public:
1925 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1926#define OPENMP_CLAUSE(Name, Class) \
1927 void Visit##Class(const Class *C);
1928#include "clang/Basic/OpenMPKinds.def"
1929};
1930
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001931void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1932 Visitor->AddStmt(C->getCondition());
1933}
1934
Alexey Bataev568a8332014-03-06 06:15:19 +00001935void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1936 Visitor->AddStmt(C->getNumThreads());
1937}
1938
Alexey Bataev62c87d22014-03-21 04:51:18 +00001939void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1940 Visitor->AddStmt(C->getSafelen());
1941}
1942
Alexander Musman8bd31e62014-05-27 15:12:19 +00001943void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1944 Visitor->AddStmt(C->getNumForLoops());
1945}
1946
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001948
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001949void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1950
Alexey Bataev56dafe82014-06-20 07:16:17 +00001951void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1952 Visitor->AddStmt(C->getChunkSize());
1953}
1954
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001955void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1956
Alexey Bataev236070f2014-06-20 11:19:47 +00001957void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1958
Alexey Bataev756c1962013-09-24 03:17:45 +00001959template<typename T>
1960void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001961 for (const auto *I : Node->varlists())
1962 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001963}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001964
1965void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001966 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001967}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001968void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1969 const OMPFirstprivateClause *C) {
1970 VisitOMPClauseList(C);
1971}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001972void OMPClauseEnqueue::VisitOMPLastprivateClause(
1973 const OMPLastprivateClause *C) {
1974 VisitOMPClauseList(C);
1975}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001976void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001977 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001978}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001979void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1980 VisitOMPClauseList(C);
1981}
Alexander Musman8dba6642014-04-22 13:09:42 +00001982void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1983 VisitOMPClauseList(C);
1984 Visitor->AddStmt(C->getStep());
1985}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001986void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1987 VisitOMPClauseList(C);
1988 Visitor->AddStmt(C->getAlignment());
1989}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001990void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1991 VisitOMPClauseList(C);
1992}
Alexey Bataevbae9a792014-06-27 10:37:06 +00001993void
1994OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
1995 VisitOMPClauseList(C);
1996}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001997}
Alexey Bataev756c1962013-09-24 03:17:45 +00001998
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001999void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2000 unsigned size = WL.size();
2001 OMPClauseEnqueue Visitor(this);
2002 Visitor.Visit(S);
2003 if (size == WL.size())
2004 return;
2005 // Now reverse the entries we just added. This will match the DFS
2006 // ordering performed by the worklist.
2007 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2008 std::reverse(I, E);
2009}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002010void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002011 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2012}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002013void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002014 AddDecl(B->getBlockDecl());
2015}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002016void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002017 EnqueueChildren(E);
2018 AddTypeLoc(E->getTypeSourceInfo());
2019}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002020void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2021 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002022 E = S->body_rend(); I != E; ++I) {
2023 AddStmt(*I);
2024 }
2025}
2026void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002027VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002028 AddStmt(S->getSubStmt());
2029 AddDeclarationNameInfo(S);
2030 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2031 AddNestedNameSpecifierLoc(QualifierLoc);
2032}
2033
2034void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002035VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002036 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2037 AddDeclarationNameInfo(E);
2038 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2039 AddNestedNameSpecifierLoc(QualifierLoc);
2040 if (!E->isImplicitAccess())
2041 AddStmt(E->getBase());
2042}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002043void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002044 // Enqueue the initializer , if any.
2045 AddStmt(E->getInitializer());
2046 // Enqueue the array size, if any.
2047 AddStmt(E->getArraySize());
2048 // Enqueue the allocated type.
2049 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2050 // Enqueue the placement arguments.
2051 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2052 AddStmt(E->getPlacementArg(I-1));
2053}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2056 AddStmt(CE->getArg(I-1));
2057 AddStmt(CE->getCallee());
2058 AddStmt(CE->getArg(0));
2059}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002060void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2061 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002062 // Visit the name of the type being destroyed.
2063 AddTypeLoc(E->getDestroyedTypeInfo());
2064 // Visit the scope type that looks disturbingly like the nested-name-specifier
2065 // but isn't.
2066 AddTypeLoc(E->getScopeTypeInfo());
2067 // Visit the nested-name-specifier.
2068 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2069 AddNestedNameSpecifierLoc(QualifierLoc);
2070 // Visit base expression.
2071 AddStmt(E->getBase());
2072}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2074 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002075 AddTypeLoc(E->getTypeSourceInfo());
2076}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2078 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002079 EnqueueChildren(E);
2080 AddTypeLoc(E->getTypeSourceInfo());
2081}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 EnqueueChildren(E);
2084 if (E->isTypeOperand())
2085 AddTypeLoc(E->getTypeOperandSourceInfo());
2086}
2087
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2089 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002090 EnqueueChildren(E);
2091 AddTypeLoc(E->getTypeSourceInfo());
2092}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 EnqueueChildren(E);
2095 if (E->isTypeOperand())
2096 AddTypeLoc(E->getTypeOperandSourceInfo());
2097}
2098
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002100 EnqueueChildren(S);
2101 AddDecl(S->getExceptionDecl());
2102}
2103
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002104void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 if (DR->hasExplicitTemplateArgs()) {
2106 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2107 }
2108 WL.push_back(DeclRefExprParts(DR, Parent));
2109}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2111 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002112 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2113 AddDeclarationNameInfo(E);
2114 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 unsigned size = WL.size();
2118 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002119 for (const auto *D : S->decls()) {
2120 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 isFirst = false;
2122 }
2123 if (size == WL.size())
2124 return;
2125 // Now reverse the entries we just added. This will match the DFS
2126 // ordering performed by the worklist.
2127 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2128 std::reverse(I, E);
2129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 D = E->designators_rbegin(), DEnd = E->designators_rend();
2134 D != DEnd; ++D) {
2135 if (D->isFieldDesignator()) {
2136 if (FieldDecl *Field = D->getField())
2137 AddMemberRef(Field, D->getFieldLoc());
2138 continue;
2139 }
2140 if (D->isArrayDesignator()) {
2141 AddStmt(E->getArrayIndex(*D));
2142 continue;
2143 }
2144 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2145 AddStmt(E->getArrayRangeEnd(*D));
2146 AddStmt(E->getArrayRangeStart(*D));
2147 }
2148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 EnqueueChildren(E);
2151 AddTypeLoc(E->getTypeInfoAsWritten());
2152}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 AddStmt(FS->getBody());
2155 AddStmt(FS->getInc());
2156 AddStmt(FS->getCond());
2157 AddDecl(FS->getConditionVariable());
2158 AddStmt(FS->getInit());
2159}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002160void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002161 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2162}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 AddStmt(If->getElse());
2165 AddStmt(If->getThen());
2166 AddStmt(If->getCond());
2167 AddDecl(If->getConditionVariable());
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002170 // We care about the syntactic form of the initializer list, only.
2171 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2172 IE = Syntactic;
2173 EnqueueChildren(IE);
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 WL.push_back(MemberExprParts(M, Parent));
2177
2178 // If the base of the member access expression is an implicit 'this', don't
2179 // visit it.
2180 // FIXME: If we ever want to show these implicit accesses, this will be
2181 // unfortunate. However, clang_getCursor() relies on this behavior.
2182 if (!M->isImplicitAccess())
2183 AddStmt(M->getBase());
2184}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 AddTypeLoc(E->getEncodedTypeSourceInfo());
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 EnqueueChildren(M);
2190 AddTypeLoc(M->getClassReceiverTypeInfo());
2191}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 // Visit the components of the offsetof expression.
2194 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2195 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2196 const OffsetOfNode &Node = E->getComponent(I-1);
2197 switch (Node.getKind()) {
2198 case OffsetOfNode::Array:
2199 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2200 break;
2201 case OffsetOfNode::Field:
2202 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2203 break;
2204 case OffsetOfNode::Identifier:
2205 case OffsetOfNode::Base:
2206 continue;
2207 }
2208 }
2209 // Visit the type into which we're computing the offset.
2210 AddTypeLoc(E->getTypeSourceInfo());
2211}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2214 WL.push_back(OverloadExprParts(E, Parent));
2215}
2216void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 EnqueueChildren(E);
2219 if (E->isArgumentType())
2220 AddTypeLoc(E->getArgumentTypeInfo());
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 EnqueueChildren(S);
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 AddStmt(S->getBody());
2227 AddStmt(S->getCond());
2228 AddDecl(S->getConditionVariable());
2229}
2230
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddStmt(W->getBody());
2233 AddStmt(W->getCond());
2234 AddDecl(W->getConditionVariable());
2235}
2236
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002238 for (unsigned I = E->getNumArgs(); I > 0; --I)
2239 AddTypeLoc(E->getArg(I-1));
2240}
2241
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 AddTypeLoc(E->getQueriedTypeSourceInfo());
2244}
2245
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002246void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 EnqueueChildren(E);
2248}
2249
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 VisitOverloadExpr(U);
2252 if (!U->isImplicitAccess())
2253 AddStmt(U->getBase());
2254}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 AddStmt(E->getSubExpr());
2257 AddTypeLoc(E->getWrittenTypeInfo());
2258}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 WL.push_back(SizeOfPackExprParts(E, Parent));
2261}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 // If the opaque value has a source expression, just transparently
2264 // visit that. This is useful for (e.g.) pseudo-object expressions.
2265 if (Expr *SourceExpr = E->getSourceExpr())
2266 return Visit(SourceExpr);
2267}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 AddStmt(E->getBody());
2270 WL.push_back(LambdaExprParts(E, Parent));
2271}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002272void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002273 // Treat the expression like its syntactic form.
2274 Visit(E->getSyntacticForm());
2275}
2276
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002277void EnqueueVisitor::VisitOMPExecutableDirective(
2278 const OMPExecutableDirective *D) {
2279 EnqueueChildren(D);
2280 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2281 E = D->clauses().end();
2282 I != E; ++I)
2283 EnqueueChildren(*I);
2284}
2285
2286void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2287 VisitOMPExecutableDirective(D);
2288}
2289
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002290void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2291 VisitOMPExecutableDirective(D);
2292}
2293
Alexey Bataevf29276e2014-06-18 04:14:57 +00002294void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2295 VisitOMPExecutableDirective(D);
2296}
2297
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002298void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2299 VisitOMPExecutableDirective(D);
2300}
2301
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002302void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2303 VisitOMPExecutableDirective(D);
2304}
2305
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002306void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2307 VisitOMPExecutableDirective(D);
2308}
2309
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2312}
2313
2314bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2315 if (RegionOfInterest.isValid()) {
2316 SourceRange Range = getRawCursorExtent(C);
2317 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2318 return false;
2319 }
2320 return true;
2321}
2322
2323bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2324 while (!WL.empty()) {
2325 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002326 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002327
2328 // Set the Parent field, then back to its old value once we're done.
2329 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2330
2331 switch (LI.getKind()) {
2332 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002333 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002334 if (!D)
2335 continue;
2336
2337 // For now, perform default visitation for Decls.
2338 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2339 cast<DeclVisit>(&LI)->isFirst())))
2340 return true;
2341
2342 continue;
2343 }
2344 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2345 const ASTTemplateArgumentListInfo *ArgList =
2346 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2347 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2348 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2349 Arg != ArgEnd; ++Arg) {
2350 if (VisitTemplateArgumentLoc(*Arg))
2351 return true;
2352 }
2353 continue;
2354 }
2355 case VisitorJob::TypeLocVisitKind: {
2356 // Perform default visitation for TypeLocs.
2357 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2358 return true;
2359 continue;
2360 }
2361 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002362 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002363 if (LabelStmt *stmt = LS->getStmt()) {
2364 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2365 TU))) {
2366 return true;
2367 }
2368 }
2369 continue;
2370 }
2371
2372 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2373 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2374 if (VisitNestedNameSpecifierLoc(V->get()))
2375 return true;
2376 continue;
2377 }
2378
2379 case VisitorJob::DeclarationNameInfoVisitKind: {
2380 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2381 ->get()))
2382 return true;
2383 continue;
2384 }
2385 case VisitorJob::MemberRefVisitKind: {
2386 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2387 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2388 return true;
2389 continue;
2390 }
2391 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002392 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002393 if (!S)
2394 continue;
2395
2396 // Update the current cursor.
2397 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2398 if (!IsInRegionOfInterest(Cursor))
2399 continue;
2400 switch (Visitor(Cursor, Parent, ClientData)) {
2401 case CXChildVisit_Break: return true;
2402 case CXChildVisit_Continue: break;
2403 case CXChildVisit_Recurse:
2404 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002405 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002406 EnqueueWorkList(WL, S);
2407 break;
2408 }
2409 continue;
2410 }
2411 case VisitorJob::MemberExprPartsKind: {
2412 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002414
2415 // Visit the nested-name-specifier
2416 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2417 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2418 return true;
2419
2420 // Visit the declaration name.
2421 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2422 return true;
2423
2424 // Visit the explicitly-specified template arguments, if any.
2425 if (M->hasExplicitTemplateArgs()) {
2426 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2427 *ArgEnd = Arg + M->getNumTemplateArgs();
2428 Arg != ArgEnd; ++Arg) {
2429 if (VisitTemplateArgumentLoc(*Arg))
2430 return true;
2431 }
2432 }
2433 continue;
2434 }
2435 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002436 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002437 // Visit nested-name-specifier, if present.
2438 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2439 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2440 return true;
2441 // Visit declaration name.
2442 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2443 return true;
2444 continue;
2445 }
2446 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002447 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002448 // Visit the nested-name-specifier.
2449 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2450 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2451 return true;
2452 // Visit the declaration name.
2453 if (VisitDeclarationNameInfo(O->getNameInfo()))
2454 return true;
2455 // Visit the overloaded declaration reference.
2456 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2457 return true;
2458 continue;
2459 }
2460 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002461 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002462 NamedDecl *Pack = E->getPack();
2463 if (isa<TemplateTypeParmDecl>(Pack)) {
2464 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2465 E->getPackLoc(), TU)))
2466 return true;
2467
2468 continue;
2469 }
2470
2471 if (isa<TemplateTemplateParmDecl>(Pack)) {
2472 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2473 E->getPackLoc(), TU)))
2474 return true;
2475
2476 continue;
2477 }
2478
2479 // Non-type template parameter packs and function parameter packs are
2480 // treated like DeclRefExpr cursors.
2481 continue;
2482 }
2483
2484 case VisitorJob::LambdaExprPartsKind: {
2485 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002486 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002487 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2488 CEnd = E->explicit_capture_end();
2489 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002490 // FIXME: Lambda init-captures.
2491 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002492 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002493
Guy Benyei11169dd2012-12-18 14:30:41 +00002494 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2495 C->getLocation(),
2496 TU)))
2497 return true;
2498 }
2499
2500 // Visit parameters and return type, if present.
2501 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2502 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2503 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2504 // Visit the whole type.
2505 if (Visit(TL))
2506 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002507 } else if (FunctionProtoTypeLoc Proto =
2508 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002509 if (E->hasExplicitParameters()) {
2510 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002511 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2512 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002513 return true;
2514 } else {
2515 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002516 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002517 return true;
2518 }
2519 }
2520 }
2521 break;
2522 }
2523
2524 case VisitorJob::PostChildrenVisitKind:
2525 if (PostChildrenVisitor(Parent, ClientData))
2526 return true;
2527 break;
2528 }
2529 }
2530 return false;
2531}
2532
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002533bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002534 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002535 if (!WorkListFreeList.empty()) {
2536 WL = WorkListFreeList.back();
2537 WL->clear();
2538 WorkListFreeList.pop_back();
2539 }
2540 else {
2541 WL = new VisitorWorkList();
2542 WorkListCache.push_back(WL);
2543 }
2544 EnqueueWorkList(*WL, S);
2545 bool result = RunVisitorWorkList(*WL);
2546 WorkListFreeList.push_back(WL);
2547 return result;
2548}
2549
2550namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002551typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002552RefNamePieces
2553buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2554 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2555 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002556 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2557 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2558 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2559
2560 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2561
2562 RefNamePieces Pieces;
2563
2564 if (WantQualifier && QLoc.isValid())
2565 Pieces.push_back(QLoc);
2566
2567 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2568 Pieces.push_back(NI.getLoc());
2569
2570 if (WantTemplateArgs && TemplateArgs)
2571 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2572 TemplateArgs->RAngleLoc));
2573
2574 if (Kind == DeclarationName::CXXOperatorName) {
2575 Pieces.push_back(SourceLocation::getFromRawEncoding(
2576 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2577 Pieces.push_back(SourceLocation::getFromRawEncoding(
2578 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2579 }
2580
2581 if (WantSinglePiece) {
2582 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2583 Pieces.clear();
2584 Pieces.push_back(R);
2585 }
2586
2587 return Pieces;
2588}
2589}
2590
2591//===----------------------------------------------------------------------===//
2592// Misc. API hooks.
2593//===----------------------------------------------------------------------===//
2594
Chad Rosier05c71aa2013-03-27 18:28:23 +00002595static void fatal_error_handler(void *user_data, const std::string& reason,
2596 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002597 // Write the result out to stderr avoiding errs() because raw_ostreams can
2598 // call report_fatal_error.
2599 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2600 ::abort();
2601}
2602
2603extern "C" {
2604CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2605 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002606 // We use crash recovery to make some of our APIs more reliable, implicitly
2607 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002608 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2609 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002610
Chandler Carruth37ad2582014-06-27 15:14:39 +00002611 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00002612
2613 CIndexer *CIdxr = new CIndexer();
2614 if (excludeDeclarationsFromPCH)
2615 CIdxr->setOnlyLocalDecls();
2616 if (displayDiagnostics)
2617 CIdxr->setDisplayDiagnostics();
2618
2619 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2620 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2621 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2622 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2623 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2624 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2625
2626 return CIdxr;
2627}
2628
2629void clang_disposeIndex(CXIndex CIdx) {
2630 if (CIdx)
2631 delete static_cast<CIndexer *>(CIdx);
2632}
2633
2634void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2635 if (CIdx)
2636 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2637}
2638
2639unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2640 if (CIdx)
2641 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2642 return 0;
2643}
2644
2645void clang_toggleCrashRecovery(unsigned isEnabled) {
2646 if (isEnabled)
2647 llvm::CrashRecoveryContext::Enable();
2648 else
2649 llvm::CrashRecoveryContext::Disable();
2650}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002651
Guy Benyei11169dd2012-12-18 14:30:41 +00002652CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2653 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002654 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002655 enum CXErrorCode Result =
2656 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002657 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002658 assert((TU && Result == CXError_Success) ||
2659 (!TU && Result != CXError_Success));
2660 return TU;
2661}
2662
2663enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2664 const char *ast_filename,
2665 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002666 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002667 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002668
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002669 if (!CIdx || !ast_filename || !out_TU)
2670 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002671
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002672 LOG_FUNC_SECTION {
2673 *Log << ast_filename;
2674 }
2675
Guy Benyei11169dd2012-12-18 14:30:41 +00002676 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2677 FileSystemOptions FileSystemOpts;
2678
2679 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002680 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002681 CXXIdx->getOnlyLocalDecls(), None,
2682 /*CaptureDiagnostics=*/true,
2683 /*AllowPCHWithCompilerErrors=*/true,
2684 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002685 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2686 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002687}
2688
2689unsigned clang_defaultEditingTranslationUnitOptions() {
2690 return CXTranslationUnit_PrecompiledPreamble |
2691 CXTranslationUnit_CacheCompletionResults;
2692}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002693
Guy Benyei11169dd2012-12-18 14:30:41 +00002694CXTranslationUnit
2695clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2696 const char *source_filename,
2697 int num_command_line_args,
2698 const char * const *command_line_args,
2699 unsigned num_unsaved_files,
2700 struct CXUnsavedFile *unsaved_files) {
2701 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2702 return clang_parseTranslationUnit(CIdx, source_filename,
2703 command_line_args, num_command_line_args,
2704 unsaved_files, num_unsaved_files,
2705 Options);
2706}
2707
2708struct ParseTranslationUnitInfo {
2709 CXIndex CIdx;
2710 const char *source_filename;
2711 const char *const *command_line_args;
2712 int num_command_line_args;
2713 struct CXUnsavedFile *unsaved_files;
2714 unsigned num_unsaved_files;
2715 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002716 CXTranslationUnit *out_TU;
2717 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002718};
2719static void clang_parseTranslationUnit_Impl(void *UserData) {
2720 ParseTranslationUnitInfo *PTUI =
2721 static_cast<ParseTranslationUnitInfo*>(UserData);
2722 CXIndex CIdx = PTUI->CIdx;
2723 const char *source_filename = PTUI->source_filename;
2724 const char * const *command_line_args = PTUI->command_line_args;
2725 int num_command_line_args = PTUI->num_command_line_args;
2726 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2727 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2728 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002729 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002730
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002731 // Set up the initial return values.
2732 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002733 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002734 PTUI->result = CXError_Failure;
2735
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002736 // Check arguments.
2737 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002738 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002739 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002740 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002741 }
2742
Guy Benyei11169dd2012-12-18 14:30:41 +00002743 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2744
2745 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2746 setThreadBackgroundPriority();
2747
2748 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2749 // FIXME: Add a flag for modules.
2750 TranslationUnitKind TUKind
2751 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002752 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002753 = options & CXTranslationUnit_CacheCompletionResults;
2754 bool IncludeBriefCommentsInCodeCompletion
2755 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2756 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2757 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2758
2759 // Configure the diagnostics.
2760 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002761 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002762
2763 // Recover resources if we crash before exiting this function.
2764 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2765 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2766 DiagCleanup(Diags.getPtr());
2767
Ahmed Charlesb8984322014-03-07 20:03:18 +00002768 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2769 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002770
2771 // Recover resources if we crash before exiting this function.
2772 llvm::CrashRecoveryContextCleanupRegistrar<
2773 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2774
2775 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2776 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2777 const llvm::MemoryBuffer *Buffer
2778 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2779 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2780 Buffer));
2781 }
2782
Ahmed Charlesb8984322014-03-07 20:03:18 +00002783 std::unique_ptr<std::vector<const char *>> Args(
2784 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002785
2786 // Recover resources if we crash before exiting this method.
2787 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2788 ArgsCleanup(Args.get());
2789
2790 // Since the Clang C library is primarily used by batch tools dealing with
2791 // (often very broken) source code, where spell-checking can have a
2792 // significant negative impact on performance (particularly when
2793 // precompiled headers are involved), we disable it by default.
2794 // Only do this if we haven't found a spell-checking-related argument.
2795 bool FoundSpellCheckingArgument = false;
2796 for (int I = 0; I != num_command_line_args; ++I) {
2797 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2798 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2799 FoundSpellCheckingArgument = true;
2800 break;
2801 }
2802 }
2803 if (!FoundSpellCheckingArgument)
2804 Args->push_back("-fno-spell-checking");
2805
2806 Args->insert(Args->end(), command_line_args,
2807 command_line_args + num_command_line_args);
2808
2809 // The 'source_filename' argument is optional. If the caller does not
2810 // specify it then it is assumed that the source file is specified
2811 // in the actual argument list.
2812 // Put the source file after command_line_args otherwise if '-x' flag is
2813 // present it will be unused.
2814 if (source_filename)
2815 Args->push_back(source_filename);
2816
2817 // Do we need the detailed preprocessing record?
2818 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2819 Args->push_back("-Xclang");
2820 Args->push_back("-detailed-preprocessing-record");
2821 }
2822
2823 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002824 std::unique_ptr<ASTUnit> ErrUnit;
2825 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002826 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002827 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2828 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2829 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2830 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2831 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2832 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002833
2834 if (NumErrors != Diags->getClient()->getNumErrors()) {
2835 // Make sure to check that 'Unit' is non-NULL.
2836 if (CXXIdx->getDisplayDiagnostics())
2837 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2838 }
2839
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002840 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2841 PTUI->result = CXError_ASTReadError;
2842 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002843 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002844 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2845 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002846}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002847
2848CXTranslationUnit
2849clang_parseTranslationUnit(CXIndex CIdx,
2850 const char *source_filename,
2851 const char *const *command_line_args,
2852 int num_command_line_args,
2853 struct CXUnsavedFile *unsaved_files,
2854 unsigned num_unsaved_files,
2855 unsigned options) {
2856 CXTranslationUnit TU;
2857 enum CXErrorCode Result = clang_parseTranslationUnit2(
2858 CIdx, source_filename, command_line_args, num_command_line_args,
2859 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002860 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002861 assert((TU && Result == CXError_Success) ||
2862 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002863 return TU;
2864}
2865
2866enum CXErrorCode clang_parseTranslationUnit2(
2867 CXIndex CIdx,
2868 const char *source_filename,
2869 const char *const *command_line_args,
2870 int num_command_line_args,
2871 struct CXUnsavedFile *unsaved_files,
2872 unsigned num_unsaved_files,
2873 unsigned options,
2874 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002875 LOG_FUNC_SECTION {
2876 *Log << source_filename << ": ";
2877 for (int i = 0; i != num_command_line_args; ++i)
2878 *Log << command_line_args[i] << " ";
2879 }
2880
Guy Benyei11169dd2012-12-18 14:30:41 +00002881 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2882 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002883 num_unsaved_files, options, out_TU,
2884 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002885 llvm::CrashRecoveryContext CRC;
2886
2887 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2888 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2889 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2890 fprintf(stderr, " 'command_line_args' : [");
2891 for (int i = 0; i != num_command_line_args; ++i) {
2892 if (i)
2893 fprintf(stderr, ", ");
2894 fprintf(stderr, "'%s'", command_line_args[i]);
2895 }
2896 fprintf(stderr, "],\n");
2897 fprintf(stderr, " 'unsaved_files' : [");
2898 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2899 if (i)
2900 fprintf(stderr, ", ");
2901 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2902 unsaved_files[i].Length);
2903 }
2904 fprintf(stderr, "],\n");
2905 fprintf(stderr, " 'options' : %d,\n", options);
2906 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002907
2908 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002909 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002910 if (CXTranslationUnit *TU = PTUI.out_TU)
2911 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002912 }
2913
2914 return PTUI.result;
2915}
2916
2917unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2918 return CXSaveTranslationUnit_None;
2919}
2920
2921namespace {
2922
2923struct SaveTranslationUnitInfo {
2924 CXTranslationUnit TU;
2925 const char *FileName;
2926 unsigned options;
2927 CXSaveError result;
2928};
2929
2930}
2931
2932static void clang_saveTranslationUnit_Impl(void *UserData) {
2933 SaveTranslationUnitInfo *STUI =
2934 static_cast<SaveTranslationUnitInfo*>(UserData);
2935
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002936 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002937 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2938 setThreadBackgroundPriority();
2939
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002940 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002941 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2942}
2943
2944int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2945 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002946 LOG_FUNC_SECTION {
2947 *Log << TU << ' ' << FileName;
2948 }
2949
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002950 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002951 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002952 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002953 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002954
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002955 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002956 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2957 if (!CXXUnit->hasSema())
2958 return CXSaveError_InvalidTU;
2959
2960 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2961
2962 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2963 getenv("LIBCLANG_NOTHREADS")) {
2964 clang_saveTranslationUnit_Impl(&STUI);
2965
2966 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2967 PrintLibclangResourceUsage(TU);
2968
2969 return STUI.result;
2970 }
2971
2972 // We have an AST that has invalid nodes due to compiler errors.
2973 // Use a crash recovery thread for protection.
2974
2975 llvm::CrashRecoveryContext CRC;
2976
2977 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2978 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2979 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2980 fprintf(stderr, " 'options' : %d,\n", options);
2981 fprintf(stderr, "}\n");
2982
2983 return CXSaveError_Unknown;
2984
2985 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2986 PrintLibclangResourceUsage(TU);
2987 }
2988
2989 return STUI.result;
2990}
2991
2992void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2993 if (CTUnit) {
2994 // If the translation unit has been marked as unsafe to free, just discard
2995 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002996 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2997 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002998 return;
2999
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003000 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003001 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003002 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3003 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003004 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003005 delete CTUnit;
3006 }
3007}
3008
3009unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3010 return CXReparse_None;
3011}
3012
3013struct ReparseTranslationUnitInfo {
3014 CXTranslationUnit TU;
3015 unsigned num_unsaved_files;
3016 struct CXUnsavedFile *unsaved_files;
3017 unsigned options;
3018 int result;
3019};
3020
3021static void clang_reparseTranslationUnit_Impl(void *UserData) {
3022 ReparseTranslationUnitInfo *RTUI =
3023 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003024 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003025
Guy Benyei11169dd2012-12-18 14:30:41 +00003026 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003027 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3028 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3029 unsigned options = RTUI->options;
3030 (void) options;
3031
3032 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003033 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003034 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003035 RTUI->result = CXError_InvalidArguments;
3036 return;
3037 }
Craig Topper69186e72014-06-08 08:38:04 +00003038 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003039 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003040 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003041 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003042
3043 // Reset the associated diagnostics.
3044 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003045 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003046
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003047 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003048 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3049 setThreadBackgroundPriority();
3050
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003051 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003052 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003053
3054 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3055 new std::vector<ASTUnit::RemappedFile>());
3056
Guy Benyei11169dd2012-12-18 14:30:41 +00003057 // Recover resources if we crash before exiting this function.
3058 llvm::CrashRecoveryContextCleanupRegistrar<
3059 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3060
3061 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3062 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3063 const llvm::MemoryBuffer *Buffer
3064 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3065 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3066 Buffer));
3067 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003068
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003069 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003070 RTUI->result = CXError_Success;
3071 else if (isASTReadError(CXXUnit))
3072 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003073}
3074
3075int clang_reparseTranslationUnit(CXTranslationUnit TU,
3076 unsigned num_unsaved_files,
3077 struct CXUnsavedFile *unsaved_files,
3078 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003079 LOG_FUNC_SECTION {
3080 *Log << TU;
3081 }
3082
Guy Benyei11169dd2012-12-18 14:30:41 +00003083 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003084 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003085
3086 if (getenv("LIBCLANG_NOTHREADS")) {
3087 clang_reparseTranslationUnit_Impl(&RTUI);
3088 return RTUI.result;
3089 }
3090
3091 llvm::CrashRecoveryContext CRC;
3092
3093 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3094 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003095 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003096 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003097 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3098 PrintLibclangResourceUsage(TU);
3099
3100 return RTUI.result;
3101}
3102
3103
3104CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003105 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003106 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003107 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003108 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003109
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003110 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003111 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003112}
3113
3114CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003115 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003116 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003117 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003118 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003119
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003120 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3122}
3123
3124} // end: extern "C"
3125
3126//===----------------------------------------------------------------------===//
3127// CXFile Operations.
3128//===----------------------------------------------------------------------===//
3129
3130extern "C" {
3131CXString clang_getFileName(CXFile SFile) {
3132 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003133 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003134
3135 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003136 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003137}
3138
3139time_t clang_getFileTime(CXFile SFile) {
3140 if (!SFile)
3141 return 0;
3142
3143 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3144 return FEnt->getModificationTime();
3145}
3146
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003147CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003148 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003149 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003150 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003151 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003152
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003153 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003154
3155 FileManager &FMgr = CXXUnit->getFileManager();
3156 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3157}
3158
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003159unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3160 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003161 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003162 LOG_BAD_TU(TU);
3163 return 0;
3164 }
3165
3166 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 return 0;
3168
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003169 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003170 FileEntry *FEnt = static_cast<FileEntry *>(file);
3171 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3172 .isFileMultipleIncludeGuarded(FEnt);
3173}
3174
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003175int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3176 if (!file || !outID)
3177 return 1;
3178
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003179 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003180 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3181 outID->data[0] = ID.getDevice();
3182 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003183 outID->data[2] = FEnt->getModificationTime();
3184 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003185}
3186
Guy Benyei11169dd2012-12-18 14:30:41 +00003187} // end: extern "C"
3188
3189//===----------------------------------------------------------------------===//
3190// CXCursor Operations.
3191//===----------------------------------------------------------------------===//
3192
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193static const Decl *getDeclFromExpr(const Stmt *E) {
3194 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 return getDeclFromExpr(CE->getSubExpr());
3196
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003199 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003201 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003203 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 if (PRE->isExplicitProperty())
3205 return PRE->getExplicitProperty();
3206 // It could be messaging both getter and setter as in:
3207 // ++myobj.myprop;
3208 // in which case prefer to associate the setter since it is less obvious
3209 // from inspecting the source that the setter is going to get called.
3210 if (PRE->isMessagingSetter())
3211 return PRE->getImplicitPropertySetter();
3212 return PRE->getImplicitPropertyGetter();
3213 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003214 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003216 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 if (Expr *Src = OVE->getSourceExpr())
3218 return getDeclFromExpr(Src);
3219
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003220 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003222 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 if (!CE->isElidable())
3224 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003225 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003226 return OME->getMethodDecl();
3227
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003228 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003230 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003231 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3232 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003233 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3235 isa<ParmVarDecl>(SizeOfPack->getPack()))
3236 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003237
3238 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003239}
3240
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003241static SourceLocation getLocationFromExpr(const Expr *E) {
3242 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 return getLocationFromExpr(CE->getSubExpr());
3244
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003245 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003246 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003247 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003249 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003250 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003251 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003252 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003253 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003255 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 return PropRef->getLocation();
3257
3258 return E->getLocStart();
3259}
3260
3261extern "C" {
3262
3263unsigned clang_visitChildren(CXCursor parent,
3264 CXCursorVisitor visitor,
3265 CXClientData client_data) {
3266 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3267 /*VisitPreprocessorLast=*/false);
3268 return CursorVis.VisitChildren(parent);
3269}
3270
3271#ifndef __has_feature
3272#define __has_feature(x) 0
3273#endif
3274#if __has_feature(blocks)
3275typedef enum CXChildVisitResult
3276 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3277
3278static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3279 CXClientData client_data) {
3280 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3281 return block(cursor, parent);
3282}
3283#else
3284// If we are compiled with a compiler that doesn't have native blocks support,
3285// define and call the block manually, so the
3286typedef struct _CXChildVisitResult
3287{
3288 void *isa;
3289 int flags;
3290 int reserved;
3291 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3292 CXCursor);
3293} *CXCursorVisitorBlock;
3294
3295static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3296 CXClientData client_data) {
3297 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3298 return block->invoke(block, cursor, parent);
3299}
3300#endif
3301
3302
3303unsigned clang_visitChildrenWithBlock(CXCursor parent,
3304 CXCursorVisitorBlock block) {
3305 return clang_visitChildren(parent, visitWithBlock, block);
3306}
3307
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003308static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003310 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003311
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003312 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003314 if (const ObjCPropertyImplDecl *PropImpl =
3315 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003317 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003318
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003319 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003320 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003321 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003322
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003323 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 }
3325
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003326 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003327 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003328
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003329 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3331 // and returns different names. NamedDecl returns the class name and
3332 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003333 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003334
3335 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003336 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003337
3338 SmallString<1024> S;
3339 llvm::raw_svector_ostream os(S);
3340 ND->printName(os);
3341
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003342 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003343}
3344
3345CXString clang_getCursorSpelling(CXCursor C) {
3346 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003347 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003348
3349 if (clang_isReference(C.kind)) {
3350 switch (C.kind) {
3351 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003352 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003353 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 }
3355 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003356 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003357 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 }
3359 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003360 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003362 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 }
3364 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003365 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003366 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 }
3368 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003369 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 assert(Type && "Missing type decl");
3371
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003372 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 getAsString());
3374 }
3375 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003376 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 assert(Template && "Missing template decl");
3378
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003379 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 }
3381
3382 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003383 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 assert(NS && "Missing namespace decl");
3385
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003386 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 }
3388
3389 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003390 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 assert(Field && "Missing member decl");
3392
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003393 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 }
3395
3396 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003397 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003398 assert(Label && "Missing label");
3399
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003400 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 }
3402
3403 case CXCursor_OverloadedDeclRef: {
3404 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003405 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3406 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003407 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003408 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003409 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003410 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003411 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 OverloadedTemplateStorage *Ovl
3413 = Storage.get<OverloadedTemplateStorage*>();
3414 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003415 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003416 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 }
3418
3419 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003420 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 assert(Var && "Missing variable decl");
3422
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003423 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 }
3425
3426 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003427 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003428 }
3429 }
3430
3431 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003432 const Expr *E = getCursorExpr(C);
3433
3434 if (C.kind == CXCursor_ObjCStringLiteral ||
3435 C.kind == CXCursor_StringLiteral) {
3436 const StringLiteral *SLit;
3437 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3438 SLit = OSL->getString();
3439 } else {
3440 SLit = cast<StringLiteral>(E);
3441 }
3442 SmallString<256> Buf;
3443 llvm::raw_svector_ostream OS(Buf);
3444 SLit->outputString(OS);
3445 return cxstring::createDup(OS.str());
3446 }
3447
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003448 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003449 if (D)
3450 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003451 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 }
3453
3454 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003455 const Stmt *S = getCursorStmt(C);
3456 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003457 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003458
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003459 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 }
3461
3462 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003463 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 ->getNameStart());
3465
3466 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003467 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 ->getNameStart());
3469
3470 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003471 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003472
3473 if (clang_isDeclaration(C.kind))
3474 return getDeclSpelling(getCursorDecl(C));
3475
3476 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003477 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003478 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 }
3480
3481 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003482 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003483 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 }
3485
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003486 if (C.kind == CXCursor_PackedAttr) {
3487 return cxstring::createRef("packed");
3488 }
3489
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003490 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003491}
3492
3493CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3494 unsigned pieceIndex,
3495 unsigned options) {
3496 if (clang_Cursor_isNull(C))
3497 return clang_getNullRange();
3498
3499 ASTContext &Ctx = getCursorContext(C);
3500
3501 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003502 const Stmt *S = getCursorStmt(C);
3503 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 if (pieceIndex > 0)
3505 return clang_getNullRange();
3506 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3507 }
3508
3509 return clang_getNullRange();
3510 }
3511
3512 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003513 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3515 if (pieceIndex >= ME->getNumSelectorLocs())
3516 return clang_getNullRange();
3517 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3518 }
3519 }
3520
3521 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3522 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003523 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3525 if (pieceIndex >= MD->getNumSelectorLocs())
3526 return clang_getNullRange();
3527 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3528 }
3529 }
3530
3531 if (C.kind == CXCursor_ObjCCategoryDecl ||
3532 C.kind == CXCursor_ObjCCategoryImplDecl) {
3533 if (pieceIndex > 0)
3534 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003535 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3537 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003538 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3540 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3541 }
3542
3543 if (C.kind == CXCursor_ModuleImportDecl) {
3544 if (pieceIndex > 0)
3545 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003546 if (const ImportDecl *ImportD =
3547 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3549 if (!Locs.empty())
3550 return cxloc::translateSourceRange(Ctx,
3551 SourceRange(Locs.front(), Locs.back()));
3552 }
3553 return clang_getNullRange();
3554 }
3555
3556 // FIXME: A CXCursor_InclusionDirective should give the location of the
3557 // filename, but we don't keep track of this.
3558
3559 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3560 // but we don't keep track of this.
3561
3562 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3563 // but we don't keep track of this.
3564
3565 // Default handling, give the location of the cursor.
3566
3567 if (pieceIndex > 0)
3568 return clang_getNullRange();
3569
3570 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3571 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3572 return cxloc::translateSourceRange(Ctx, Loc);
3573}
3574
3575CXString clang_getCursorDisplayName(CXCursor C) {
3576 if (!clang_isDeclaration(C.kind))
3577 return clang_getCursorSpelling(C);
3578
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003579 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003581 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003582
3583 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003584 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 D = FunTmpl->getTemplatedDecl();
3586
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003587 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 SmallString<64> Str;
3589 llvm::raw_svector_ostream OS(Str);
3590 OS << *Function;
3591 if (Function->getPrimaryTemplate())
3592 OS << "<>";
3593 OS << "(";
3594 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3595 if (I)
3596 OS << ", ";
3597 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3598 }
3599
3600 if (Function->isVariadic()) {
3601 if (Function->getNumParams())
3602 OS << ", ";
3603 OS << "...";
3604 }
3605 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003606 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 }
3608
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003609 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 SmallString<64> Str;
3611 llvm::raw_svector_ostream OS(Str);
3612 OS << *ClassTemplate;
3613 OS << "<";
3614 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3615 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3616 if (I)
3617 OS << ", ";
3618
3619 NamedDecl *Param = Params->getParam(I);
3620 if (Param->getIdentifier()) {
3621 OS << Param->getIdentifier()->getName();
3622 continue;
3623 }
3624
3625 // There is no parameter name, which makes this tricky. Try to come up
3626 // with something useful that isn't too long.
3627 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3628 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3629 else if (NonTypeTemplateParmDecl *NTTP
3630 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3631 OS << NTTP->getType().getAsString(Policy);
3632 else
3633 OS << "template<...> class";
3634 }
3635
3636 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003637 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 }
3639
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003640 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3642 // If the type was explicitly written, use that.
3643 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003644 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003645
Benjamin Kramer9170e912013-02-22 15:46:01 +00003646 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 llvm::raw_svector_ostream OS(Str);
3648 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003649 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 ClassSpec->getTemplateArgs().data(),
3651 ClassSpec->getTemplateArgs().size(),
3652 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003653 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 }
3655
3656 return clang_getCursorSpelling(C);
3657}
3658
3659CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3660 switch (Kind) {
3661 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003789 case CXCursor_ObjCSelfExpr:
3790 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003907 case CXCursor_PackedAttr:
3908 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003909 case CXCursor_PureAttr:
3910 return cxstring::createRef("attribute(pure)");
3911 case CXCursor_ConstAttr:
3912 return cxstring::createRef("attribute(const)");
3913 case CXCursor_NoDuplicateAttr:
3914 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003915 case CXCursor_CUDAConstantAttr:
3916 return cxstring::createRef("attribute(constant)");
3917 case CXCursor_CUDADeviceAttr:
3918 return cxstring::createRef("attribute(device)");
3919 case CXCursor_CUDAGlobalAttr:
3920 return cxstring::createRef("attribute(global)");
3921 case CXCursor_CUDAHostAttr:
3922 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003971 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003972 return cxstring::createRef("OMPParallelDirective");
3973 case CXCursor_OMPSimdDirective:
3974 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003975 case CXCursor_OMPForDirective:
3976 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00003977 case CXCursor_OMPSectionsDirective:
3978 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003979 case CXCursor_OMPSectionDirective:
3980 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00003981 case CXCursor_OMPSingleDirective:
3982 return cxstring::createRef("OMPSingleDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 }
3984
3985 llvm_unreachable("Unhandled CXCursorKind");
3986}
3987
3988struct GetCursorData {
3989 SourceLocation TokenBeginLoc;
3990 bool PointsAtMacroArgExpansion;
3991 bool VisitedObjCPropertyImplDecl;
3992 SourceLocation VisitedDeclaratorDeclStartLoc;
3993 CXCursor &BestCursor;
3994
3995 GetCursorData(SourceManager &SM,
3996 SourceLocation tokenBegin, CXCursor &outputCursor)
3997 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3998 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3999 VisitedObjCPropertyImplDecl = false;
4000 }
4001};
4002
4003static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4004 CXCursor parent,
4005 CXClientData client_data) {
4006 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4007 CXCursor *BestCursor = &Data->BestCursor;
4008
4009 // If we point inside a macro argument we should provide info of what the
4010 // token is so use the actual cursor, don't replace it with a macro expansion
4011 // cursor.
4012 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4013 return CXChildVisit_Recurse;
4014
4015 if (clang_isDeclaration(cursor.kind)) {
4016 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004017 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4019 if (MD->isImplicit())
4020 return CXChildVisit_Break;
4021
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004022 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4024 // Check that when we have multiple @class references in the same line,
4025 // that later ones do not override the previous ones.
4026 // If we have:
4027 // @class Foo, Bar;
4028 // source ranges for both start at '@', so 'Bar' will end up overriding
4029 // 'Foo' even though the cursor location was at 'Foo'.
4030 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4031 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004032 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4034 if (PrevID != ID &&
4035 !PrevID->isThisDeclarationADefinition() &&
4036 !ID->isThisDeclarationADefinition())
4037 return CXChildVisit_Break;
4038 }
4039
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004040 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4042 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4043 // Check that when we have multiple declarators in the same line,
4044 // that later ones do not override the previous ones.
4045 // If we have:
4046 // int Foo, Bar;
4047 // source ranges for both start at 'int', so 'Bar' will end up overriding
4048 // 'Foo' even though the cursor location was at 'Foo'.
4049 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4050 return CXChildVisit_Break;
4051 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4052
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004053 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4055 (void)PropImp;
4056 // Check that when we have multiple @synthesize in the same line,
4057 // that later ones do not override the previous ones.
4058 // If we have:
4059 // @synthesize Foo, Bar;
4060 // source ranges for both start at '@', so 'Bar' will end up overriding
4061 // 'Foo' even though the cursor location was at 'Foo'.
4062 if (Data->VisitedObjCPropertyImplDecl)
4063 return CXChildVisit_Break;
4064 Data->VisitedObjCPropertyImplDecl = true;
4065 }
4066 }
4067
4068 if (clang_isExpression(cursor.kind) &&
4069 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004070 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 // Avoid having the cursor of an expression replace the declaration cursor
4072 // when the expression source range overlaps the declaration range.
4073 // This can happen for C++ constructor expressions whose range generally
4074 // include the variable declaration, e.g.:
4075 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4076 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4077 D->getLocation() == Data->TokenBeginLoc)
4078 return CXChildVisit_Break;
4079 }
4080 }
4081
4082 // If our current best cursor is the construction of a temporary object,
4083 // don't replace that cursor with a type reference, because we want
4084 // clang_getCursor() to point at the constructor.
4085 if (clang_isExpression(BestCursor->kind) &&
4086 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4087 cursor.kind == CXCursor_TypeRef) {
4088 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4089 // as having the actual point on the type reference.
4090 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4091 return CXChildVisit_Recurse;
4092 }
4093
4094 *BestCursor = cursor;
4095 return CXChildVisit_Recurse;
4096}
4097
4098CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004099 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004100 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004102 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004103
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004104 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4106
4107 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4108 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4109
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004110 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 CXFile SearchFile;
4112 unsigned SearchLine, SearchColumn;
4113 CXFile ResultFile;
4114 unsigned ResultLine, ResultColumn;
4115 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4116 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4117 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004118
4119 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4120 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004121 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004122 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 SearchFileName = clang_getFileName(SearchFile);
4124 ResultFileName = clang_getFileName(ResultFile);
4125 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4126 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004127 *Log << llvm::format("(%s:%d:%d) = %s",
4128 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4129 clang_getCString(KindSpelling))
4130 << llvm::format("(%s:%d:%d):%s%s",
4131 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4132 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 clang_disposeString(SearchFileName);
4134 clang_disposeString(ResultFileName);
4135 clang_disposeString(KindSpelling);
4136 clang_disposeString(USR);
4137
4138 CXCursor Definition = clang_getCursorDefinition(Result);
4139 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4140 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4141 CXString DefinitionKindSpelling
4142 = clang_getCursorKindSpelling(Definition.kind);
4143 CXFile DefinitionFile;
4144 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004145 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004146 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004148 *Log << llvm::format(" -> %s(%s:%d:%d)",
4149 clang_getCString(DefinitionKindSpelling),
4150 clang_getCString(DefinitionFileName),
4151 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 clang_disposeString(DefinitionFileName);
4153 clang_disposeString(DefinitionKindSpelling);
4154 }
4155 }
4156
4157 return Result;
4158}
4159
4160CXCursor clang_getNullCursor(void) {
4161 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4162}
4163
4164unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004165 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4166 // can't set consistently. For example, when visiting a DeclStmt we will set
4167 // it but we don't set it on the result of clang_getCursorDefinition for
4168 // a reference of the same declaration.
4169 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4170 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4171 // to provide that kind of info.
4172 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004173 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004174 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004175 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004176
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 return X == Y;
4178}
4179
4180unsigned clang_hashCursor(CXCursor C) {
4181 unsigned Index = 0;
4182 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4183 Index = 1;
4184
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004185 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 std::make_pair(C.kind, C.data[Index]));
4187}
4188
4189unsigned clang_isInvalid(enum CXCursorKind K) {
4190 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4191}
4192
4193unsigned clang_isDeclaration(enum CXCursorKind K) {
4194 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4195 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4196}
4197
4198unsigned clang_isReference(enum CXCursorKind K) {
4199 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4200}
4201
4202unsigned clang_isExpression(enum CXCursorKind K) {
4203 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4204}
4205
4206unsigned clang_isStatement(enum CXCursorKind K) {
4207 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4208}
4209
4210unsigned clang_isAttribute(enum CXCursorKind K) {
4211 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4212}
4213
4214unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4215 return K == CXCursor_TranslationUnit;
4216}
4217
4218unsigned clang_isPreprocessing(enum CXCursorKind K) {
4219 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4220}
4221
4222unsigned clang_isUnexposed(enum CXCursorKind K) {
4223 switch (K) {
4224 case CXCursor_UnexposedDecl:
4225 case CXCursor_UnexposedExpr:
4226 case CXCursor_UnexposedStmt:
4227 case CXCursor_UnexposedAttr:
4228 return true;
4229 default:
4230 return false;
4231 }
4232}
4233
4234CXCursorKind clang_getCursorKind(CXCursor C) {
4235 return C.kind;
4236}
4237
4238CXSourceLocation clang_getCursorLocation(CXCursor C) {
4239 if (clang_isReference(C.kind)) {
4240 switch (C.kind) {
4241 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004242 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 = getCursorObjCSuperClassRef(C);
4244 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4245 }
4246
4247 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004248 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 = getCursorObjCProtocolRef(C);
4250 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4251 }
4252
4253 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004254 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 = getCursorObjCClassRef(C);
4256 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4257 }
4258
4259 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004260 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4262 }
4263
4264 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004265 std::pair<const TemplateDecl *, SourceLocation> P =
4266 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4268 }
4269
4270 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004271 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4273 }
4274
4275 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004276 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4278 }
4279
4280 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004281 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4283 }
4284
4285 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004286 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 if (!BaseSpec)
4288 return clang_getNullLocation();
4289
4290 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4291 return cxloc::translateSourceLocation(getCursorContext(C),
4292 TSInfo->getTypeLoc().getBeginLoc());
4293
4294 return cxloc::translateSourceLocation(getCursorContext(C),
4295 BaseSpec->getLocStart());
4296 }
4297
4298 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004299 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4301 }
4302
4303 case CXCursor_OverloadedDeclRef:
4304 return cxloc::translateSourceLocation(getCursorContext(C),
4305 getCursorOverloadedDeclRef(C).second);
4306
4307 default:
4308 // FIXME: Need a way to enumerate all non-reference cases.
4309 llvm_unreachable("Missed a reference kind");
4310 }
4311 }
4312
4313 if (clang_isExpression(C.kind))
4314 return cxloc::translateSourceLocation(getCursorContext(C),
4315 getLocationFromExpr(getCursorExpr(C)));
4316
4317 if (clang_isStatement(C.kind))
4318 return cxloc::translateSourceLocation(getCursorContext(C),
4319 getCursorStmt(C)->getLocStart());
4320
4321 if (C.kind == CXCursor_PreprocessingDirective) {
4322 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4323 return cxloc::translateSourceLocation(getCursorContext(C), L);
4324 }
4325
4326 if (C.kind == CXCursor_MacroExpansion) {
4327 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004328 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004329 return cxloc::translateSourceLocation(getCursorContext(C), L);
4330 }
4331
4332 if (C.kind == CXCursor_MacroDefinition) {
4333 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4334 return cxloc::translateSourceLocation(getCursorContext(C), L);
4335 }
4336
4337 if (C.kind == CXCursor_InclusionDirective) {
4338 SourceLocation L
4339 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4340 return cxloc::translateSourceLocation(getCursorContext(C), L);
4341 }
4342
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004343 if (clang_isAttribute(C.kind)) {
4344 SourceLocation L
4345 = cxcursor::getCursorAttr(C)->getLocation();
4346 return cxloc::translateSourceLocation(getCursorContext(C), L);
4347 }
4348
Guy Benyei11169dd2012-12-18 14:30:41 +00004349 if (!clang_isDeclaration(C.kind))
4350 return clang_getNullLocation();
4351
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004352 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004353 if (!D)
4354 return clang_getNullLocation();
4355
4356 SourceLocation Loc = D->getLocation();
4357 // FIXME: Multiple variables declared in a single declaration
4358 // currently lack the information needed to correctly determine their
4359 // ranges when accounting for the type-specifier. We use context
4360 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4361 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004362 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 if (!cxcursor::isFirstInDeclGroup(C))
4364 Loc = VD->getLocation();
4365 }
4366
4367 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004368 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004369 Loc = MD->getSelectorStartLoc();
4370
4371 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4372}
4373
4374} // end extern "C"
4375
4376CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4377 assert(TU);
4378
4379 // Guard against an invalid SourceLocation, or we may assert in one
4380 // of the following calls.
4381 if (SLoc.isInvalid())
4382 return clang_getNullCursor();
4383
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004384 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004385
4386 // Translate the given source location to make it point at the beginning of
4387 // the token under the cursor.
4388 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4389 CXXUnit->getASTContext().getLangOpts());
4390
4391 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4392 if (SLoc.isValid()) {
4393 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4394 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4395 /*VisitPreprocessorLast=*/true,
4396 /*VisitIncludedEntities=*/false,
4397 SourceLocation(SLoc));
4398 CursorVis.visitFileRegion();
4399 }
4400
4401 return Result;
4402}
4403
4404static SourceRange getRawCursorExtent(CXCursor C) {
4405 if (clang_isReference(C.kind)) {
4406 switch (C.kind) {
4407 case CXCursor_ObjCSuperClassRef:
4408 return getCursorObjCSuperClassRef(C).second;
4409
4410 case CXCursor_ObjCProtocolRef:
4411 return getCursorObjCProtocolRef(C).second;
4412
4413 case CXCursor_ObjCClassRef:
4414 return getCursorObjCClassRef(C).second;
4415
4416 case CXCursor_TypeRef:
4417 return getCursorTypeRef(C).second;
4418
4419 case CXCursor_TemplateRef:
4420 return getCursorTemplateRef(C).second;
4421
4422 case CXCursor_NamespaceRef:
4423 return getCursorNamespaceRef(C).second;
4424
4425 case CXCursor_MemberRef:
4426 return getCursorMemberRef(C).second;
4427
4428 case CXCursor_CXXBaseSpecifier:
4429 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4430
4431 case CXCursor_LabelRef:
4432 return getCursorLabelRef(C).second;
4433
4434 case CXCursor_OverloadedDeclRef:
4435 return getCursorOverloadedDeclRef(C).second;
4436
4437 case CXCursor_VariableRef:
4438 return getCursorVariableRef(C).second;
4439
4440 default:
4441 // FIXME: Need a way to enumerate all non-reference cases.
4442 llvm_unreachable("Missed a reference kind");
4443 }
4444 }
4445
4446 if (clang_isExpression(C.kind))
4447 return getCursorExpr(C)->getSourceRange();
4448
4449 if (clang_isStatement(C.kind))
4450 return getCursorStmt(C)->getSourceRange();
4451
4452 if (clang_isAttribute(C.kind))
4453 return getCursorAttr(C)->getRange();
4454
4455 if (C.kind == CXCursor_PreprocessingDirective)
4456 return cxcursor::getCursorPreprocessingDirective(C);
4457
4458 if (C.kind == CXCursor_MacroExpansion) {
4459 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004460 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004461 return TU->mapRangeFromPreamble(Range);
4462 }
4463
4464 if (C.kind == CXCursor_MacroDefinition) {
4465 ASTUnit *TU = getCursorASTUnit(C);
4466 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4467 return TU->mapRangeFromPreamble(Range);
4468 }
4469
4470 if (C.kind == CXCursor_InclusionDirective) {
4471 ASTUnit *TU = getCursorASTUnit(C);
4472 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4473 return TU->mapRangeFromPreamble(Range);
4474 }
4475
4476 if (C.kind == CXCursor_TranslationUnit) {
4477 ASTUnit *TU = getCursorASTUnit(C);
4478 FileID MainID = TU->getSourceManager().getMainFileID();
4479 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4480 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4481 return SourceRange(Start, End);
4482 }
4483
4484 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004485 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 if (!D)
4487 return SourceRange();
4488
4489 SourceRange R = D->getSourceRange();
4490 // FIXME: Multiple variables declared in a single declaration
4491 // currently lack the information needed to correctly determine their
4492 // ranges when accounting for the type-specifier. We use context
4493 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4494 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004495 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 if (!cxcursor::isFirstInDeclGroup(C))
4497 R.setBegin(VD->getLocation());
4498 }
4499 return R;
4500 }
4501 return SourceRange();
4502}
4503
4504/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4505/// the decl-specifier-seq for declarations.
4506static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4507 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004508 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 if (!D)
4510 return SourceRange();
4511
4512 SourceRange R = D->getSourceRange();
4513
4514 // Adjust the start of the location for declarations preceded by
4515 // declaration specifiers.
4516 SourceLocation StartLoc;
4517 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4518 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4519 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004520 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4522 StartLoc = TI->getTypeLoc().getLocStart();
4523 }
4524
4525 if (StartLoc.isValid() && R.getBegin().isValid() &&
4526 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4527 R.setBegin(StartLoc);
4528
4529 // FIXME: Multiple variables declared in a single declaration
4530 // currently lack the information needed to correctly determine their
4531 // ranges when accounting for the type-specifier. We use context
4532 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4533 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004534 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 if (!cxcursor::isFirstInDeclGroup(C))
4536 R.setBegin(VD->getLocation());
4537 }
4538
4539 return R;
4540 }
4541
4542 return getRawCursorExtent(C);
4543}
4544
4545extern "C" {
4546
4547CXSourceRange clang_getCursorExtent(CXCursor C) {
4548 SourceRange R = getRawCursorExtent(C);
4549 if (R.isInvalid())
4550 return clang_getNullRange();
4551
4552 return cxloc::translateSourceRange(getCursorContext(C), R);
4553}
4554
4555CXCursor clang_getCursorReferenced(CXCursor C) {
4556 if (clang_isInvalid(C.kind))
4557 return clang_getNullCursor();
4558
4559 CXTranslationUnit tu = getCursorTU(C);
4560 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004561 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 if (!D)
4563 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004564 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004566 if (const ObjCPropertyImplDecl *PropImpl =
4567 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4569 return MakeCXCursor(Property, tu);
4570
4571 return C;
4572 }
4573
4574 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004575 const Expr *E = getCursorExpr(C);
4576 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 if (D) {
4578 CXCursor declCursor = MakeCXCursor(D, tu);
4579 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4580 declCursor);
4581 return declCursor;
4582 }
4583
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004584 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 return MakeCursorOverloadedDeclRef(Ovl, tu);
4586
4587 return clang_getNullCursor();
4588 }
4589
4590 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004591 const Stmt *S = getCursorStmt(C);
4592 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 if (LabelDecl *label = Goto->getLabel())
4594 if (LabelStmt *labelS = label->getStmt())
4595 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4596
4597 return clang_getNullCursor();
4598 }
4599
4600 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004601 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004602 return MakeMacroDefinitionCursor(Def, tu);
4603 }
4604
4605 if (!clang_isReference(C.kind))
4606 return clang_getNullCursor();
4607
4608 switch (C.kind) {
4609 case CXCursor_ObjCSuperClassRef:
4610 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4611
4612 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004613 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4614 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 return MakeCXCursor(Def, tu);
4616
4617 return MakeCXCursor(Prot, tu);
4618 }
4619
4620 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004621 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4622 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 return MakeCXCursor(Def, tu);
4624
4625 return MakeCXCursor(Class, tu);
4626 }
4627
4628 case CXCursor_TypeRef:
4629 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4630
4631 case CXCursor_TemplateRef:
4632 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4633
4634 case CXCursor_NamespaceRef:
4635 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4636
4637 case CXCursor_MemberRef:
4638 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4639
4640 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004641 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004642 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4643 tu ));
4644 }
4645
4646 case CXCursor_LabelRef:
4647 // FIXME: We end up faking the "parent" declaration here because we
4648 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004649 return MakeCXCursor(getCursorLabelRef(C).first,
4650 cxtu::getASTUnit(tu)->getASTContext()
4651 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 tu);
4653
4654 case CXCursor_OverloadedDeclRef:
4655 return C;
4656
4657 case CXCursor_VariableRef:
4658 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4659
4660 default:
4661 // We would prefer to enumerate all non-reference cursor kinds here.
4662 llvm_unreachable("Unhandled reference cursor kind");
4663 }
4664}
4665
4666CXCursor clang_getCursorDefinition(CXCursor C) {
4667 if (clang_isInvalid(C.kind))
4668 return clang_getNullCursor();
4669
4670 CXTranslationUnit TU = getCursorTU(C);
4671
4672 bool WasReference = false;
4673 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4674 C = clang_getCursorReferenced(C);
4675 WasReference = true;
4676 }
4677
4678 if (C.kind == CXCursor_MacroExpansion)
4679 return clang_getCursorReferenced(C);
4680
4681 if (!clang_isDeclaration(C.kind))
4682 return clang_getNullCursor();
4683
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004684 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 if (!D)
4686 return clang_getNullCursor();
4687
4688 switch (D->getKind()) {
4689 // Declaration kinds that don't really separate the notions of
4690 // declaration and definition.
4691 case Decl::Namespace:
4692 case Decl::Typedef:
4693 case Decl::TypeAlias:
4694 case Decl::TypeAliasTemplate:
4695 case Decl::TemplateTypeParm:
4696 case Decl::EnumConstant:
4697 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004698 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 case Decl::IndirectField:
4700 case Decl::ObjCIvar:
4701 case Decl::ObjCAtDefsField:
4702 case Decl::ImplicitParam:
4703 case Decl::ParmVar:
4704 case Decl::NonTypeTemplateParm:
4705 case Decl::TemplateTemplateParm:
4706 case Decl::ObjCCategoryImpl:
4707 case Decl::ObjCImplementation:
4708 case Decl::AccessSpec:
4709 case Decl::LinkageSpec:
4710 case Decl::ObjCPropertyImpl:
4711 case Decl::FileScopeAsm:
4712 case Decl::StaticAssert:
4713 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004714 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 case Decl::Label: // FIXME: Is this right??
4716 case Decl::ClassScopeFunctionSpecialization:
4717 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004718 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 return C;
4720
4721 // Declaration kinds that don't make any sense here, but are
4722 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004723 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004724 case Decl::TranslationUnit:
4725 break;
4726
4727 // Declaration kinds for which the definition is not resolvable.
4728 case Decl::UnresolvedUsingTypename:
4729 case Decl::UnresolvedUsingValue:
4730 break;
4731
4732 case Decl::UsingDirective:
4733 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4734 TU);
4735
4736 case Decl::NamespaceAlias:
4737 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4738
4739 case Decl::Enum:
4740 case Decl::Record:
4741 case Decl::CXXRecord:
4742 case Decl::ClassTemplateSpecialization:
4743 case Decl::ClassTemplatePartialSpecialization:
4744 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4745 return MakeCXCursor(Def, TU);
4746 return clang_getNullCursor();
4747
4748 case Decl::Function:
4749 case Decl::CXXMethod:
4750 case Decl::CXXConstructor:
4751 case Decl::CXXDestructor:
4752 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004753 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004755 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 return clang_getNullCursor();
4757 }
4758
Larisse Voufo39a1e502013-08-06 01:03:05 +00004759 case Decl::Var:
4760 case Decl::VarTemplateSpecialization:
4761 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004762 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004763 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 return MakeCXCursor(Def, TU);
4765 return clang_getNullCursor();
4766 }
4767
4768 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004769 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4771 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4772 return clang_getNullCursor();
4773 }
4774
4775 case Decl::ClassTemplate: {
4776 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4777 ->getDefinition())
4778 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4779 TU);
4780 return clang_getNullCursor();
4781 }
4782
Larisse Voufo39a1e502013-08-06 01:03:05 +00004783 case Decl::VarTemplate: {
4784 if (VarDecl *Def =
4785 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4786 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4787 return clang_getNullCursor();
4788 }
4789
Guy Benyei11169dd2012-12-18 14:30:41 +00004790 case Decl::Using:
4791 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4792 D->getLocation(), TU);
4793
4794 case Decl::UsingShadow:
4795 return clang_getCursorDefinition(
4796 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4797 TU));
4798
4799 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004800 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 if (Method->isThisDeclarationADefinition())
4802 return C;
4803
4804 // Dig out the method definition in the associated
4805 // @implementation, if we have it.
4806 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004807 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004808 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4809 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4810 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4811 Method->isInstanceMethod()))
4812 if (Def->isThisDeclarationADefinition())
4813 return MakeCXCursor(Def, TU);
4814
4815 return clang_getNullCursor();
4816 }
4817
4818 case Decl::ObjCCategory:
4819 if (ObjCCategoryImplDecl *Impl
4820 = cast<ObjCCategoryDecl>(D)->getImplementation())
4821 return MakeCXCursor(Impl, TU);
4822 return clang_getNullCursor();
4823
4824 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004825 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004826 return MakeCXCursor(Def, TU);
4827 return clang_getNullCursor();
4828
4829 case Decl::ObjCInterface: {
4830 // There are two notions of a "definition" for an Objective-C
4831 // class: the interface and its implementation. When we resolved a
4832 // reference to an Objective-C class, produce the @interface as
4833 // the definition; when we were provided with the interface,
4834 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004835 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004836 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004837 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 return MakeCXCursor(Def, TU);
4839 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4840 return MakeCXCursor(Impl, TU);
4841 return clang_getNullCursor();
4842 }
4843
4844 case Decl::ObjCProperty:
4845 // FIXME: We don't really know where to find the
4846 // ObjCPropertyImplDecls that implement this property.
4847 return clang_getNullCursor();
4848
4849 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004850 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004852 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 return MakeCXCursor(Def, TU);
4854
4855 return clang_getNullCursor();
4856
4857 case Decl::Friend:
4858 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4859 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4860 return clang_getNullCursor();
4861
4862 case Decl::FriendTemplate:
4863 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4864 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4865 return clang_getNullCursor();
4866 }
4867
4868 return clang_getNullCursor();
4869}
4870
4871unsigned clang_isCursorDefinition(CXCursor C) {
4872 if (!clang_isDeclaration(C.kind))
4873 return 0;
4874
4875 return clang_getCursorDefinition(C) == C;
4876}
4877
4878CXCursor clang_getCanonicalCursor(CXCursor C) {
4879 if (!clang_isDeclaration(C.kind))
4880 return C;
4881
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 if (const Decl *D = getCursorDecl(C)) {
4883 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4885 return MakeCXCursor(CatD, getCursorTU(C));
4886
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004887 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4888 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004889 return MakeCXCursor(IFD, getCursorTU(C));
4890
4891 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4892 }
4893
4894 return C;
4895}
4896
4897int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4898 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4899}
4900
4901unsigned clang_getNumOverloadedDecls(CXCursor C) {
4902 if (C.kind != CXCursor_OverloadedDeclRef)
4903 return 0;
4904
4905 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004906 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004907 return E->getNumDecls();
4908
4909 if (OverloadedTemplateStorage *S
4910 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4911 return S->size();
4912
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004913 const Decl *D = Storage.get<const Decl *>();
4914 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 return Using->shadow_size();
4916
4917 return 0;
4918}
4919
4920CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4921 if (cursor.kind != CXCursor_OverloadedDeclRef)
4922 return clang_getNullCursor();
4923
4924 if (index >= clang_getNumOverloadedDecls(cursor))
4925 return clang_getNullCursor();
4926
4927 CXTranslationUnit TU = getCursorTU(cursor);
4928 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004929 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004930 return MakeCXCursor(E->decls_begin()[index], TU);
4931
4932 if (OverloadedTemplateStorage *S
4933 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4934 return MakeCXCursor(S->begin()[index], TU);
4935
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004936 const Decl *D = Storage.get<const Decl *>();
4937 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004938 // FIXME: This is, unfortunately, linear time.
4939 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4940 std::advance(Pos, index);
4941 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4942 }
4943
4944 return clang_getNullCursor();
4945}
4946
4947void clang_getDefinitionSpellingAndExtent(CXCursor C,
4948 const char **startBuf,
4949 const char **endBuf,
4950 unsigned *startLine,
4951 unsigned *startColumn,
4952 unsigned *endLine,
4953 unsigned *endColumn) {
4954 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004955 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004956 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4957
4958 SourceManager &SM = FD->getASTContext().getSourceManager();
4959 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4960 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4961 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4962 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4963 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4964 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4965}
4966
4967
4968CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4969 unsigned PieceIndex) {
4970 RefNamePieces Pieces;
4971
4972 switch (C.kind) {
4973 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004974 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004975 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4976 E->getQualifierLoc().getSourceRange());
4977 break;
4978
4979 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004980 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004981 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4982 E->getQualifierLoc().getSourceRange(),
4983 E->getOptionalExplicitTemplateArgs());
4984 break;
4985
4986 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004987 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004988 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004989 const Expr *Callee = OCE->getCallee();
4990 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 Callee = ICE->getSubExpr();
4992
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004993 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4995 DRE->getQualifierLoc().getSourceRange());
4996 }
4997 break;
4998
4999 default:
5000 break;
5001 }
5002
5003 if (Pieces.empty()) {
5004 if (PieceIndex == 0)
5005 return clang_getCursorExtent(C);
5006 } else if (PieceIndex < Pieces.size()) {
5007 SourceRange R = Pieces[PieceIndex];
5008 if (R.isValid())
5009 return cxloc::translateSourceRange(getCursorContext(C), R);
5010 }
5011
5012 return clang_getNullRange();
5013}
5014
5015void clang_enableStackTraces(void) {
5016 llvm::sys::PrintStackTraceOnErrorSignal();
5017}
5018
5019void clang_executeOnThread(void (*fn)(void*), void *user_data,
5020 unsigned stack_size) {
5021 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5022}
5023
5024} // end: extern "C"
5025
5026//===----------------------------------------------------------------------===//
5027// Token-based Operations.
5028//===----------------------------------------------------------------------===//
5029
5030/* CXToken layout:
5031 * int_data[0]: a CXTokenKind
5032 * int_data[1]: starting token location
5033 * int_data[2]: token length
5034 * int_data[3]: reserved
5035 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5036 * otherwise unused.
5037 */
5038extern "C" {
5039
5040CXTokenKind clang_getTokenKind(CXToken CXTok) {
5041 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5042}
5043
5044CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5045 switch (clang_getTokenKind(CXTok)) {
5046 case CXToken_Identifier:
5047 case CXToken_Keyword:
5048 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005049 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 ->getNameStart());
5051
5052 case CXToken_Literal: {
5053 // We have stashed the starting pointer in the ptr_data field. Use it.
5054 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005055 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 }
5057
5058 case CXToken_Punctuation:
5059 case CXToken_Comment:
5060 break;
5061 }
5062
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005063 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005064 LOG_BAD_TU(TU);
5065 return cxstring::createEmpty();
5066 }
5067
Guy Benyei11169dd2012-12-18 14:30:41 +00005068 // We have to find the starting buffer pointer the hard way, by
5069 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005070 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005071 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005072 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005073
5074 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5075 std::pair<FileID, unsigned> LocInfo
5076 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5077 bool Invalid = false;
5078 StringRef Buffer
5079 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5080 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005081 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005082
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005083 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005084}
5085
5086CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005087 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005088 LOG_BAD_TU(TU);
5089 return clang_getNullLocation();
5090 }
5091
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005092 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005093 if (!CXXUnit)
5094 return clang_getNullLocation();
5095
5096 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5097 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5098}
5099
5100CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005101 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005102 LOG_BAD_TU(TU);
5103 return clang_getNullRange();
5104 }
5105
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005106 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005107 if (!CXXUnit)
5108 return clang_getNullRange();
5109
5110 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5111 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5112}
5113
5114static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5115 SmallVectorImpl<CXToken> &CXTokens) {
5116 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5117 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005118 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005120 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005121
5122 // Cannot tokenize across files.
5123 if (BeginLocInfo.first != EndLocInfo.first)
5124 return;
5125
5126 // Create a lexer
5127 bool Invalid = false;
5128 StringRef Buffer
5129 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5130 if (Invalid)
5131 return;
5132
5133 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5134 CXXUnit->getASTContext().getLangOpts(),
5135 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5136 Lex.SetCommentRetentionState(true);
5137
5138 // Lex tokens until we hit the end of the range.
5139 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5140 Token Tok;
5141 bool previousWasAt = false;
5142 do {
5143 // Lex the next token
5144 Lex.LexFromRawLexer(Tok);
5145 if (Tok.is(tok::eof))
5146 break;
5147
5148 // Initialize the CXToken.
5149 CXToken CXTok;
5150
5151 // - Common fields
5152 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5153 CXTok.int_data[2] = Tok.getLength();
5154 CXTok.int_data[3] = 0;
5155
5156 // - Kind-specific fields
5157 if (Tok.isLiteral()) {
5158 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005159 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 } else if (Tok.is(tok::raw_identifier)) {
5161 // Lookup the identifier to determine whether we have a keyword.
5162 IdentifierInfo *II
5163 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5164
5165 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5166 CXTok.int_data[0] = CXToken_Keyword;
5167 }
5168 else {
5169 CXTok.int_data[0] = Tok.is(tok::identifier)
5170 ? CXToken_Identifier
5171 : CXToken_Keyword;
5172 }
5173 CXTok.ptr_data = II;
5174 } else if (Tok.is(tok::comment)) {
5175 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005176 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 } else {
5178 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005179 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 }
5181 CXTokens.push_back(CXTok);
5182 previousWasAt = Tok.is(tok::at);
5183 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5184}
5185
5186void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5187 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005188 LOG_FUNC_SECTION {
5189 *Log << TU << ' ' << Range;
5190 }
5191
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005193 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 if (NumTokens)
5195 *NumTokens = 0;
5196
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005197 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005198 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005199 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005200 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005201
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005202 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 if (!CXXUnit || !Tokens || !NumTokens)
5204 return;
5205
5206 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5207
5208 SourceRange R = cxloc::translateCXSourceRange(Range);
5209 if (R.isInvalid())
5210 return;
5211
5212 SmallVector<CXToken, 32> CXTokens;
5213 getTokens(CXXUnit, R, CXTokens);
5214
5215 if (CXTokens.empty())
5216 return;
5217
5218 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5219 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5220 *NumTokens = CXTokens.size();
5221}
5222
5223void clang_disposeTokens(CXTranslationUnit TU,
5224 CXToken *Tokens, unsigned NumTokens) {
5225 free(Tokens);
5226}
5227
5228} // end: extern "C"
5229
5230//===----------------------------------------------------------------------===//
5231// Token annotation APIs.
5232//===----------------------------------------------------------------------===//
5233
Guy Benyei11169dd2012-12-18 14:30:41 +00005234static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5235 CXCursor parent,
5236 CXClientData client_data);
5237static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5238 CXClientData client_data);
5239
5240namespace {
5241class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 CXToken *Tokens;
5243 CXCursor *Cursors;
5244 unsigned NumTokens;
5245 unsigned TokIdx;
5246 unsigned PreprocessingTokIdx;
5247 CursorVisitor AnnotateVis;
5248 SourceManager &SrcMgr;
5249 bool HasContextSensitiveKeywords;
5250
5251 struct PostChildrenInfo {
5252 CXCursor Cursor;
5253 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005254 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 unsigned BeforeChildrenTokenIdx;
5256 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005257 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005258
5259 CXToken &getTok(unsigned Idx) {
5260 assert(Idx < NumTokens);
5261 return Tokens[Idx];
5262 }
5263 const CXToken &getTok(unsigned Idx) const {
5264 assert(Idx < NumTokens);
5265 return Tokens[Idx];
5266 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005267 bool MoreTokens() const { return TokIdx < NumTokens; }
5268 unsigned NextToken() const { return TokIdx; }
5269 void AdvanceToken() { ++TokIdx; }
5270 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005271 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 }
5273 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005274 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 }
5276 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005277 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 }
5279
5280 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005281 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 SourceRange);
5283
5284public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005285 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005286 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005287 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005289 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 AnnotateTokensVisitor, this,
5291 /*VisitPreprocessorLast=*/true,
5292 /*VisitIncludedEntities=*/false,
5293 RegionOfInterest,
5294 /*VisitDeclsOnly=*/false,
5295 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005296 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005297 HasContextSensitiveKeywords(false) { }
5298
5299 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5300 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5301 bool postVisitChildren(CXCursor cursor);
5302 void AnnotateTokens();
5303
5304 /// \brief Determine whether the annotator saw any cursors that have
5305 /// context-sensitive keywords.
5306 bool hasContextSensitiveKeywords() const {
5307 return HasContextSensitiveKeywords;
5308 }
5309
5310 ~AnnotateTokensWorker() {
5311 assert(PostChildrenInfos.empty());
5312 }
5313};
5314}
5315
5316void AnnotateTokensWorker::AnnotateTokens() {
5317 // Walk the AST within the region of interest, annotating tokens
5318 // along the way.
5319 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005320}
Guy Benyei11169dd2012-12-18 14:30:41 +00005321
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005322static inline void updateCursorAnnotation(CXCursor &Cursor,
5323 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005324 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005325 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005326 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005327}
5328
5329/// \brief It annotates and advances tokens with a cursor until the comparison
5330//// between the cursor location and the source range is the same as
5331/// \arg compResult.
5332///
5333/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5334/// Pass RangeOverlap to annotate tokens inside a range.
5335void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5336 RangeComparisonResult compResult,
5337 SourceRange range) {
5338 while (MoreTokens()) {
5339 const unsigned I = NextToken();
5340 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005341 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5342 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005343
5344 SourceLocation TokLoc = GetTokenLoc(I);
5345 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005346 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 AdvanceToken();
5348 continue;
5349 }
5350 break;
5351 }
5352}
5353
5354/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005355/// \returns true if it advanced beyond all macro tokens, false otherwise.
5356bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 CXCursor updateC,
5358 RangeComparisonResult compResult,
5359 SourceRange range) {
5360 assert(MoreTokens());
5361 assert(isFunctionMacroToken(NextToken()) &&
5362 "Should be called only for macro arg tokens");
5363
5364 // This works differently than annotateAndAdvanceTokens; because expanded
5365 // macro arguments can have arbitrary translation-unit source order, we do not
5366 // advance the token index one by one until a token fails the range test.
5367 // We only advance once past all of the macro arg tokens if all of them
5368 // pass the range test. If one of them fails we keep the token index pointing
5369 // at the start of the macro arg tokens so that the failing token will be
5370 // annotated by a subsequent annotation try.
5371
5372 bool atLeastOneCompFail = false;
5373
5374 unsigned I = NextToken();
5375 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5376 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5377 if (TokLoc.isFileID())
5378 continue; // not macro arg token, it's parens or comma.
5379 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5380 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5381 Cursors[I] = updateC;
5382 } else
5383 atLeastOneCompFail = true;
5384 }
5385
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005386 if (atLeastOneCompFail)
5387 return false;
5388
5389 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5390 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005391}
5392
5393enum CXChildVisitResult
5394AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 SourceRange cursorRange = getRawCursorExtent(cursor);
5396 if (cursorRange.isInvalid())
5397 return CXChildVisit_Recurse;
5398
5399 if (!HasContextSensitiveKeywords) {
5400 // Objective-C properties can have context-sensitive keywords.
5401 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005402 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5404 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5405 }
5406 // Objective-C methods can have context-sensitive keywords.
5407 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5408 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005409 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005410 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5411 if (Method->getObjCDeclQualifier())
5412 HasContextSensitiveKeywords = true;
5413 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005414 for (const auto *P : Method->params()) {
5415 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005416 HasContextSensitiveKeywords = true;
5417 break;
5418 }
5419 }
5420 }
5421 }
5422 }
5423 // C++ methods can have context-sensitive keywords.
5424 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005425 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5427 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5428 HasContextSensitiveKeywords = true;
5429 }
5430 }
5431 // C++ classes can have context-sensitive keywords.
5432 else if (cursor.kind == CXCursor_StructDecl ||
5433 cursor.kind == CXCursor_ClassDecl ||
5434 cursor.kind == CXCursor_ClassTemplate ||
5435 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005436 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 if (D->hasAttr<FinalAttr>())
5438 HasContextSensitiveKeywords = true;
5439 }
5440 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005441
5442 // Don't override a property annotation with its getter/setter method.
5443 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5444 parent.kind == CXCursor_ObjCPropertyDecl)
5445 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005446
5447 if (clang_isPreprocessing(cursor.kind)) {
5448 // Items in the preprocessing record are kept separate from items in
5449 // declarations, so we keep a separate token index.
5450 unsigned SavedTokIdx = TokIdx;
5451 TokIdx = PreprocessingTokIdx;
5452
5453 // Skip tokens up until we catch up to the beginning of the preprocessing
5454 // entry.
5455 while (MoreTokens()) {
5456 const unsigned I = NextToken();
5457 SourceLocation TokLoc = GetTokenLoc(I);
5458 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5459 case RangeBefore:
5460 AdvanceToken();
5461 continue;
5462 case RangeAfter:
5463 case RangeOverlap:
5464 break;
5465 }
5466 break;
5467 }
5468
5469 // Look at all of the tokens within this range.
5470 while (MoreTokens()) {
5471 const unsigned I = NextToken();
5472 SourceLocation TokLoc = GetTokenLoc(I);
5473 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5474 case RangeBefore:
5475 llvm_unreachable("Infeasible");
5476 case RangeAfter:
5477 break;
5478 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005479 // For macro expansions, just note where the beginning of the macro
5480 // expansion occurs.
5481 if (cursor.kind == CXCursor_MacroExpansion) {
5482 if (TokLoc == cursorRange.getBegin())
5483 Cursors[I] = cursor;
5484 AdvanceToken();
5485 break;
5486 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005487 // We may have already annotated macro names inside macro definitions.
5488 if (Cursors[I].kind != CXCursor_MacroExpansion)
5489 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005490 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 continue;
5492 }
5493 break;
5494 }
5495
5496 // Save the preprocessing token index; restore the non-preprocessing
5497 // token index.
5498 PreprocessingTokIdx = TokIdx;
5499 TokIdx = SavedTokIdx;
5500 return CXChildVisit_Recurse;
5501 }
5502
5503 if (cursorRange.isInvalid())
5504 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005505
5506 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005507 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005508 const enum CXCursorKind K = clang_getCursorKind(parent);
5509 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005510 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5511 // Attributes are annotated out-of-order, skip tokens until we reach it.
5512 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005513 ? clang_getNullCursor() : parent;
5514
5515 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5516
5517 // Avoid having the cursor of an expression "overwrite" the annotation of the
5518 // variable declaration that it belongs to.
5519 // This can happen for C++ constructor expressions whose range generally
5520 // include the variable declaration, e.g.:
5521 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005522 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005523 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005524 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 const unsigned I = NextToken();
5526 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5527 E->getLocStart() == D->getLocation() &&
5528 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005529 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005530 AdvanceToken();
5531 }
5532 }
5533 }
5534
5535 // Before recursing into the children keep some state that we are going
5536 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5537 // extra work after the child nodes are visited.
5538 // Note that we don't call VisitChildren here to avoid traversing statements
5539 // code-recursively which can blow the stack.
5540
5541 PostChildrenInfo Info;
5542 Info.Cursor = cursor;
5543 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005544 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005545 Info.BeforeChildrenTokenIdx = NextToken();
5546 PostChildrenInfos.push_back(Info);
5547
5548 return CXChildVisit_Recurse;
5549}
5550
5551bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5552 if (PostChildrenInfos.empty())
5553 return false;
5554 const PostChildrenInfo &Info = PostChildrenInfos.back();
5555 if (!clang_equalCursors(Info.Cursor, cursor))
5556 return false;
5557
5558 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5559 const unsigned AfterChildren = NextToken();
5560 SourceRange cursorRange = Info.CursorRange;
5561
5562 // Scan the tokens that are at the end of the cursor, but are not captured
5563 // but the child cursors.
5564 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5565
5566 // Scan the tokens that are at the beginning of the cursor, but are not
5567 // capture by the child cursors.
5568 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5569 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5570 break;
5571
5572 Cursors[I] = cursor;
5573 }
5574
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005575 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5576 // encountered the attribute cursor.
5577 if (clang_isAttribute(cursor.kind))
5578 TokIdx = Info.BeforeReachingCursorIdx;
5579
Guy Benyei11169dd2012-12-18 14:30:41 +00005580 PostChildrenInfos.pop_back();
5581 return false;
5582}
5583
5584static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5585 CXCursor parent,
5586 CXClientData client_data) {
5587 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5588}
5589
5590static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5591 CXClientData client_data) {
5592 return static_cast<AnnotateTokensWorker*>(client_data)->
5593 postVisitChildren(cursor);
5594}
5595
5596namespace {
5597
5598/// \brief Uses the macro expansions in the preprocessing record to find
5599/// and mark tokens that are macro arguments. This info is used by the
5600/// AnnotateTokensWorker.
5601class MarkMacroArgTokensVisitor {
5602 SourceManager &SM;
5603 CXToken *Tokens;
5604 unsigned NumTokens;
5605 unsigned CurIdx;
5606
5607public:
5608 MarkMacroArgTokensVisitor(SourceManager &SM,
5609 CXToken *tokens, unsigned numTokens)
5610 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5611
5612 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5613 if (cursor.kind != CXCursor_MacroExpansion)
5614 return CXChildVisit_Continue;
5615
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005616 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005617 if (macroRange.getBegin() == macroRange.getEnd())
5618 return CXChildVisit_Continue; // it's not a function macro.
5619
5620 for (; CurIdx < NumTokens; ++CurIdx) {
5621 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5622 macroRange.getBegin()))
5623 break;
5624 }
5625
5626 if (CurIdx == NumTokens)
5627 return CXChildVisit_Break;
5628
5629 for (; CurIdx < NumTokens; ++CurIdx) {
5630 SourceLocation tokLoc = getTokenLoc(CurIdx);
5631 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5632 break;
5633
5634 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5635 }
5636
5637 if (CurIdx == NumTokens)
5638 return CXChildVisit_Break;
5639
5640 return CXChildVisit_Continue;
5641 }
5642
5643private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005644 CXToken &getTok(unsigned Idx) {
5645 assert(Idx < NumTokens);
5646 return Tokens[Idx];
5647 }
5648 const CXToken &getTok(unsigned Idx) const {
5649 assert(Idx < NumTokens);
5650 return Tokens[Idx];
5651 }
5652
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005654 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 }
5656
5657 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5658 // The third field is reserved and currently not used. Use it here
5659 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005660 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005661 }
5662};
5663
5664} // end anonymous namespace
5665
5666static CXChildVisitResult
5667MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5668 CXClientData client_data) {
5669 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5670 parent);
5671}
5672
5673namespace {
5674 struct clang_annotateTokens_Data {
5675 CXTranslationUnit TU;
5676 ASTUnit *CXXUnit;
5677 CXToken *Tokens;
5678 unsigned NumTokens;
5679 CXCursor *Cursors;
5680 };
5681}
5682
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005683/// \brief Used by \c annotatePreprocessorTokens.
5684/// \returns true if lexing was finished, false otherwise.
5685static bool lexNext(Lexer &Lex, Token &Tok,
5686 unsigned &NextIdx, unsigned NumTokens) {
5687 if (NextIdx >= NumTokens)
5688 return true;
5689
5690 ++NextIdx;
5691 Lex.LexFromRawLexer(Tok);
5692 if (Tok.is(tok::eof))
5693 return true;
5694
5695 return false;
5696}
5697
Guy Benyei11169dd2012-12-18 14:30:41 +00005698static void annotatePreprocessorTokens(CXTranslationUnit TU,
5699 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005700 CXCursor *Cursors,
5701 CXToken *Tokens,
5702 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005703 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005704
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005705 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005706 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5707 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005708 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005709 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005710 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005711
5712 if (BeginLocInfo.first != EndLocInfo.first)
5713 return;
5714
5715 StringRef Buffer;
5716 bool Invalid = false;
5717 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5718 if (Buffer.empty() || Invalid)
5719 return;
5720
5721 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5722 CXXUnit->getASTContext().getLangOpts(),
5723 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5724 Buffer.end());
5725 Lex.SetCommentRetentionState(true);
5726
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005727 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005728 // Lex tokens in raw mode until we hit the end of the range, to avoid
5729 // entering #includes or expanding macros.
5730 while (true) {
5731 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005732 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5733 break;
5734 unsigned TokIdx = NextIdx-1;
5735 assert(Tok.getLocation() ==
5736 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005737
5738 reprocess:
5739 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005740 // We have found a preprocessing directive. Annotate the tokens
5741 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005742 //
5743 // FIXME: Some simple tests here could identify macro definitions and
5744 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005745
5746 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005747 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5748 break;
5749
Craig Topper69186e72014-06-08 08:38:04 +00005750 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005751 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005752 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5753 break;
5754
5755 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005756 IdentifierInfo &II =
5757 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005758 SourceLocation MappedTokLoc =
5759 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5760 MI = getMacroInfo(II, MappedTokLoc, TU);
5761 }
5762 }
5763
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005764 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005765 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005766 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5767 finished = true;
5768 break;
5769 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005770 // If we are in a macro definition, check if the token was ever a
5771 // macro name and annotate it if that's the case.
5772 if (MI) {
5773 SourceLocation SaveLoc = Tok.getLocation();
5774 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5775 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5776 Tok.setLocation(SaveLoc);
5777 if (MacroDef)
5778 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5779 Tok.getLocation(), TU);
5780 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005781 } while (!Tok.isAtStartOfLine());
5782
5783 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5784 assert(TokIdx <= LastIdx);
5785 SourceLocation EndLoc =
5786 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5787 CXCursor Cursor =
5788 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5789
5790 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005791 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005792
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005793 if (finished)
5794 break;
5795 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005797 }
5798}
5799
5800// This gets run a separate thread to avoid stack blowout.
5801static void clang_annotateTokensImpl(void *UserData) {
5802 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5803 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5804 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5805 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5806 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5807
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005808 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005809 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5810 setThreadBackgroundPriority();
5811
5812 // Determine the region of interest, which contains all of the tokens.
5813 SourceRange RegionOfInterest;
5814 RegionOfInterest.setBegin(
5815 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5816 RegionOfInterest.setEnd(
5817 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5818 Tokens[NumTokens-1])));
5819
Guy Benyei11169dd2012-12-18 14:30:41 +00005820 // Relex the tokens within the source range to look for preprocessing
5821 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005822 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005823
5824 // If begin location points inside a macro argument, set it to the expansion
5825 // location so we can have the full context when annotating semantically.
5826 {
5827 SourceManager &SM = CXXUnit->getSourceManager();
5828 SourceLocation Loc =
5829 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5830 if (Loc.isMacroID())
5831 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5832 }
5833
Guy Benyei11169dd2012-12-18 14:30:41 +00005834 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5835 // Search and mark tokens that are macro argument expansions.
5836 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5837 Tokens, NumTokens);
5838 CursorVisitor MacroArgMarker(TU,
5839 MarkMacroArgTokensVisitorDelegate, &Visitor,
5840 /*VisitPreprocessorLast=*/true,
5841 /*VisitIncludedEntities=*/false,
5842 RegionOfInterest);
5843 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5844 }
5845
5846 // Annotate all of the source locations in the region of interest that map to
5847 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005848 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005849
5850 // FIXME: We use a ridiculous stack size here because the data-recursion
5851 // algorithm uses a large stack frame than the non-data recursive version,
5852 // and AnnotationTokensWorker currently transforms the data-recursion
5853 // algorithm back into a traditional recursion by explicitly calling
5854 // VisitChildren(). We will need to remove this explicit recursive call.
5855 W.AnnotateTokens();
5856
5857 // If we ran into any entities that involve context-sensitive keywords,
5858 // take another pass through the tokens to mark them as such.
5859 if (W.hasContextSensitiveKeywords()) {
5860 for (unsigned I = 0; I != NumTokens; ++I) {
5861 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5862 continue;
5863
5864 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5865 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005866 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005867 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5868 if (Property->getPropertyAttributesAsWritten() != 0 &&
5869 llvm::StringSwitch<bool>(II->getName())
5870 .Case("readonly", true)
5871 .Case("assign", true)
5872 .Case("unsafe_unretained", true)
5873 .Case("readwrite", true)
5874 .Case("retain", true)
5875 .Case("copy", true)
5876 .Case("nonatomic", true)
5877 .Case("atomic", true)
5878 .Case("getter", true)
5879 .Case("setter", true)
5880 .Case("strong", true)
5881 .Case("weak", true)
5882 .Default(false))
5883 Tokens[I].int_data[0] = CXToken_Keyword;
5884 }
5885 continue;
5886 }
5887
5888 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5889 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5890 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5891 if (llvm::StringSwitch<bool>(II->getName())
5892 .Case("in", true)
5893 .Case("out", true)
5894 .Case("inout", true)
5895 .Case("oneway", true)
5896 .Case("bycopy", true)
5897 .Case("byref", true)
5898 .Default(false))
5899 Tokens[I].int_data[0] = CXToken_Keyword;
5900 continue;
5901 }
5902
5903 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5904 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5905 Tokens[I].int_data[0] = CXToken_Keyword;
5906 continue;
5907 }
5908 }
5909 }
5910}
5911
5912extern "C" {
5913
5914void clang_annotateTokens(CXTranslationUnit TU,
5915 CXToken *Tokens, unsigned NumTokens,
5916 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005917 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005918 LOG_BAD_TU(TU);
5919 return;
5920 }
5921 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005922 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005923 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005924 }
5925
5926 LOG_FUNC_SECTION {
5927 *Log << TU << ' ';
5928 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5929 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5930 *Log << clang_getRange(bloc, eloc);
5931 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005932
5933 // Any token we don't specifically annotate will have a NULL cursor.
5934 CXCursor C = clang_getNullCursor();
5935 for (unsigned I = 0; I != NumTokens; ++I)
5936 Cursors[I] = C;
5937
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005938 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005939 if (!CXXUnit)
5940 return;
5941
5942 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5943
5944 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5945 llvm::CrashRecoveryContext CRC;
5946 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5947 GetSafetyThreadStackSize() * 2)) {
5948 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5949 }
5950}
5951
5952} // end: extern "C"
5953
5954//===----------------------------------------------------------------------===//
5955// Operations for querying linkage of a cursor.
5956//===----------------------------------------------------------------------===//
5957
5958extern "C" {
5959CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5960 if (!clang_isDeclaration(cursor.kind))
5961 return CXLinkage_Invalid;
5962
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005963 const Decl *D = cxcursor::getCursorDecl(cursor);
5964 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005965 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005966 case NoLinkage:
5967 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005968 case InternalLinkage: return CXLinkage_Internal;
5969 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5970 case ExternalLinkage: return CXLinkage_External;
5971 };
5972
5973 return CXLinkage_Invalid;
5974}
5975} // end: extern "C"
5976
5977//===----------------------------------------------------------------------===//
5978// Operations for querying language of a cursor.
5979//===----------------------------------------------------------------------===//
5980
5981static CXLanguageKind getDeclLanguage(const Decl *D) {
5982 if (!D)
5983 return CXLanguage_C;
5984
5985 switch (D->getKind()) {
5986 default:
5987 break;
5988 case Decl::ImplicitParam:
5989 case Decl::ObjCAtDefsField:
5990 case Decl::ObjCCategory:
5991 case Decl::ObjCCategoryImpl:
5992 case Decl::ObjCCompatibleAlias:
5993 case Decl::ObjCImplementation:
5994 case Decl::ObjCInterface:
5995 case Decl::ObjCIvar:
5996 case Decl::ObjCMethod:
5997 case Decl::ObjCProperty:
5998 case Decl::ObjCPropertyImpl:
5999 case Decl::ObjCProtocol:
6000 return CXLanguage_ObjC;
6001 case Decl::CXXConstructor:
6002 case Decl::CXXConversion:
6003 case Decl::CXXDestructor:
6004 case Decl::CXXMethod:
6005 case Decl::CXXRecord:
6006 case Decl::ClassTemplate:
6007 case Decl::ClassTemplatePartialSpecialization:
6008 case Decl::ClassTemplateSpecialization:
6009 case Decl::Friend:
6010 case Decl::FriendTemplate:
6011 case Decl::FunctionTemplate:
6012 case Decl::LinkageSpec:
6013 case Decl::Namespace:
6014 case Decl::NamespaceAlias:
6015 case Decl::NonTypeTemplateParm:
6016 case Decl::StaticAssert:
6017 case Decl::TemplateTemplateParm:
6018 case Decl::TemplateTypeParm:
6019 case Decl::UnresolvedUsingTypename:
6020 case Decl::UnresolvedUsingValue:
6021 case Decl::Using:
6022 case Decl::UsingDirective:
6023 case Decl::UsingShadow:
6024 return CXLanguage_CPlusPlus;
6025 }
6026
6027 return CXLanguage_C;
6028}
6029
6030extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006031
6032static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6033 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6034 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006035
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006036 switch (D->getAvailability()) {
6037 case AR_Available:
6038 case AR_NotYetIntroduced:
6039 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006040 return getCursorAvailabilityForDecl(
6041 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006042 return CXAvailability_Available;
6043
6044 case AR_Deprecated:
6045 return CXAvailability_Deprecated;
6046
6047 case AR_Unavailable:
6048 return CXAvailability_NotAvailable;
6049 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006050
6051 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006052}
6053
Guy Benyei11169dd2012-12-18 14:30:41 +00006054enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6055 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006056 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6057 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006058
6059 return CXAvailability_Available;
6060}
6061
6062static CXVersion convertVersion(VersionTuple In) {
6063 CXVersion Out = { -1, -1, -1 };
6064 if (In.empty())
6065 return Out;
6066
6067 Out.Major = In.getMajor();
6068
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006069 Optional<unsigned> Minor = In.getMinor();
6070 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006071 Out.Minor = *Minor;
6072 else
6073 return Out;
6074
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006075 Optional<unsigned> Subminor = In.getSubminor();
6076 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006077 Out.Subminor = *Subminor;
6078
6079 return Out;
6080}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006081
6082static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6083 int *always_deprecated,
6084 CXString *deprecated_message,
6085 int *always_unavailable,
6086 CXString *unavailable_message,
6087 CXPlatformAvailability *availability,
6088 int availability_size) {
6089 bool HadAvailAttr = false;
6090 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006091 for (auto A : D->attrs()) {
6092 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006093 HadAvailAttr = true;
6094 if (always_deprecated)
6095 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006096 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006097 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006098 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006099 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006100 continue;
6101 }
6102
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006103 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006104 HadAvailAttr = true;
6105 if (always_unavailable)
6106 *always_unavailable = 1;
6107 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006108 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006109 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6110 }
6111 continue;
6112 }
6113
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006114 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006115 HadAvailAttr = true;
6116 if (N < availability_size) {
6117 availability[N].Platform
6118 = cxstring::createDup(Avail->getPlatform()->getName());
6119 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6120 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6121 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6122 availability[N].Unavailable = Avail->getUnavailable();
6123 availability[N].Message = cxstring::createDup(Avail->getMessage());
6124 }
6125 ++N;
6126 }
6127 }
6128
6129 if (!HadAvailAttr)
6130 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6131 return getCursorPlatformAvailabilityForDecl(
6132 cast<Decl>(EnumConst->getDeclContext()),
6133 always_deprecated,
6134 deprecated_message,
6135 always_unavailable,
6136 unavailable_message,
6137 availability,
6138 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006139
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006140 return N;
6141}
6142
Guy Benyei11169dd2012-12-18 14:30:41 +00006143int clang_getCursorPlatformAvailability(CXCursor cursor,
6144 int *always_deprecated,
6145 CXString *deprecated_message,
6146 int *always_unavailable,
6147 CXString *unavailable_message,
6148 CXPlatformAvailability *availability,
6149 int availability_size) {
6150 if (always_deprecated)
6151 *always_deprecated = 0;
6152 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006153 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006154 if (always_unavailable)
6155 *always_unavailable = 0;
6156 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006157 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006158
Guy Benyei11169dd2012-12-18 14:30:41 +00006159 if (!clang_isDeclaration(cursor.kind))
6160 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006161
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006162 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006163 if (!D)
6164 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006165
6166 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6167 deprecated_message,
6168 always_unavailable,
6169 unavailable_message,
6170 availability,
6171 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006172}
6173
6174void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6175 clang_disposeString(availability->Platform);
6176 clang_disposeString(availability->Message);
6177}
6178
6179CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6180 if (clang_isDeclaration(cursor.kind))
6181 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6182
6183 return CXLanguage_Invalid;
6184}
6185
6186 /// \brief If the given cursor is the "templated" declaration
6187 /// descibing a class or function template, return the class or
6188 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006189static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006191 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006192
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006193 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006194 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6195 return FunTmpl;
6196
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006197 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006198 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6199 return ClassTmpl;
6200
6201 return D;
6202}
6203
6204CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6205 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006206 if (const Decl *D = getCursorDecl(cursor)) {
6207 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006208 if (!DC)
6209 return clang_getNullCursor();
6210
6211 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6212 getCursorTU(cursor));
6213 }
6214 }
6215
6216 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006217 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006218 return MakeCXCursor(D, getCursorTU(cursor));
6219 }
6220
6221 return clang_getNullCursor();
6222}
6223
6224CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6225 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006226 if (const Decl *D = getCursorDecl(cursor)) {
6227 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006228 if (!DC)
6229 return clang_getNullCursor();
6230
6231 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6232 getCursorTU(cursor));
6233 }
6234 }
6235
6236 // FIXME: Note that we can't easily compute the lexical context of a
6237 // statement or expression, so we return nothing.
6238 return clang_getNullCursor();
6239}
6240
6241CXFile clang_getIncludedFile(CXCursor cursor) {
6242 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006243 return nullptr;
6244
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006245 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006246 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006247}
6248
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006249unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6250 if (C.kind != CXCursor_ObjCPropertyDecl)
6251 return CXObjCPropertyAttr_noattr;
6252
6253 unsigned Result = CXObjCPropertyAttr_noattr;
6254 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6255 ObjCPropertyDecl::PropertyAttributeKind Attr =
6256 PD->getPropertyAttributesAsWritten();
6257
6258#define SET_CXOBJCPROP_ATTR(A) \
6259 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6260 Result |= CXObjCPropertyAttr_##A
6261 SET_CXOBJCPROP_ATTR(readonly);
6262 SET_CXOBJCPROP_ATTR(getter);
6263 SET_CXOBJCPROP_ATTR(assign);
6264 SET_CXOBJCPROP_ATTR(readwrite);
6265 SET_CXOBJCPROP_ATTR(retain);
6266 SET_CXOBJCPROP_ATTR(copy);
6267 SET_CXOBJCPROP_ATTR(nonatomic);
6268 SET_CXOBJCPROP_ATTR(setter);
6269 SET_CXOBJCPROP_ATTR(atomic);
6270 SET_CXOBJCPROP_ATTR(weak);
6271 SET_CXOBJCPROP_ATTR(strong);
6272 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6273#undef SET_CXOBJCPROP_ATTR
6274
6275 return Result;
6276}
6277
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006278unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6279 if (!clang_isDeclaration(C.kind))
6280 return CXObjCDeclQualifier_None;
6281
6282 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6283 const Decl *D = getCursorDecl(C);
6284 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6285 QT = MD->getObjCDeclQualifier();
6286 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6287 QT = PD->getObjCDeclQualifier();
6288 if (QT == Decl::OBJC_TQ_None)
6289 return CXObjCDeclQualifier_None;
6290
6291 unsigned Result = CXObjCDeclQualifier_None;
6292 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6293 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6294 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6295 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6296 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6297 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6298
6299 return Result;
6300}
6301
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006302unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6303 if (!clang_isDeclaration(C.kind))
6304 return 0;
6305
6306 const Decl *D = getCursorDecl(C);
6307 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6308 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6309 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6310 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6311
6312 return 0;
6313}
6314
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006315unsigned clang_Cursor_isVariadic(CXCursor C) {
6316 if (!clang_isDeclaration(C.kind))
6317 return 0;
6318
6319 const Decl *D = getCursorDecl(C);
6320 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6321 return FD->isVariadic();
6322 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6323 return MD->isVariadic();
6324
6325 return 0;
6326}
6327
Guy Benyei11169dd2012-12-18 14:30:41 +00006328CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6329 if (!clang_isDeclaration(C.kind))
6330 return clang_getNullRange();
6331
6332 const Decl *D = getCursorDecl(C);
6333 ASTContext &Context = getCursorContext(C);
6334 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6335 if (!RC)
6336 return clang_getNullRange();
6337
6338 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6339}
6340
6341CXString clang_Cursor_getRawCommentText(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 ASTContext &Context = getCursorContext(C);
6347 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6348 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6349 StringRef();
6350
6351 // Don't duplicate the string because RawText points directly into source
6352 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006353 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006354}
6355
6356CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6357 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006358 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006359
6360 const Decl *D = getCursorDecl(C);
6361 const ASTContext &Context = getCursorContext(C);
6362 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6363
6364 if (RC) {
6365 StringRef BriefText = RC->getBriefText(Context);
6366
6367 // Don't duplicate the string because RawComment ensures that this memory
6368 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006369 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006370 }
6371
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006372 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006373}
6374
Guy Benyei11169dd2012-12-18 14:30:41 +00006375CXModule clang_Cursor_getModule(CXCursor C) {
6376 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006377 if (const ImportDecl *ImportD =
6378 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006379 return ImportD->getImportedModule();
6380 }
6381
Craig Topper69186e72014-06-08 08:38:04 +00006382 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006383}
6384
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006385CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6386 if (isNotUsableTU(TU)) {
6387 LOG_BAD_TU(TU);
6388 return nullptr;
6389 }
6390 if (!File)
6391 return nullptr;
6392 FileEntry *FE = static_cast<FileEntry *>(File);
6393
6394 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6395 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6396 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6397
6398 if (Module *Mod = Header.getModule()) {
6399 if (Header.getRole() != ModuleMap::ExcludedHeader)
6400 return Mod;
6401 }
6402 return nullptr;
6403}
6404
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006405CXFile clang_Module_getASTFile(CXModule CXMod) {
6406 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006407 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006408 Module *Mod = static_cast<Module*>(CXMod);
6409 return const_cast<FileEntry *>(Mod->getASTFile());
6410}
6411
Guy Benyei11169dd2012-12-18 14:30:41 +00006412CXModule clang_Module_getParent(CXModule CXMod) {
6413 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006414 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006415 Module *Mod = static_cast<Module*>(CXMod);
6416 return Mod->Parent;
6417}
6418
6419CXString clang_Module_getName(CXModule CXMod) {
6420 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006421 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006422 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006423 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006424}
6425
6426CXString clang_Module_getFullName(CXModule CXMod) {
6427 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006428 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006429 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006430 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006431}
6432
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006433int clang_Module_isSystem(CXModule CXMod) {
6434 if (!CXMod)
6435 return 0;
6436 Module *Mod = static_cast<Module*>(CXMod);
6437 return Mod->IsSystem;
6438}
6439
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006440unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6441 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006442 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006443 LOG_BAD_TU(TU);
6444 return 0;
6445 }
6446 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006447 return 0;
6448 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006449 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6450 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6451 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006452}
6453
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006454CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6455 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006456 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006457 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006458 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006459 }
6460 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006461 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006462 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006463 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006464
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006465 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6466 if (Index < TopHeaders.size())
6467 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006468
Craig Topper69186e72014-06-08 08:38:04 +00006469 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006470}
6471
6472} // end: extern "C"
6473
6474//===----------------------------------------------------------------------===//
6475// C++ AST instrospection.
6476//===----------------------------------------------------------------------===//
6477
6478extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006479unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6480 if (!clang_isDeclaration(C.kind))
6481 return 0;
6482
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006483 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006484 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006485 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006486 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6487}
6488
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006489unsigned clang_CXXMethod_isConst(CXCursor C) {
6490 if (!clang_isDeclaration(C.kind))
6491 return 0;
6492
6493 const Decl *D = cxcursor::getCursorDecl(C);
6494 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006495 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006496 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6497}
6498
Guy Benyei11169dd2012-12-18 14:30:41 +00006499unsigned clang_CXXMethod_isStatic(CXCursor C) {
6500 if (!clang_isDeclaration(C.kind))
6501 return 0;
6502
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006503 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006504 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006505 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006506 return (Method && Method->isStatic()) ? 1 : 0;
6507}
6508
6509unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6510 if (!clang_isDeclaration(C.kind))
6511 return 0;
6512
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006513 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006514 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006515 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006516 return (Method && Method->isVirtual()) ? 1 : 0;
6517}
6518} // end: extern "C"
6519
6520//===----------------------------------------------------------------------===//
6521// Attribute introspection.
6522//===----------------------------------------------------------------------===//
6523
6524extern "C" {
6525CXType clang_getIBOutletCollectionType(CXCursor C) {
6526 if (C.kind != CXCursor_IBOutletCollectionAttr)
6527 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6528
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006529 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006530 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6531
6532 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6533}
6534} // end: extern "C"
6535
6536//===----------------------------------------------------------------------===//
6537// Inspecting memory usage.
6538//===----------------------------------------------------------------------===//
6539
6540typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6541
6542static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6543 enum CXTUResourceUsageKind k,
6544 unsigned long amount) {
6545 CXTUResourceUsageEntry entry = { k, amount };
6546 entries.push_back(entry);
6547}
6548
6549extern "C" {
6550
6551const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6552 const char *str = "";
6553 switch (kind) {
6554 case CXTUResourceUsage_AST:
6555 str = "ASTContext: expressions, declarations, and types";
6556 break;
6557 case CXTUResourceUsage_Identifiers:
6558 str = "ASTContext: identifiers";
6559 break;
6560 case CXTUResourceUsage_Selectors:
6561 str = "ASTContext: selectors";
6562 break;
6563 case CXTUResourceUsage_GlobalCompletionResults:
6564 str = "Code completion: cached global results";
6565 break;
6566 case CXTUResourceUsage_SourceManagerContentCache:
6567 str = "SourceManager: content cache allocator";
6568 break;
6569 case CXTUResourceUsage_AST_SideTables:
6570 str = "ASTContext: side tables";
6571 break;
6572 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6573 str = "SourceManager: malloc'ed memory buffers";
6574 break;
6575 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6576 str = "SourceManager: mmap'ed memory buffers";
6577 break;
6578 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6579 str = "ExternalASTSource: malloc'ed memory buffers";
6580 break;
6581 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6582 str = "ExternalASTSource: mmap'ed memory buffers";
6583 break;
6584 case CXTUResourceUsage_Preprocessor:
6585 str = "Preprocessor: malloc'ed memory";
6586 break;
6587 case CXTUResourceUsage_PreprocessingRecord:
6588 str = "Preprocessor: PreprocessingRecord";
6589 break;
6590 case CXTUResourceUsage_SourceManager_DataStructures:
6591 str = "SourceManager: data structures and tables";
6592 break;
6593 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6594 str = "Preprocessor: header search tables";
6595 break;
6596 }
6597 return str;
6598}
6599
6600CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006601 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006602 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006603 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006604 return usage;
6605 }
6606
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006607 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006608 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006609 ASTContext &astContext = astUnit->getASTContext();
6610
6611 // How much memory is used by AST nodes and types?
6612 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6613 (unsigned long) astContext.getASTAllocatedMemory());
6614
6615 // How much memory is used by identifiers?
6616 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6617 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6618
6619 // How much memory is used for selectors?
6620 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6621 (unsigned long) astContext.Selectors.getTotalMemory());
6622
6623 // How much memory is used by ASTContext's side tables?
6624 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6625 (unsigned long) astContext.getSideTableAllocatedMemory());
6626
6627 // How much memory is used for caching global code completion results?
6628 unsigned long completionBytes = 0;
6629 if (GlobalCodeCompletionAllocator *completionAllocator =
6630 astUnit->getCachedCompletionAllocator().getPtr()) {
6631 completionBytes = completionAllocator->getTotalMemory();
6632 }
6633 createCXTUResourceUsageEntry(*entries,
6634 CXTUResourceUsage_GlobalCompletionResults,
6635 completionBytes);
6636
6637 // How much memory is being used by SourceManager's content cache?
6638 createCXTUResourceUsageEntry(*entries,
6639 CXTUResourceUsage_SourceManagerContentCache,
6640 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6641
6642 // How much memory is being used by the MemoryBuffer's in SourceManager?
6643 const SourceManager::MemoryBufferSizes &srcBufs =
6644 astUnit->getSourceManager().getMemoryBufferSizes();
6645
6646 createCXTUResourceUsageEntry(*entries,
6647 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6648 (unsigned long) srcBufs.malloc_bytes);
6649 createCXTUResourceUsageEntry(*entries,
6650 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6651 (unsigned long) srcBufs.mmap_bytes);
6652 createCXTUResourceUsageEntry(*entries,
6653 CXTUResourceUsage_SourceManager_DataStructures,
6654 (unsigned long) astContext.getSourceManager()
6655 .getDataStructureSizes());
6656
6657 // How much memory is being used by the ExternalASTSource?
6658 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6659 const ExternalASTSource::MemoryBufferSizes &sizes =
6660 esrc->getMemoryBufferSizes();
6661
6662 createCXTUResourceUsageEntry(*entries,
6663 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6664 (unsigned long) sizes.malloc_bytes);
6665 createCXTUResourceUsageEntry(*entries,
6666 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6667 (unsigned long) sizes.mmap_bytes);
6668 }
6669
6670 // How much memory is being used by the Preprocessor?
6671 Preprocessor &pp = astUnit->getPreprocessor();
6672 createCXTUResourceUsageEntry(*entries,
6673 CXTUResourceUsage_Preprocessor,
6674 pp.getTotalMemory());
6675
6676 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6677 createCXTUResourceUsageEntry(*entries,
6678 CXTUResourceUsage_PreprocessingRecord,
6679 pRec->getTotalMemory());
6680 }
6681
6682 createCXTUResourceUsageEntry(*entries,
6683 CXTUResourceUsage_Preprocessor_HeaderSearch,
6684 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006685
Guy Benyei11169dd2012-12-18 14:30:41 +00006686 CXTUResourceUsage usage = { (void*) entries.get(),
6687 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006688 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006689 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006690 return usage;
6691}
6692
6693void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6694 if (usage.data)
6695 delete (MemUsageEntries*) usage.data;
6696}
6697
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006698CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6699 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006700 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006701 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006702
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006703 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006704 LOG_BAD_TU(TU);
6705 return skipped;
6706 }
6707
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006708 if (!file)
6709 return skipped;
6710
6711 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6712 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6713 if (!ppRec)
6714 return skipped;
6715
6716 ASTContext &Ctx = astUnit->getASTContext();
6717 SourceManager &sm = Ctx.getSourceManager();
6718 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6719 FileID wantedFileID = sm.translateFile(fileEntry);
6720
6721 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6722 std::vector<SourceRange> wantedRanges;
6723 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6724 i != ei; ++i) {
6725 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6726 wantedRanges.push_back(*i);
6727 }
6728
6729 skipped->count = wantedRanges.size();
6730 skipped->ranges = new CXSourceRange[skipped->count];
6731 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6732 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6733
6734 return skipped;
6735}
6736
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006737void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6738 if (ranges) {
6739 delete[] ranges->ranges;
6740 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006741 }
6742}
6743
Guy Benyei11169dd2012-12-18 14:30:41 +00006744} // end extern "C"
6745
6746void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6747 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6748 for (unsigned I = 0; I != Usage.numEntries; ++I)
6749 fprintf(stderr, " %s: %lu\n",
6750 clang_getTUResourceUsageName(Usage.entries[I].kind),
6751 Usage.entries[I].amount);
6752
6753 clang_disposeCXTUResourceUsage(Usage);
6754}
6755
6756//===----------------------------------------------------------------------===//
6757// Misc. utility functions.
6758//===----------------------------------------------------------------------===//
6759
6760/// Default to using an 8 MB stack size on "safety" threads.
6761static unsigned SafetyStackThreadSize = 8 << 20;
6762
6763namespace clang {
6764
6765bool RunSafely(llvm::CrashRecoveryContext &CRC,
6766 void (*Fn)(void*), void *UserData,
6767 unsigned Size) {
6768 if (!Size)
6769 Size = GetSafetyThreadStackSize();
6770 if (Size)
6771 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6772 return CRC.RunSafely(Fn, UserData);
6773}
6774
6775unsigned GetSafetyThreadStackSize() {
6776 return SafetyStackThreadSize;
6777}
6778
6779void SetSafetyThreadStackSize(unsigned Value) {
6780 SafetyStackThreadSize = Value;
6781}
6782
6783}
6784
6785void clang::setThreadBackgroundPriority() {
6786 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6787 return;
6788
6789 // FIXME: Move to llvm/Support and make it cross-platform.
6790#ifdef __APPLE__
6791 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6792#endif
6793}
6794
6795void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6796 if (!Unit)
6797 return;
6798
6799 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6800 DEnd = Unit->stored_diag_end();
6801 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006802 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006803 CXString Msg = clang_formatDiagnostic(&Diag,
6804 clang_defaultDiagnosticDisplayOptions());
6805 fprintf(stderr, "%s\n", clang_getCString(Msg));
6806 clang_disposeString(Msg);
6807 }
6808#ifdef LLVM_ON_WIN32
6809 // On Windows, force a flush, since there may be multiple copies of
6810 // stderr and stdout in the file system, all with different buffers
6811 // but writing to the same device.
6812 fflush(stderr);
6813#endif
6814}
6815
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006816MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6817 SourceLocation MacroDefLoc,
6818 CXTranslationUnit TU){
6819 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006820 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006821 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006822 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006823
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006824 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006825 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006826 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006827 if (MD) {
6828 for (MacroDirective::DefInfo
6829 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6830 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6831 return Def.getMacroInfo();
6832 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006833 }
6834
Craig Topper69186e72014-06-08 08:38:04 +00006835 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006836}
6837
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006838const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6839 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006840 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006841 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006842 const IdentifierInfo *II = MacroDef->getName();
6843 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006844 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006845
6846 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6847}
6848
6849MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6850 const Token &Tok,
6851 CXTranslationUnit TU) {
6852 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006853 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006854 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006855 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006856
6857 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006858 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006859 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6860 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006861 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006862
6863 // Check that the token is inside the definition and not its argument list.
6864 SourceManager &SM = Unit->getSourceManager();
6865 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006866 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006867 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006868 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006869
6870 Preprocessor &PP = Unit->getPreprocessor();
6871 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6872 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006873 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006874
Alp Toker2d57cea2014-05-17 04:53:25 +00006875 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006876 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006877 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006878
6879 // Check that the identifier is not one of the macro arguments.
6880 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006881 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006882
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006883 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6884 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006885 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006886
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006887 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006888}
6889
6890MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6891 SourceLocation Loc,
6892 CXTranslationUnit TU) {
6893 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006894 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006895
6896 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006897 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006898 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006899 Preprocessor &PP = Unit->getPreprocessor();
6900 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006901 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006902 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6903 Token Tok;
6904 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006905 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006906
6907 return checkForMacroInMacroDefinition(MI, Tok, TU);
6908}
6909
Guy Benyei11169dd2012-12-18 14:30:41 +00006910extern "C" {
6911
6912CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006913 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006914}
6915
6916} // end: extern "C"
6917
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006918Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6919 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006920 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006921 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006922 if (Unit->isMainFileAST())
6923 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006924 return *this;
6925 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006926 } else {
6927 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006928 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006929 return *this;
6930}
6931
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006932Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6933 *this << FE->getName();
6934 return *this;
6935}
6936
6937Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6938 CXString cursorName = clang_getCursorDisplayName(cursor);
6939 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6940 clang_disposeString(cursorName);
6941 return *this;
6942}
6943
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006944Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6945 CXFile File;
6946 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006947 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006948 CXString FileName = clang_getFileName(File);
6949 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6950 clang_disposeString(FileName);
6951 return *this;
6952}
6953
6954Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6955 CXSourceLocation BLoc = clang_getRangeStart(range);
6956 CXSourceLocation ELoc = clang_getRangeEnd(range);
6957
6958 CXFile BFile;
6959 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006960 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006961
6962 CXFile EFile;
6963 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006964 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006965
6966 CXString BFileName = clang_getFileName(BFile);
6967 if (BFile == EFile) {
6968 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6969 BLine, BColumn, ELine, EColumn);
6970 } else {
6971 CXString EFileName = clang_getFileName(EFile);
6972 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6973 BLine, BColumn)
6974 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6975 ELine, EColumn);
6976 clang_disposeString(EFileName);
6977 }
6978 clang_disposeString(BFileName);
6979 return *this;
6980}
6981
6982Logger &cxindex::Logger::operator<<(CXString Str) {
6983 *this << clang_getCString(Str);
6984 return *this;
6985}
6986
6987Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6988 LogOS << Fmt;
6989 return *this;
6990}
6991
Chandler Carruth37ad2582014-06-27 15:14:39 +00006992static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
6993
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006994cxindex::Logger::~Logger() {
6995 LogOS.flush();
6996
Chandler Carruth37ad2582014-06-27 15:14:39 +00006997 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006998
6999 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7000
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007001 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007002 OS << "[libclang:" << Name << ':';
7003
7004 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00007005#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007006 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7007 OS << tid << ':';
7008#endif
7009
7010 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7011 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7012 OS << Msg.str() << '\n';
7013
7014 if (Trace) {
7015 llvm::sys::PrintStackTrace(stderr);
7016 OS << "--------------------------------------------------\n";
7017 }
7018}