blob: 8683ae62b076c4796d23366889ce7154e44dbde7 [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
Chandler Carruth66660742014-06-27 16:37:27 +00002603namespace {
2604struct RegisterFatalErrorHandler {
2605 RegisterFatalErrorHandler() {
2606 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2607 }
2608};
2609}
2610
2611static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2612
Guy Benyei11169dd2012-12-18 14:30:41 +00002613extern "C" {
2614CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2615 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002616 // We use crash recovery to make some of our APIs more reliable, implicitly
2617 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002618 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2619 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002620
Chandler Carruth66660742014-06-27 16:37:27 +00002621 // Look through the managed static to trigger construction of the managed
2622 // static which registers our fatal error handler. This ensures it is only
2623 // registered once.
2624 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002625
2626 CIndexer *CIdxr = new CIndexer();
2627 if (excludeDeclarationsFromPCH)
2628 CIdxr->setOnlyLocalDecls();
2629 if (displayDiagnostics)
2630 CIdxr->setDisplayDiagnostics();
2631
2632 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2633 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2634 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2635 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2636 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2637 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2638
2639 return CIdxr;
2640}
2641
2642void clang_disposeIndex(CXIndex CIdx) {
2643 if (CIdx)
2644 delete static_cast<CIndexer *>(CIdx);
2645}
2646
2647void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2648 if (CIdx)
2649 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2650}
2651
2652unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2653 if (CIdx)
2654 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2655 return 0;
2656}
2657
2658void clang_toggleCrashRecovery(unsigned isEnabled) {
2659 if (isEnabled)
2660 llvm::CrashRecoveryContext::Enable();
2661 else
2662 llvm::CrashRecoveryContext::Disable();
2663}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002664
Guy Benyei11169dd2012-12-18 14:30:41 +00002665CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2666 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002667 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002668 enum CXErrorCode Result =
2669 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002670 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002671 assert((TU && Result == CXError_Success) ||
2672 (!TU && Result != CXError_Success));
2673 return TU;
2674}
2675
2676enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2677 const char *ast_filename,
2678 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002679 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002680 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002681
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002682 if (!CIdx || !ast_filename || !out_TU)
2683 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002684
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002685 LOG_FUNC_SECTION {
2686 *Log << ast_filename;
2687 }
2688
Guy Benyei11169dd2012-12-18 14:30:41 +00002689 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2690 FileSystemOptions FileSystemOpts;
2691
2692 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002693 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002694 CXXIdx->getOnlyLocalDecls(), None,
2695 /*CaptureDiagnostics=*/true,
2696 /*AllowPCHWithCompilerErrors=*/true,
2697 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002698 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2699 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002700}
2701
2702unsigned clang_defaultEditingTranslationUnitOptions() {
2703 return CXTranslationUnit_PrecompiledPreamble |
2704 CXTranslationUnit_CacheCompletionResults;
2705}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002706
Guy Benyei11169dd2012-12-18 14:30:41 +00002707CXTranslationUnit
2708clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2709 const char *source_filename,
2710 int num_command_line_args,
2711 const char * const *command_line_args,
2712 unsigned num_unsaved_files,
2713 struct CXUnsavedFile *unsaved_files) {
2714 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2715 return clang_parseTranslationUnit(CIdx, source_filename,
2716 command_line_args, num_command_line_args,
2717 unsaved_files, num_unsaved_files,
2718 Options);
2719}
2720
2721struct ParseTranslationUnitInfo {
2722 CXIndex CIdx;
2723 const char *source_filename;
2724 const char *const *command_line_args;
2725 int num_command_line_args;
2726 struct CXUnsavedFile *unsaved_files;
2727 unsigned num_unsaved_files;
2728 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002729 CXTranslationUnit *out_TU;
2730 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002731};
2732static void clang_parseTranslationUnit_Impl(void *UserData) {
2733 ParseTranslationUnitInfo *PTUI =
2734 static_cast<ParseTranslationUnitInfo*>(UserData);
2735 CXIndex CIdx = PTUI->CIdx;
2736 const char *source_filename = PTUI->source_filename;
2737 const char * const *command_line_args = PTUI->command_line_args;
2738 int num_command_line_args = PTUI->num_command_line_args;
2739 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2740 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2741 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002742 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002743
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002744 // Set up the initial return values.
2745 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002746 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002747 PTUI->result = CXError_Failure;
2748
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002749 // Check arguments.
2750 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002751 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002752 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002753 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002754 }
2755
Guy Benyei11169dd2012-12-18 14:30:41 +00002756 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2757
2758 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2759 setThreadBackgroundPriority();
2760
2761 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2762 // FIXME: Add a flag for modules.
2763 TranslationUnitKind TUKind
2764 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002765 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002766 = options & CXTranslationUnit_CacheCompletionResults;
2767 bool IncludeBriefCommentsInCodeCompletion
2768 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2769 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2770 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2771
2772 // Configure the diagnostics.
2773 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002774 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002775
2776 // Recover resources if we crash before exiting this function.
2777 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2778 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2779 DiagCleanup(Diags.getPtr());
2780
Ahmed Charlesb8984322014-03-07 20:03:18 +00002781 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2782 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002783
2784 // Recover resources if we crash before exiting this function.
2785 llvm::CrashRecoveryContextCleanupRegistrar<
2786 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2787
2788 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2789 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
David Blaikie66cc07b2014-06-27 17:40:03 +00002790 llvm::MemoryBuffer *Buffer =
2791 llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Guy Benyei11169dd2012-12-18 14:30:41 +00002792 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2793 Buffer));
2794 }
2795
Ahmed Charlesb8984322014-03-07 20:03:18 +00002796 std::unique_ptr<std::vector<const char *>> Args(
2797 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002798
2799 // Recover resources if we crash before exiting this method.
2800 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2801 ArgsCleanup(Args.get());
2802
2803 // Since the Clang C library is primarily used by batch tools dealing with
2804 // (often very broken) source code, where spell-checking can have a
2805 // significant negative impact on performance (particularly when
2806 // precompiled headers are involved), we disable it by default.
2807 // Only do this if we haven't found a spell-checking-related argument.
2808 bool FoundSpellCheckingArgument = false;
2809 for (int I = 0; I != num_command_line_args; ++I) {
2810 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2811 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2812 FoundSpellCheckingArgument = true;
2813 break;
2814 }
2815 }
2816 if (!FoundSpellCheckingArgument)
2817 Args->push_back("-fno-spell-checking");
2818
2819 Args->insert(Args->end(), command_line_args,
2820 command_line_args + num_command_line_args);
2821
2822 // The 'source_filename' argument is optional. If the caller does not
2823 // specify it then it is assumed that the source file is specified
2824 // in the actual argument list.
2825 // Put the source file after command_line_args otherwise if '-x' flag is
2826 // present it will be unused.
2827 if (source_filename)
2828 Args->push_back(source_filename);
2829
2830 // Do we need the detailed preprocessing record?
2831 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2832 Args->push_back("-Xclang");
2833 Args->push_back("-detailed-preprocessing-record");
2834 }
2835
2836 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002837 std::unique_ptr<ASTUnit> ErrUnit;
2838 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002839 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002840 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2841 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2842 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2843 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2844 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2845 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002846
2847 if (NumErrors != Diags->getClient()->getNumErrors()) {
2848 // Make sure to check that 'Unit' is non-NULL.
2849 if (CXXIdx->getDisplayDiagnostics())
2850 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2851 }
2852
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002853 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2854 PTUI->result = CXError_ASTReadError;
2855 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002856 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002857 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2858 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002859}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002860
2861CXTranslationUnit
2862clang_parseTranslationUnit(CXIndex CIdx,
2863 const char *source_filename,
2864 const char *const *command_line_args,
2865 int num_command_line_args,
2866 struct CXUnsavedFile *unsaved_files,
2867 unsigned num_unsaved_files,
2868 unsigned options) {
2869 CXTranslationUnit TU;
2870 enum CXErrorCode Result = clang_parseTranslationUnit2(
2871 CIdx, source_filename, command_line_args, num_command_line_args,
2872 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002873 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002874 assert((TU && Result == CXError_Success) ||
2875 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002876 return TU;
2877}
2878
2879enum CXErrorCode clang_parseTranslationUnit2(
2880 CXIndex CIdx,
2881 const char *source_filename,
2882 const char *const *command_line_args,
2883 int num_command_line_args,
2884 struct CXUnsavedFile *unsaved_files,
2885 unsigned num_unsaved_files,
2886 unsigned options,
2887 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002888 LOG_FUNC_SECTION {
2889 *Log << source_filename << ": ";
2890 for (int i = 0; i != num_command_line_args; ++i)
2891 *Log << command_line_args[i] << " ";
2892 }
2893
Guy Benyei11169dd2012-12-18 14:30:41 +00002894 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2895 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002896 num_unsaved_files, options, out_TU,
2897 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002898 llvm::CrashRecoveryContext CRC;
2899
2900 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2901 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2902 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2903 fprintf(stderr, " 'command_line_args' : [");
2904 for (int i = 0; i != num_command_line_args; ++i) {
2905 if (i)
2906 fprintf(stderr, ", ");
2907 fprintf(stderr, "'%s'", command_line_args[i]);
2908 }
2909 fprintf(stderr, "],\n");
2910 fprintf(stderr, " 'unsaved_files' : [");
2911 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2912 if (i)
2913 fprintf(stderr, ", ");
2914 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2915 unsaved_files[i].Length);
2916 }
2917 fprintf(stderr, "],\n");
2918 fprintf(stderr, " 'options' : %d,\n", options);
2919 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002920
2921 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002922 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002923 if (CXTranslationUnit *TU = PTUI.out_TU)
2924 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002925 }
2926
2927 return PTUI.result;
2928}
2929
2930unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2931 return CXSaveTranslationUnit_None;
2932}
2933
2934namespace {
2935
2936struct SaveTranslationUnitInfo {
2937 CXTranslationUnit TU;
2938 const char *FileName;
2939 unsigned options;
2940 CXSaveError result;
2941};
2942
2943}
2944
2945static void clang_saveTranslationUnit_Impl(void *UserData) {
2946 SaveTranslationUnitInfo *STUI =
2947 static_cast<SaveTranslationUnitInfo*>(UserData);
2948
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002949 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002950 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2951 setThreadBackgroundPriority();
2952
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002953 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002954 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2955}
2956
2957int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2958 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002959 LOG_FUNC_SECTION {
2960 *Log << TU << ' ' << FileName;
2961 }
2962
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002963 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002964 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002965 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002966 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002967
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002968 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002969 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2970 if (!CXXUnit->hasSema())
2971 return CXSaveError_InvalidTU;
2972
2973 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2974
2975 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2976 getenv("LIBCLANG_NOTHREADS")) {
2977 clang_saveTranslationUnit_Impl(&STUI);
2978
2979 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2980 PrintLibclangResourceUsage(TU);
2981
2982 return STUI.result;
2983 }
2984
2985 // We have an AST that has invalid nodes due to compiler errors.
2986 // Use a crash recovery thread for protection.
2987
2988 llvm::CrashRecoveryContext CRC;
2989
2990 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2991 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2992 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2993 fprintf(stderr, " 'options' : %d,\n", options);
2994 fprintf(stderr, "}\n");
2995
2996 return CXSaveError_Unknown;
2997
2998 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2999 PrintLibclangResourceUsage(TU);
3000 }
3001
3002 return STUI.result;
3003}
3004
3005void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3006 if (CTUnit) {
3007 // If the translation unit has been marked as unsafe to free, just discard
3008 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003009 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3010 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 return;
3012
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003013 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003014 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003015 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3016 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003017 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003018 delete CTUnit;
3019 }
3020}
3021
3022unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3023 return CXReparse_None;
3024}
3025
3026struct ReparseTranslationUnitInfo {
3027 CXTranslationUnit TU;
3028 unsigned num_unsaved_files;
3029 struct CXUnsavedFile *unsaved_files;
3030 unsigned options;
3031 int result;
3032};
3033
3034static void clang_reparseTranslationUnit_Impl(void *UserData) {
3035 ReparseTranslationUnitInfo *RTUI =
3036 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003037 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003038
Guy Benyei11169dd2012-12-18 14:30:41 +00003039 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003040 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3041 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3042 unsigned options = RTUI->options;
3043 (void) options;
3044
3045 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003046 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003047 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003048 RTUI->result = CXError_InvalidArguments;
3049 return;
3050 }
Craig Topper69186e72014-06-08 08:38:04 +00003051 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003052 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003053 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003054 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003055
3056 // Reset the associated diagnostics.
3057 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003058 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003059
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003060 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003061 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3062 setThreadBackgroundPriority();
3063
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003064 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003065 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003066
3067 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3068 new std::vector<ASTUnit::RemappedFile>());
3069
Guy Benyei11169dd2012-12-18 14:30:41 +00003070 // Recover resources if we crash before exiting this function.
3071 llvm::CrashRecoveryContextCleanupRegistrar<
3072 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3073
3074 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3075 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
David Blaikie66cc07b2014-06-27 17:40:03 +00003076 llvm::MemoryBuffer *Buffer =
3077 llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
Guy Benyei11169dd2012-12-18 14:30:41 +00003078 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3079 Buffer));
3080 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003081
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003082 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003083 RTUI->result = CXError_Success;
3084 else if (isASTReadError(CXXUnit))
3085 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003086}
3087
3088int clang_reparseTranslationUnit(CXTranslationUnit TU,
3089 unsigned num_unsaved_files,
3090 struct CXUnsavedFile *unsaved_files,
3091 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003092 LOG_FUNC_SECTION {
3093 *Log << TU;
3094 }
3095
Guy Benyei11169dd2012-12-18 14:30:41 +00003096 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003097 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003098
3099 if (getenv("LIBCLANG_NOTHREADS")) {
3100 clang_reparseTranslationUnit_Impl(&RTUI);
3101 return RTUI.result;
3102 }
3103
3104 llvm::CrashRecoveryContext CRC;
3105
3106 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3107 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003108 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003109 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003110 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3111 PrintLibclangResourceUsage(TU);
3112
3113 return RTUI.result;
3114}
3115
3116
3117CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003118 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003119 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003120 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003121 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003122
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003123 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003124 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003125}
3126
3127CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003128 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003129 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003130 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003131 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003132
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003133 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003134 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3135}
3136
3137} // end: extern "C"
3138
3139//===----------------------------------------------------------------------===//
3140// CXFile Operations.
3141//===----------------------------------------------------------------------===//
3142
3143extern "C" {
3144CXString clang_getFileName(CXFile SFile) {
3145 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003146 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003147
3148 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003149 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003150}
3151
3152time_t clang_getFileTime(CXFile SFile) {
3153 if (!SFile)
3154 return 0;
3155
3156 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3157 return FEnt->getModificationTime();
3158}
3159
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003160CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003161 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003162 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003163 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003164 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003165
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003166 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003167
3168 FileManager &FMgr = CXXUnit->getFileManager();
3169 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3170}
3171
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003172unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3173 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003174 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003175 LOG_BAD_TU(TU);
3176 return 0;
3177 }
3178
3179 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 return 0;
3181
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003182 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 FileEntry *FEnt = static_cast<FileEntry *>(file);
3184 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3185 .isFileMultipleIncludeGuarded(FEnt);
3186}
3187
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003188int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3189 if (!file || !outID)
3190 return 1;
3191
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003192 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003193 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3194 outID->data[0] = ID.getDevice();
3195 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003196 outID->data[2] = FEnt->getModificationTime();
3197 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003198}
3199
Guy Benyei11169dd2012-12-18 14:30:41 +00003200} // end: extern "C"
3201
3202//===----------------------------------------------------------------------===//
3203// CXCursor Operations.
3204//===----------------------------------------------------------------------===//
3205
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003206static const Decl *getDeclFromExpr(const Stmt *E) {
3207 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return getDeclFromExpr(CE->getSubExpr());
3209
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003210 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003212 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003214 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003216 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 if (PRE->isExplicitProperty())
3218 return PRE->getExplicitProperty();
3219 // It could be messaging both getter and setter as in:
3220 // ++myobj.myprop;
3221 // in which case prefer to associate the setter since it is less obvious
3222 // from inspecting the source that the setter is going to get called.
3223 if (PRE->isMessagingSetter())
3224 return PRE->getImplicitPropertySetter();
3225 return PRE->getImplicitPropertyGetter();
3226 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003227 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003228 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003229 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003230 if (Expr *Src = OVE->getSourceExpr())
3231 return getDeclFromExpr(Src);
3232
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003233 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003235 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 if (!CE->isElidable())
3237 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003238 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003239 return OME->getMethodDecl();
3240
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003241 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003242 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003243 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3245 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003246 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003247 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3248 isa<ParmVarDecl>(SizeOfPack->getPack()))
3249 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003250
3251 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003252}
3253
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003254static SourceLocation getLocationFromExpr(const Expr *E) {
3255 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003256 return getLocationFromExpr(CE->getSubExpr());
3257
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003258 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003260 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003262 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003264 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003266 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003268 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 return PropRef->getLocation();
3270
3271 return E->getLocStart();
3272}
3273
3274extern "C" {
3275
3276unsigned clang_visitChildren(CXCursor parent,
3277 CXCursorVisitor visitor,
3278 CXClientData client_data) {
3279 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3280 /*VisitPreprocessorLast=*/false);
3281 return CursorVis.VisitChildren(parent);
3282}
3283
3284#ifndef __has_feature
3285#define __has_feature(x) 0
3286#endif
3287#if __has_feature(blocks)
3288typedef enum CXChildVisitResult
3289 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3290
3291static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3292 CXClientData client_data) {
3293 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3294 return block(cursor, parent);
3295}
3296#else
3297// If we are compiled with a compiler that doesn't have native blocks support,
3298// define and call the block manually, so the
3299typedef struct _CXChildVisitResult
3300{
3301 void *isa;
3302 int flags;
3303 int reserved;
3304 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3305 CXCursor);
3306} *CXCursorVisitorBlock;
3307
3308static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3309 CXClientData client_data) {
3310 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3311 return block->invoke(block, cursor, parent);
3312}
3313#endif
3314
3315
3316unsigned clang_visitChildrenWithBlock(CXCursor parent,
3317 CXCursorVisitorBlock block) {
3318 return clang_visitChildren(parent, visitWithBlock, block);
3319}
3320
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003321static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003323 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003324
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003325 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003327 if (const ObjCPropertyImplDecl *PropImpl =
3328 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003330 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003331
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003332 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003334 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003335
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003336 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 }
3338
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003339 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003340 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003341
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003342 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3344 // and returns different names. NamedDecl returns the class name and
3345 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003346 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003347
3348 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003349 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003350
3351 SmallString<1024> S;
3352 llvm::raw_svector_ostream os(S);
3353 ND->printName(os);
3354
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003355 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003356}
3357
3358CXString clang_getCursorSpelling(CXCursor C) {
3359 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003360 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003361
3362 if (clang_isReference(C.kind)) {
3363 switch (C.kind) {
3364 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003365 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003366 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 }
3368 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003369 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003370 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 }
3372 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003373 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003375 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 }
3377 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003378 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003379 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 }
3381 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003382 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 assert(Type && "Missing type decl");
3384
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003385 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 getAsString());
3387 }
3388 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003389 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 assert(Template && "Missing template decl");
3391
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003392 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 }
3394
3395 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003396 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 assert(NS && "Missing namespace decl");
3398
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003399 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 }
3401
3402 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003403 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 assert(Field && "Missing member decl");
3405
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003406 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 }
3408
3409 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003410 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 assert(Label && "Missing label");
3412
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003413 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003414 }
3415
3416 case CXCursor_OverloadedDeclRef: {
3417 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003418 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3419 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003420 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003421 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003423 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003424 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 OverloadedTemplateStorage *Ovl
3426 = Storage.get<OverloadedTemplateStorage*>();
3427 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003428 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003429 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003430 }
3431
3432 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003433 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 assert(Var && "Missing variable decl");
3435
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003436 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 }
3438
3439 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003440 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 }
3442 }
3443
3444 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003445 const Expr *E = getCursorExpr(C);
3446
3447 if (C.kind == CXCursor_ObjCStringLiteral ||
3448 C.kind == CXCursor_StringLiteral) {
3449 const StringLiteral *SLit;
3450 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3451 SLit = OSL->getString();
3452 } else {
3453 SLit = cast<StringLiteral>(E);
3454 }
3455 SmallString<256> Buf;
3456 llvm::raw_svector_ostream OS(Buf);
3457 SLit->outputString(OS);
3458 return cxstring::createDup(OS.str());
3459 }
3460
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003461 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 if (D)
3463 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003464 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 }
3466
3467 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003468 const Stmt *S = getCursorStmt(C);
3469 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003470 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003471
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003472 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 }
3474
3475 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003476 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003477 ->getNameStart());
3478
3479 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003480 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 ->getNameStart());
3482
3483 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003484 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003485
3486 if (clang_isDeclaration(C.kind))
3487 return getDeclSpelling(getCursorDecl(C));
3488
3489 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003490 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003491 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 }
3493
3494 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003495 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003496 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 }
3498
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003499 if (C.kind == CXCursor_PackedAttr) {
3500 return cxstring::createRef("packed");
3501 }
3502
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003503 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003504}
3505
3506CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3507 unsigned pieceIndex,
3508 unsigned options) {
3509 if (clang_Cursor_isNull(C))
3510 return clang_getNullRange();
3511
3512 ASTContext &Ctx = getCursorContext(C);
3513
3514 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003515 const Stmt *S = getCursorStmt(C);
3516 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 if (pieceIndex > 0)
3518 return clang_getNullRange();
3519 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3520 }
3521
3522 return clang_getNullRange();
3523 }
3524
3525 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003526 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3528 if (pieceIndex >= ME->getNumSelectorLocs())
3529 return clang_getNullRange();
3530 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3531 }
3532 }
3533
3534 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3535 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003536 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3538 if (pieceIndex >= MD->getNumSelectorLocs())
3539 return clang_getNullRange();
3540 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3541 }
3542 }
3543
3544 if (C.kind == CXCursor_ObjCCategoryDecl ||
3545 C.kind == CXCursor_ObjCCategoryImplDecl) {
3546 if (pieceIndex > 0)
3547 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003548 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3550 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003551 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3553 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3554 }
3555
3556 if (C.kind == CXCursor_ModuleImportDecl) {
3557 if (pieceIndex > 0)
3558 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003559 if (const ImportDecl *ImportD =
3560 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3562 if (!Locs.empty())
3563 return cxloc::translateSourceRange(Ctx,
3564 SourceRange(Locs.front(), Locs.back()));
3565 }
3566 return clang_getNullRange();
3567 }
3568
3569 // FIXME: A CXCursor_InclusionDirective should give the location of the
3570 // filename, but we don't keep track of this.
3571
3572 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3573 // but we don't keep track of this.
3574
3575 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3576 // but we don't keep track of this.
3577
3578 // Default handling, give the location of the cursor.
3579
3580 if (pieceIndex > 0)
3581 return clang_getNullRange();
3582
3583 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3584 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3585 return cxloc::translateSourceRange(Ctx, Loc);
3586}
3587
3588CXString clang_getCursorDisplayName(CXCursor C) {
3589 if (!clang_isDeclaration(C.kind))
3590 return clang_getCursorSpelling(C);
3591
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003592 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003594 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003595
3596 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003597 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 D = FunTmpl->getTemplatedDecl();
3599
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003600 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 SmallString<64> Str;
3602 llvm::raw_svector_ostream OS(Str);
3603 OS << *Function;
3604 if (Function->getPrimaryTemplate())
3605 OS << "<>";
3606 OS << "(";
3607 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3608 if (I)
3609 OS << ", ";
3610 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3611 }
3612
3613 if (Function->isVariadic()) {
3614 if (Function->getNumParams())
3615 OS << ", ";
3616 OS << "...";
3617 }
3618 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003619 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 }
3621
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003622 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 SmallString<64> Str;
3624 llvm::raw_svector_ostream OS(Str);
3625 OS << *ClassTemplate;
3626 OS << "<";
3627 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3628 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3629 if (I)
3630 OS << ", ";
3631
3632 NamedDecl *Param = Params->getParam(I);
3633 if (Param->getIdentifier()) {
3634 OS << Param->getIdentifier()->getName();
3635 continue;
3636 }
3637
3638 // There is no parameter name, which makes this tricky. Try to come up
3639 // with something useful that isn't too long.
3640 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3641 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3642 else if (NonTypeTemplateParmDecl *NTTP
3643 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3644 OS << NTTP->getType().getAsString(Policy);
3645 else
3646 OS << "template<...> class";
3647 }
3648
3649 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003650 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 }
3652
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003653 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3655 // If the type was explicitly written, use that.
3656 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003657 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003658
Benjamin Kramer9170e912013-02-22 15:46:01 +00003659 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 llvm::raw_svector_ostream OS(Str);
3661 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003662 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 ClassSpec->getTemplateArgs().data(),
3664 ClassSpec->getTemplateArgs().size(),
3665 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003666 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 }
3668
3669 return clang_getCursorSpelling(C);
3670}
3671
3672CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3673 switch (Kind) {
3674 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003802 case CXCursor_ObjCSelfExpr:
3803 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003920 case CXCursor_PackedAttr:
3921 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003922 case CXCursor_PureAttr:
3923 return cxstring::createRef("attribute(pure)");
3924 case CXCursor_ConstAttr:
3925 return cxstring::createRef("attribute(const)");
3926 case CXCursor_NoDuplicateAttr:
3927 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003928 case CXCursor_CUDAConstantAttr:
3929 return cxstring::createRef("attribute(constant)");
3930 case CXCursor_CUDADeviceAttr:
3931 return cxstring::createRef("attribute(device)");
3932 case CXCursor_CUDAGlobalAttr:
3933 return cxstring::createRef("attribute(global)");
3934 case CXCursor_CUDAHostAttr:
3935 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003984 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003985 return cxstring::createRef("OMPParallelDirective");
3986 case CXCursor_OMPSimdDirective:
3987 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003988 case CXCursor_OMPForDirective:
3989 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00003990 case CXCursor_OMPSectionsDirective:
3991 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00003992 case CXCursor_OMPSectionDirective:
3993 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00003994 case CXCursor_OMPSingleDirective:
3995 return cxstring::createRef("OMPSingleDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 }
3997
3998 llvm_unreachable("Unhandled CXCursorKind");
3999}
4000
4001struct GetCursorData {
4002 SourceLocation TokenBeginLoc;
4003 bool PointsAtMacroArgExpansion;
4004 bool VisitedObjCPropertyImplDecl;
4005 SourceLocation VisitedDeclaratorDeclStartLoc;
4006 CXCursor &BestCursor;
4007
4008 GetCursorData(SourceManager &SM,
4009 SourceLocation tokenBegin, CXCursor &outputCursor)
4010 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4011 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4012 VisitedObjCPropertyImplDecl = false;
4013 }
4014};
4015
4016static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4017 CXCursor parent,
4018 CXClientData client_data) {
4019 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4020 CXCursor *BestCursor = &Data->BestCursor;
4021
4022 // If we point inside a macro argument we should provide info of what the
4023 // token is so use the actual cursor, don't replace it with a macro expansion
4024 // cursor.
4025 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4026 return CXChildVisit_Recurse;
4027
4028 if (clang_isDeclaration(cursor.kind)) {
4029 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004030 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4032 if (MD->isImplicit())
4033 return CXChildVisit_Break;
4034
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004035 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4037 // Check that when we have multiple @class references in the same line,
4038 // that later ones do not override the previous ones.
4039 // If we have:
4040 // @class Foo, Bar;
4041 // source ranges for both start at '@', so 'Bar' will end up overriding
4042 // 'Foo' even though the cursor location was at 'Foo'.
4043 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4044 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004045 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4047 if (PrevID != ID &&
4048 !PrevID->isThisDeclarationADefinition() &&
4049 !ID->isThisDeclarationADefinition())
4050 return CXChildVisit_Break;
4051 }
4052
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004053 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4055 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4056 // Check that when we have multiple declarators in the same line,
4057 // that later ones do not override the previous ones.
4058 // If we have:
4059 // int Foo, Bar;
4060 // source ranges for both start at 'int', so 'Bar' will end up overriding
4061 // 'Foo' even though the cursor location was at 'Foo'.
4062 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4063 return CXChildVisit_Break;
4064 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4065
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004066 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4068 (void)PropImp;
4069 // Check that when we have multiple @synthesize in the same line,
4070 // that later ones do not override the previous ones.
4071 // If we have:
4072 // @synthesize Foo, Bar;
4073 // source ranges for both start at '@', so 'Bar' will end up overriding
4074 // 'Foo' even though the cursor location was at 'Foo'.
4075 if (Data->VisitedObjCPropertyImplDecl)
4076 return CXChildVisit_Break;
4077 Data->VisitedObjCPropertyImplDecl = true;
4078 }
4079 }
4080
4081 if (clang_isExpression(cursor.kind) &&
4082 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004083 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 // Avoid having the cursor of an expression replace the declaration cursor
4085 // when the expression source range overlaps the declaration range.
4086 // This can happen for C++ constructor expressions whose range generally
4087 // include the variable declaration, e.g.:
4088 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4089 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4090 D->getLocation() == Data->TokenBeginLoc)
4091 return CXChildVisit_Break;
4092 }
4093 }
4094
4095 // If our current best cursor is the construction of a temporary object,
4096 // don't replace that cursor with a type reference, because we want
4097 // clang_getCursor() to point at the constructor.
4098 if (clang_isExpression(BestCursor->kind) &&
4099 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4100 cursor.kind == CXCursor_TypeRef) {
4101 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4102 // as having the actual point on the type reference.
4103 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4104 return CXChildVisit_Recurse;
4105 }
4106
4107 *BestCursor = cursor;
4108 return CXChildVisit_Recurse;
4109}
4110
4111CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004112 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004113 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004115 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004116
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004117 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4119
4120 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4121 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4122
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004123 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 CXFile SearchFile;
4125 unsigned SearchLine, SearchColumn;
4126 CXFile ResultFile;
4127 unsigned ResultLine, ResultColumn;
4128 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4129 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4130 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004131
4132 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4133 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004134 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004135 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 SearchFileName = clang_getFileName(SearchFile);
4137 ResultFileName = clang_getFileName(ResultFile);
4138 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4139 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004140 *Log << llvm::format("(%s:%d:%d) = %s",
4141 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4142 clang_getCString(KindSpelling))
4143 << llvm::format("(%s:%d:%d):%s%s",
4144 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4145 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 clang_disposeString(SearchFileName);
4147 clang_disposeString(ResultFileName);
4148 clang_disposeString(KindSpelling);
4149 clang_disposeString(USR);
4150
4151 CXCursor Definition = clang_getCursorDefinition(Result);
4152 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4153 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4154 CXString DefinitionKindSpelling
4155 = clang_getCursorKindSpelling(Definition.kind);
4156 CXFile DefinitionFile;
4157 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004158 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004159 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004161 *Log << llvm::format(" -> %s(%s:%d:%d)",
4162 clang_getCString(DefinitionKindSpelling),
4163 clang_getCString(DefinitionFileName),
4164 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 clang_disposeString(DefinitionFileName);
4166 clang_disposeString(DefinitionKindSpelling);
4167 }
4168 }
4169
4170 return Result;
4171}
4172
4173CXCursor clang_getNullCursor(void) {
4174 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4175}
4176
4177unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004178 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4179 // can't set consistently. For example, when visiting a DeclStmt we will set
4180 // it but we don't set it on the result of clang_getCursorDefinition for
4181 // a reference of the same declaration.
4182 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4183 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4184 // to provide that kind of info.
4185 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004186 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004187 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004188 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004189
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 return X == Y;
4191}
4192
4193unsigned clang_hashCursor(CXCursor C) {
4194 unsigned Index = 0;
4195 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4196 Index = 1;
4197
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004198 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 std::make_pair(C.kind, C.data[Index]));
4200}
4201
4202unsigned clang_isInvalid(enum CXCursorKind K) {
4203 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4204}
4205
4206unsigned clang_isDeclaration(enum CXCursorKind K) {
4207 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4208 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4209}
4210
4211unsigned clang_isReference(enum CXCursorKind K) {
4212 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4213}
4214
4215unsigned clang_isExpression(enum CXCursorKind K) {
4216 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4217}
4218
4219unsigned clang_isStatement(enum CXCursorKind K) {
4220 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4221}
4222
4223unsigned clang_isAttribute(enum CXCursorKind K) {
4224 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4225}
4226
4227unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4228 return K == CXCursor_TranslationUnit;
4229}
4230
4231unsigned clang_isPreprocessing(enum CXCursorKind K) {
4232 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4233}
4234
4235unsigned clang_isUnexposed(enum CXCursorKind K) {
4236 switch (K) {
4237 case CXCursor_UnexposedDecl:
4238 case CXCursor_UnexposedExpr:
4239 case CXCursor_UnexposedStmt:
4240 case CXCursor_UnexposedAttr:
4241 return true;
4242 default:
4243 return false;
4244 }
4245}
4246
4247CXCursorKind clang_getCursorKind(CXCursor C) {
4248 return C.kind;
4249}
4250
4251CXSourceLocation clang_getCursorLocation(CXCursor C) {
4252 if (clang_isReference(C.kind)) {
4253 switch (C.kind) {
4254 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004255 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 = getCursorObjCSuperClassRef(C);
4257 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4258 }
4259
4260 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004261 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 = getCursorObjCProtocolRef(C);
4263 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4264 }
4265
4266 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004267 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 = getCursorObjCClassRef(C);
4269 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4270 }
4271
4272 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004273 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4275 }
4276
4277 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004278 std::pair<const TemplateDecl *, SourceLocation> P =
4279 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4281 }
4282
4283 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004284 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4286 }
4287
4288 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004289 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4291 }
4292
4293 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004294 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4296 }
4297
4298 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004299 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 if (!BaseSpec)
4301 return clang_getNullLocation();
4302
4303 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4304 return cxloc::translateSourceLocation(getCursorContext(C),
4305 TSInfo->getTypeLoc().getBeginLoc());
4306
4307 return cxloc::translateSourceLocation(getCursorContext(C),
4308 BaseSpec->getLocStart());
4309 }
4310
4311 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004312 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004313 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4314 }
4315
4316 case CXCursor_OverloadedDeclRef:
4317 return cxloc::translateSourceLocation(getCursorContext(C),
4318 getCursorOverloadedDeclRef(C).second);
4319
4320 default:
4321 // FIXME: Need a way to enumerate all non-reference cases.
4322 llvm_unreachable("Missed a reference kind");
4323 }
4324 }
4325
4326 if (clang_isExpression(C.kind))
4327 return cxloc::translateSourceLocation(getCursorContext(C),
4328 getLocationFromExpr(getCursorExpr(C)));
4329
4330 if (clang_isStatement(C.kind))
4331 return cxloc::translateSourceLocation(getCursorContext(C),
4332 getCursorStmt(C)->getLocStart());
4333
4334 if (C.kind == CXCursor_PreprocessingDirective) {
4335 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4336 return cxloc::translateSourceLocation(getCursorContext(C), L);
4337 }
4338
4339 if (C.kind == CXCursor_MacroExpansion) {
4340 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004341 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004342 return cxloc::translateSourceLocation(getCursorContext(C), L);
4343 }
4344
4345 if (C.kind == CXCursor_MacroDefinition) {
4346 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4347 return cxloc::translateSourceLocation(getCursorContext(C), L);
4348 }
4349
4350 if (C.kind == CXCursor_InclusionDirective) {
4351 SourceLocation L
4352 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4353 return cxloc::translateSourceLocation(getCursorContext(C), L);
4354 }
4355
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004356 if (clang_isAttribute(C.kind)) {
4357 SourceLocation L
4358 = cxcursor::getCursorAttr(C)->getLocation();
4359 return cxloc::translateSourceLocation(getCursorContext(C), L);
4360 }
4361
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 if (!clang_isDeclaration(C.kind))
4363 return clang_getNullLocation();
4364
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004365 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004366 if (!D)
4367 return clang_getNullLocation();
4368
4369 SourceLocation Loc = D->getLocation();
4370 // FIXME: Multiple variables declared in a single declaration
4371 // currently lack the information needed to correctly determine their
4372 // ranges when accounting for the type-specifier. We use context
4373 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4374 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004375 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 if (!cxcursor::isFirstInDeclGroup(C))
4377 Loc = VD->getLocation();
4378 }
4379
4380 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004381 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004382 Loc = MD->getSelectorStartLoc();
4383
4384 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4385}
4386
4387} // end extern "C"
4388
4389CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4390 assert(TU);
4391
4392 // Guard against an invalid SourceLocation, or we may assert in one
4393 // of the following calls.
4394 if (SLoc.isInvalid())
4395 return clang_getNullCursor();
4396
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004397 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004398
4399 // Translate the given source location to make it point at the beginning of
4400 // the token under the cursor.
4401 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4402 CXXUnit->getASTContext().getLangOpts());
4403
4404 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4405 if (SLoc.isValid()) {
4406 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4407 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4408 /*VisitPreprocessorLast=*/true,
4409 /*VisitIncludedEntities=*/false,
4410 SourceLocation(SLoc));
4411 CursorVis.visitFileRegion();
4412 }
4413
4414 return Result;
4415}
4416
4417static SourceRange getRawCursorExtent(CXCursor C) {
4418 if (clang_isReference(C.kind)) {
4419 switch (C.kind) {
4420 case CXCursor_ObjCSuperClassRef:
4421 return getCursorObjCSuperClassRef(C).second;
4422
4423 case CXCursor_ObjCProtocolRef:
4424 return getCursorObjCProtocolRef(C).second;
4425
4426 case CXCursor_ObjCClassRef:
4427 return getCursorObjCClassRef(C).second;
4428
4429 case CXCursor_TypeRef:
4430 return getCursorTypeRef(C).second;
4431
4432 case CXCursor_TemplateRef:
4433 return getCursorTemplateRef(C).second;
4434
4435 case CXCursor_NamespaceRef:
4436 return getCursorNamespaceRef(C).second;
4437
4438 case CXCursor_MemberRef:
4439 return getCursorMemberRef(C).second;
4440
4441 case CXCursor_CXXBaseSpecifier:
4442 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4443
4444 case CXCursor_LabelRef:
4445 return getCursorLabelRef(C).second;
4446
4447 case CXCursor_OverloadedDeclRef:
4448 return getCursorOverloadedDeclRef(C).second;
4449
4450 case CXCursor_VariableRef:
4451 return getCursorVariableRef(C).second;
4452
4453 default:
4454 // FIXME: Need a way to enumerate all non-reference cases.
4455 llvm_unreachable("Missed a reference kind");
4456 }
4457 }
4458
4459 if (clang_isExpression(C.kind))
4460 return getCursorExpr(C)->getSourceRange();
4461
4462 if (clang_isStatement(C.kind))
4463 return getCursorStmt(C)->getSourceRange();
4464
4465 if (clang_isAttribute(C.kind))
4466 return getCursorAttr(C)->getRange();
4467
4468 if (C.kind == CXCursor_PreprocessingDirective)
4469 return cxcursor::getCursorPreprocessingDirective(C);
4470
4471 if (C.kind == CXCursor_MacroExpansion) {
4472 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004473 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 return TU->mapRangeFromPreamble(Range);
4475 }
4476
4477 if (C.kind == CXCursor_MacroDefinition) {
4478 ASTUnit *TU = getCursorASTUnit(C);
4479 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4480 return TU->mapRangeFromPreamble(Range);
4481 }
4482
4483 if (C.kind == CXCursor_InclusionDirective) {
4484 ASTUnit *TU = getCursorASTUnit(C);
4485 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4486 return TU->mapRangeFromPreamble(Range);
4487 }
4488
4489 if (C.kind == CXCursor_TranslationUnit) {
4490 ASTUnit *TU = getCursorASTUnit(C);
4491 FileID MainID = TU->getSourceManager().getMainFileID();
4492 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4493 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4494 return SourceRange(Start, End);
4495 }
4496
4497 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004498 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 if (!D)
4500 return SourceRange();
4501
4502 SourceRange R = D->getSourceRange();
4503 // FIXME: Multiple variables declared in a single declaration
4504 // currently lack the information needed to correctly determine their
4505 // ranges when accounting for the type-specifier. We use context
4506 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4507 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004508 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 if (!cxcursor::isFirstInDeclGroup(C))
4510 R.setBegin(VD->getLocation());
4511 }
4512 return R;
4513 }
4514 return SourceRange();
4515}
4516
4517/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4518/// the decl-specifier-seq for declarations.
4519static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4520 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004521 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 if (!D)
4523 return SourceRange();
4524
4525 SourceRange R = D->getSourceRange();
4526
4527 // Adjust the start of the location for declarations preceded by
4528 // declaration specifiers.
4529 SourceLocation StartLoc;
4530 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4531 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4532 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004533 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4535 StartLoc = TI->getTypeLoc().getLocStart();
4536 }
4537
4538 if (StartLoc.isValid() && R.getBegin().isValid() &&
4539 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4540 R.setBegin(StartLoc);
4541
4542 // FIXME: Multiple variables declared in a single declaration
4543 // currently lack the information needed to correctly determine their
4544 // ranges when accounting for the type-specifier. We use context
4545 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4546 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004547 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 if (!cxcursor::isFirstInDeclGroup(C))
4549 R.setBegin(VD->getLocation());
4550 }
4551
4552 return R;
4553 }
4554
4555 return getRawCursorExtent(C);
4556}
4557
4558extern "C" {
4559
4560CXSourceRange clang_getCursorExtent(CXCursor C) {
4561 SourceRange R = getRawCursorExtent(C);
4562 if (R.isInvalid())
4563 return clang_getNullRange();
4564
4565 return cxloc::translateSourceRange(getCursorContext(C), R);
4566}
4567
4568CXCursor clang_getCursorReferenced(CXCursor C) {
4569 if (clang_isInvalid(C.kind))
4570 return clang_getNullCursor();
4571
4572 CXTranslationUnit tu = getCursorTU(C);
4573 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004574 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 if (!D)
4576 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004577 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004579 if (const ObjCPropertyImplDecl *PropImpl =
4580 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4582 return MakeCXCursor(Property, tu);
4583
4584 return C;
4585 }
4586
4587 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004588 const Expr *E = getCursorExpr(C);
4589 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 if (D) {
4591 CXCursor declCursor = MakeCXCursor(D, tu);
4592 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4593 declCursor);
4594 return declCursor;
4595 }
4596
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004597 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 return MakeCursorOverloadedDeclRef(Ovl, tu);
4599
4600 return clang_getNullCursor();
4601 }
4602
4603 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004604 const Stmt *S = getCursorStmt(C);
4605 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004606 if (LabelDecl *label = Goto->getLabel())
4607 if (LabelStmt *labelS = label->getStmt())
4608 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4609
4610 return clang_getNullCursor();
4611 }
4612
4613 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004614 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 return MakeMacroDefinitionCursor(Def, tu);
4616 }
4617
4618 if (!clang_isReference(C.kind))
4619 return clang_getNullCursor();
4620
4621 switch (C.kind) {
4622 case CXCursor_ObjCSuperClassRef:
4623 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4624
4625 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004626 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4627 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 return MakeCXCursor(Def, tu);
4629
4630 return MakeCXCursor(Prot, tu);
4631 }
4632
4633 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004634 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4635 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 return MakeCXCursor(Def, tu);
4637
4638 return MakeCXCursor(Class, tu);
4639 }
4640
4641 case CXCursor_TypeRef:
4642 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4643
4644 case CXCursor_TemplateRef:
4645 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4646
4647 case CXCursor_NamespaceRef:
4648 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4649
4650 case CXCursor_MemberRef:
4651 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4652
4653 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004654 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4656 tu ));
4657 }
4658
4659 case CXCursor_LabelRef:
4660 // FIXME: We end up faking the "parent" declaration here because we
4661 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004662 return MakeCXCursor(getCursorLabelRef(C).first,
4663 cxtu::getASTUnit(tu)->getASTContext()
4664 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 tu);
4666
4667 case CXCursor_OverloadedDeclRef:
4668 return C;
4669
4670 case CXCursor_VariableRef:
4671 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4672
4673 default:
4674 // We would prefer to enumerate all non-reference cursor kinds here.
4675 llvm_unreachable("Unhandled reference cursor kind");
4676 }
4677}
4678
4679CXCursor clang_getCursorDefinition(CXCursor C) {
4680 if (clang_isInvalid(C.kind))
4681 return clang_getNullCursor();
4682
4683 CXTranslationUnit TU = getCursorTU(C);
4684
4685 bool WasReference = false;
4686 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4687 C = clang_getCursorReferenced(C);
4688 WasReference = true;
4689 }
4690
4691 if (C.kind == CXCursor_MacroExpansion)
4692 return clang_getCursorReferenced(C);
4693
4694 if (!clang_isDeclaration(C.kind))
4695 return clang_getNullCursor();
4696
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004697 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004698 if (!D)
4699 return clang_getNullCursor();
4700
4701 switch (D->getKind()) {
4702 // Declaration kinds that don't really separate the notions of
4703 // declaration and definition.
4704 case Decl::Namespace:
4705 case Decl::Typedef:
4706 case Decl::TypeAlias:
4707 case Decl::TypeAliasTemplate:
4708 case Decl::TemplateTypeParm:
4709 case Decl::EnumConstant:
4710 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004711 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 case Decl::IndirectField:
4713 case Decl::ObjCIvar:
4714 case Decl::ObjCAtDefsField:
4715 case Decl::ImplicitParam:
4716 case Decl::ParmVar:
4717 case Decl::NonTypeTemplateParm:
4718 case Decl::TemplateTemplateParm:
4719 case Decl::ObjCCategoryImpl:
4720 case Decl::ObjCImplementation:
4721 case Decl::AccessSpec:
4722 case Decl::LinkageSpec:
4723 case Decl::ObjCPropertyImpl:
4724 case Decl::FileScopeAsm:
4725 case Decl::StaticAssert:
4726 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004727 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 case Decl::Label: // FIXME: Is this right??
4729 case Decl::ClassScopeFunctionSpecialization:
4730 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004731 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 return C;
4733
4734 // Declaration kinds that don't make any sense here, but are
4735 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004736 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 case Decl::TranslationUnit:
4738 break;
4739
4740 // Declaration kinds for which the definition is not resolvable.
4741 case Decl::UnresolvedUsingTypename:
4742 case Decl::UnresolvedUsingValue:
4743 break;
4744
4745 case Decl::UsingDirective:
4746 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4747 TU);
4748
4749 case Decl::NamespaceAlias:
4750 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4751
4752 case Decl::Enum:
4753 case Decl::Record:
4754 case Decl::CXXRecord:
4755 case Decl::ClassTemplateSpecialization:
4756 case Decl::ClassTemplatePartialSpecialization:
4757 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4758 return MakeCXCursor(Def, TU);
4759 return clang_getNullCursor();
4760
4761 case Decl::Function:
4762 case Decl::CXXMethod:
4763 case Decl::CXXConstructor:
4764 case Decl::CXXDestructor:
4765 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004766 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004768 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 return clang_getNullCursor();
4770 }
4771
Larisse Voufo39a1e502013-08-06 01:03:05 +00004772 case Decl::Var:
4773 case Decl::VarTemplateSpecialization:
4774 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004776 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 return MakeCXCursor(Def, TU);
4778 return clang_getNullCursor();
4779 }
4780
4781 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004782 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4784 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4785 return clang_getNullCursor();
4786 }
4787
4788 case Decl::ClassTemplate: {
4789 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4790 ->getDefinition())
4791 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4792 TU);
4793 return clang_getNullCursor();
4794 }
4795
Larisse Voufo39a1e502013-08-06 01:03:05 +00004796 case Decl::VarTemplate: {
4797 if (VarDecl *Def =
4798 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4799 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4800 return clang_getNullCursor();
4801 }
4802
Guy Benyei11169dd2012-12-18 14:30:41 +00004803 case Decl::Using:
4804 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4805 D->getLocation(), TU);
4806
4807 case Decl::UsingShadow:
4808 return clang_getCursorDefinition(
4809 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4810 TU));
4811
4812 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004813 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 if (Method->isThisDeclarationADefinition())
4815 return C;
4816
4817 // Dig out the method definition in the associated
4818 // @implementation, if we have it.
4819 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004820 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004821 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4822 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4823 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4824 Method->isInstanceMethod()))
4825 if (Def->isThisDeclarationADefinition())
4826 return MakeCXCursor(Def, TU);
4827
4828 return clang_getNullCursor();
4829 }
4830
4831 case Decl::ObjCCategory:
4832 if (ObjCCategoryImplDecl *Impl
4833 = cast<ObjCCategoryDecl>(D)->getImplementation())
4834 return MakeCXCursor(Impl, TU);
4835 return clang_getNullCursor();
4836
4837 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004838 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004839 return MakeCXCursor(Def, TU);
4840 return clang_getNullCursor();
4841
4842 case Decl::ObjCInterface: {
4843 // There are two notions of a "definition" for an Objective-C
4844 // class: the interface and its implementation. When we resolved a
4845 // reference to an Objective-C class, produce the @interface as
4846 // the definition; when we were provided with the interface,
4847 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004848 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004849 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004850 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 return MakeCXCursor(Def, TU);
4852 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4853 return MakeCXCursor(Impl, TU);
4854 return clang_getNullCursor();
4855 }
4856
4857 case Decl::ObjCProperty:
4858 // FIXME: We don't really know where to find the
4859 // ObjCPropertyImplDecls that implement this property.
4860 return clang_getNullCursor();
4861
4862 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004863 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004864 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004865 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004866 return MakeCXCursor(Def, TU);
4867
4868 return clang_getNullCursor();
4869
4870 case Decl::Friend:
4871 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4872 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4873 return clang_getNullCursor();
4874
4875 case Decl::FriendTemplate:
4876 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4877 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4878 return clang_getNullCursor();
4879 }
4880
4881 return clang_getNullCursor();
4882}
4883
4884unsigned clang_isCursorDefinition(CXCursor C) {
4885 if (!clang_isDeclaration(C.kind))
4886 return 0;
4887
4888 return clang_getCursorDefinition(C) == C;
4889}
4890
4891CXCursor clang_getCanonicalCursor(CXCursor C) {
4892 if (!clang_isDeclaration(C.kind))
4893 return C;
4894
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004895 if (const Decl *D = getCursorDecl(C)) {
4896 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004897 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4898 return MakeCXCursor(CatD, getCursorTU(C));
4899
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004900 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4901 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004902 return MakeCXCursor(IFD, getCursorTU(C));
4903
4904 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4905 }
4906
4907 return C;
4908}
4909
4910int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4911 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4912}
4913
4914unsigned clang_getNumOverloadedDecls(CXCursor C) {
4915 if (C.kind != CXCursor_OverloadedDeclRef)
4916 return 0;
4917
4918 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004919 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 return E->getNumDecls();
4921
4922 if (OverloadedTemplateStorage *S
4923 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4924 return S->size();
4925
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004926 const Decl *D = Storage.get<const Decl *>();
4927 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004928 return Using->shadow_size();
4929
4930 return 0;
4931}
4932
4933CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4934 if (cursor.kind != CXCursor_OverloadedDeclRef)
4935 return clang_getNullCursor();
4936
4937 if (index >= clang_getNumOverloadedDecls(cursor))
4938 return clang_getNullCursor();
4939
4940 CXTranslationUnit TU = getCursorTU(cursor);
4941 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004942 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004943 return MakeCXCursor(E->decls_begin()[index], TU);
4944
4945 if (OverloadedTemplateStorage *S
4946 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4947 return MakeCXCursor(S->begin()[index], TU);
4948
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004949 const Decl *D = Storage.get<const Decl *>();
4950 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004951 // FIXME: This is, unfortunately, linear time.
4952 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4953 std::advance(Pos, index);
4954 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4955 }
4956
4957 return clang_getNullCursor();
4958}
4959
4960void clang_getDefinitionSpellingAndExtent(CXCursor C,
4961 const char **startBuf,
4962 const char **endBuf,
4963 unsigned *startLine,
4964 unsigned *startColumn,
4965 unsigned *endLine,
4966 unsigned *endColumn) {
4967 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004968 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004969 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4970
4971 SourceManager &SM = FD->getASTContext().getSourceManager();
4972 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4973 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4974 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4975 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4976 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4977 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4978}
4979
4980
4981CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4982 unsigned PieceIndex) {
4983 RefNamePieces Pieces;
4984
4985 switch (C.kind) {
4986 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004987 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004988 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4989 E->getQualifierLoc().getSourceRange());
4990 break;
4991
4992 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004993 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4995 E->getQualifierLoc().getSourceRange(),
4996 E->getOptionalExplicitTemplateArgs());
4997 break;
4998
4999 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005000 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005001 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005002 const Expr *Callee = OCE->getCallee();
5003 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005004 Callee = ICE->getSubExpr();
5005
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005006 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5008 DRE->getQualifierLoc().getSourceRange());
5009 }
5010 break;
5011
5012 default:
5013 break;
5014 }
5015
5016 if (Pieces.empty()) {
5017 if (PieceIndex == 0)
5018 return clang_getCursorExtent(C);
5019 } else if (PieceIndex < Pieces.size()) {
5020 SourceRange R = Pieces[PieceIndex];
5021 if (R.isValid())
5022 return cxloc::translateSourceRange(getCursorContext(C), R);
5023 }
5024
5025 return clang_getNullRange();
5026}
5027
5028void clang_enableStackTraces(void) {
5029 llvm::sys::PrintStackTraceOnErrorSignal();
5030}
5031
5032void clang_executeOnThread(void (*fn)(void*), void *user_data,
5033 unsigned stack_size) {
5034 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5035}
5036
5037} // end: extern "C"
5038
5039//===----------------------------------------------------------------------===//
5040// Token-based Operations.
5041//===----------------------------------------------------------------------===//
5042
5043/* CXToken layout:
5044 * int_data[0]: a CXTokenKind
5045 * int_data[1]: starting token location
5046 * int_data[2]: token length
5047 * int_data[3]: reserved
5048 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5049 * otherwise unused.
5050 */
5051extern "C" {
5052
5053CXTokenKind clang_getTokenKind(CXToken CXTok) {
5054 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5055}
5056
5057CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5058 switch (clang_getTokenKind(CXTok)) {
5059 case CXToken_Identifier:
5060 case CXToken_Keyword:
5061 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005062 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005063 ->getNameStart());
5064
5065 case CXToken_Literal: {
5066 // We have stashed the starting pointer in the ptr_data field. Use it.
5067 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005068 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 }
5070
5071 case CXToken_Punctuation:
5072 case CXToken_Comment:
5073 break;
5074 }
5075
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005076 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005077 LOG_BAD_TU(TU);
5078 return cxstring::createEmpty();
5079 }
5080
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 // We have to find the starting buffer pointer the hard way, by
5082 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005083 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005085 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005086
5087 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5088 std::pair<FileID, unsigned> LocInfo
5089 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5090 bool Invalid = false;
5091 StringRef Buffer
5092 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5093 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005094 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005095
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005096 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005097}
5098
5099CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005100 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005101 LOG_BAD_TU(TU);
5102 return clang_getNullLocation();
5103 }
5104
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005105 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 if (!CXXUnit)
5107 return clang_getNullLocation();
5108
5109 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5110 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5111}
5112
5113CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005114 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005115 LOG_BAD_TU(TU);
5116 return clang_getNullRange();
5117 }
5118
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005119 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 if (!CXXUnit)
5121 return clang_getNullRange();
5122
5123 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5124 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5125}
5126
5127static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5128 SmallVectorImpl<CXToken> &CXTokens) {
5129 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5130 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005131 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005133 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005134
5135 // Cannot tokenize across files.
5136 if (BeginLocInfo.first != EndLocInfo.first)
5137 return;
5138
5139 // Create a lexer
5140 bool Invalid = false;
5141 StringRef Buffer
5142 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5143 if (Invalid)
5144 return;
5145
5146 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5147 CXXUnit->getASTContext().getLangOpts(),
5148 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5149 Lex.SetCommentRetentionState(true);
5150
5151 // Lex tokens until we hit the end of the range.
5152 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5153 Token Tok;
5154 bool previousWasAt = false;
5155 do {
5156 // Lex the next token
5157 Lex.LexFromRawLexer(Tok);
5158 if (Tok.is(tok::eof))
5159 break;
5160
5161 // Initialize the CXToken.
5162 CXToken CXTok;
5163
5164 // - Common fields
5165 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5166 CXTok.int_data[2] = Tok.getLength();
5167 CXTok.int_data[3] = 0;
5168
5169 // - Kind-specific fields
5170 if (Tok.isLiteral()) {
5171 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005172 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005173 } else if (Tok.is(tok::raw_identifier)) {
5174 // Lookup the identifier to determine whether we have a keyword.
5175 IdentifierInfo *II
5176 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5177
5178 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5179 CXTok.int_data[0] = CXToken_Keyword;
5180 }
5181 else {
5182 CXTok.int_data[0] = Tok.is(tok::identifier)
5183 ? CXToken_Identifier
5184 : CXToken_Keyword;
5185 }
5186 CXTok.ptr_data = II;
5187 } else if (Tok.is(tok::comment)) {
5188 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005189 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 } else {
5191 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005192 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 }
5194 CXTokens.push_back(CXTok);
5195 previousWasAt = Tok.is(tok::at);
5196 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5197}
5198
5199void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5200 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005201 LOG_FUNC_SECTION {
5202 *Log << TU << ' ' << Range;
5203 }
5204
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005206 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005207 if (NumTokens)
5208 *NumTokens = 0;
5209
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005210 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005211 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005212 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005213 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005214
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005215 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 if (!CXXUnit || !Tokens || !NumTokens)
5217 return;
5218
5219 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5220
5221 SourceRange R = cxloc::translateCXSourceRange(Range);
5222 if (R.isInvalid())
5223 return;
5224
5225 SmallVector<CXToken, 32> CXTokens;
5226 getTokens(CXXUnit, R, CXTokens);
5227
5228 if (CXTokens.empty())
5229 return;
5230
5231 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5232 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5233 *NumTokens = CXTokens.size();
5234}
5235
5236void clang_disposeTokens(CXTranslationUnit TU,
5237 CXToken *Tokens, unsigned NumTokens) {
5238 free(Tokens);
5239}
5240
5241} // end: extern "C"
5242
5243//===----------------------------------------------------------------------===//
5244// Token annotation APIs.
5245//===----------------------------------------------------------------------===//
5246
Guy Benyei11169dd2012-12-18 14:30:41 +00005247static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5248 CXCursor parent,
5249 CXClientData client_data);
5250static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5251 CXClientData client_data);
5252
5253namespace {
5254class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 CXToken *Tokens;
5256 CXCursor *Cursors;
5257 unsigned NumTokens;
5258 unsigned TokIdx;
5259 unsigned PreprocessingTokIdx;
5260 CursorVisitor AnnotateVis;
5261 SourceManager &SrcMgr;
5262 bool HasContextSensitiveKeywords;
5263
5264 struct PostChildrenInfo {
5265 CXCursor Cursor;
5266 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005267 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 unsigned BeforeChildrenTokenIdx;
5269 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005270 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005271
5272 CXToken &getTok(unsigned Idx) {
5273 assert(Idx < NumTokens);
5274 return Tokens[Idx];
5275 }
5276 const CXToken &getTok(unsigned Idx) const {
5277 assert(Idx < NumTokens);
5278 return Tokens[Idx];
5279 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 bool MoreTokens() const { return TokIdx < NumTokens; }
5281 unsigned NextToken() const { return TokIdx; }
5282 void AdvanceToken() { ++TokIdx; }
5283 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005284 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 }
5286 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005287 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 }
5289 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005290 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005291 }
5292
5293 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005294 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005295 SourceRange);
5296
5297public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005298 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005299 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005300 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005301 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005302 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 AnnotateTokensVisitor, this,
5304 /*VisitPreprocessorLast=*/true,
5305 /*VisitIncludedEntities=*/false,
5306 RegionOfInterest,
5307 /*VisitDeclsOnly=*/false,
5308 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005309 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 HasContextSensitiveKeywords(false) { }
5311
5312 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5313 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5314 bool postVisitChildren(CXCursor cursor);
5315 void AnnotateTokens();
5316
5317 /// \brief Determine whether the annotator saw any cursors that have
5318 /// context-sensitive keywords.
5319 bool hasContextSensitiveKeywords() const {
5320 return HasContextSensitiveKeywords;
5321 }
5322
5323 ~AnnotateTokensWorker() {
5324 assert(PostChildrenInfos.empty());
5325 }
5326};
5327}
5328
5329void AnnotateTokensWorker::AnnotateTokens() {
5330 // Walk the AST within the region of interest, annotating tokens
5331 // along the way.
5332 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005333}
Guy Benyei11169dd2012-12-18 14:30:41 +00005334
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005335static inline void updateCursorAnnotation(CXCursor &Cursor,
5336 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005337 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005339 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005340}
5341
5342/// \brief It annotates and advances tokens with a cursor until the comparison
5343//// between the cursor location and the source range is the same as
5344/// \arg compResult.
5345///
5346/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5347/// Pass RangeOverlap to annotate tokens inside a range.
5348void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5349 RangeComparisonResult compResult,
5350 SourceRange range) {
5351 while (MoreTokens()) {
5352 const unsigned I = NextToken();
5353 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005354 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5355 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005356
5357 SourceLocation TokLoc = GetTokenLoc(I);
5358 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005359 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 AdvanceToken();
5361 continue;
5362 }
5363 break;
5364 }
5365}
5366
5367/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005368/// \returns true if it advanced beyond all macro tokens, false otherwise.
5369bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 CXCursor updateC,
5371 RangeComparisonResult compResult,
5372 SourceRange range) {
5373 assert(MoreTokens());
5374 assert(isFunctionMacroToken(NextToken()) &&
5375 "Should be called only for macro arg tokens");
5376
5377 // This works differently than annotateAndAdvanceTokens; because expanded
5378 // macro arguments can have arbitrary translation-unit source order, we do not
5379 // advance the token index one by one until a token fails the range test.
5380 // We only advance once past all of the macro arg tokens if all of them
5381 // pass the range test. If one of them fails we keep the token index pointing
5382 // at the start of the macro arg tokens so that the failing token will be
5383 // annotated by a subsequent annotation try.
5384
5385 bool atLeastOneCompFail = false;
5386
5387 unsigned I = NextToken();
5388 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5389 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5390 if (TokLoc.isFileID())
5391 continue; // not macro arg token, it's parens or comma.
5392 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5393 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5394 Cursors[I] = updateC;
5395 } else
5396 atLeastOneCompFail = true;
5397 }
5398
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005399 if (atLeastOneCompFail)
5400 return false;
5401
5402 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5403 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005404}
5405
5406enum CXChildVisitResult
5407AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 SourceRange cursorRange = getRawCursorExtent(cursor);
5409 if (cursorRange.isInvalid())
5410 return CXChildVisit_Recurse;
5411
5412 if (!HasContextSensitiveKeywords) {
5413 // Objective-C properties can have context-sensitive keywords.
5414 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005415 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005416 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5417 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5418 }
5419 // Objective-C methods can have context-sensitive keywords.
5420 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5421 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005422 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5424 if (Method->getObjCDeclQualifier())
5425 HasContextSensitiveKeywords = true;
5426 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005427 for (const auto *P : Method->params()) {
5428 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 HasContextSensitiveKeywords = true;
5430 break;
5431 }
5432 }
5433 }
5434 }
5435 }
5436 // C++ methods can have context-sensitive keywords.
5437 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005438 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5440 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5441 HasContextSensitiveKeywords = true;
5442 }
5443 }
5444 // C++ classes can have context-sensitive keywords.
5445 else if (cursor.kind == CXCursor_StructDecl ||
5446 cursor.kind == CXCursor_ClassDecl ||
5447 cursor.kind == CXCursor_ClassTemplate ||
5448 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005449 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005450 if (D->hasAttr<FinalAttr>())
5451 HasContextSensitiveKeywords = true;
5452 }
5453 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005454
5455 // Don't override a property annotation with its getter/setter method.
5456 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5457 parent.kind == CXCursor_ObjCPropertyDecl)
5458 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005459
5460 if (clang_isPreprocessing(cursor.kind)) {
5461 // Items in the preprocessing record are kept separate from items in
5462 // declarations, so we keep a separate token index.
5463 unsigned SavedTokIdx = TokIdx;
5464 TokIdx = PreprocessingTokIdx;
5465
5466 // Skip tokens up until we catch up to the beginning of the preprocessing
5467 // entry.
5468 while (MoreTokens()) {
5469 const unsigned I = NextToken();
5470 SourceLocation TokLoc = GetTokenLoc(I);
5471 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5472 case RangeBefore:
5473 AdvanceToken();
5474 continue;
5475 case RangeAfter:
5476 case RangeOverlap:
5477 break;
5478 }
5479 break;
5480 }
5481
5482 // Look at all of the tokens within this range.
5483 while (MoreTokens()) {
5484 const unsigned I = NextToken();
5485 SourceLocation TokLoc = GetTokenLoc(I);
5486 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5487 case RangeBefore:
5488 llvm_unreachable("Infeasible");
5489 case RangeAfter:
5490 break;
5491 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005492 // For macro expansions, just note where the beginning of the macro
5493 // expansion occurs.
5494 if (cursor.kind == CXCursor_MacroExpansion) {
5495 if (TokLoc == cursorRange.getBegin())
5496 Cursors[I] = cursor;
5497 AdvanceToken();
5498 break;
5499 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005500 // We may have already annotated macro names inside macro definitions.
5501 if (Cursors[I].kind != CXCursor_MacroExpansion)
5502 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005503 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005504 continue;
5505 }
5506 break;
5507 }
5508
5509 // Save the preprocessing token index; restore the non-preprocessing
5510 // token index.
5511 PreprocessingTokIdx = TokIdx;
5512 TokIdx = SavedTokIdx;
5513 return CXChildVisit_Recurse;
5514 }
5515
5516 if (cursorRange.isInvalid())
5517 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005518
5519 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005520 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005521 const enum CXCursorKind K = clang_getCursorKind(parent);
5522 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005523 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5524 // Attributes are annotated out-of-order, skip tokens until we reach it.
5525 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005526 ? clang_getNullCursor() : parent;
5527
5528 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5529
5530 // Avoid having the cursor of an expression "overwrite" the annotation of the
5531 // variable declaration that it belongs to.
5532 // This can happen for C++ constructor expressions whose range generally
5533 // include the variable declaration, e.g.:
5534 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005535 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005536 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005537 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005538 const unsigned I = NextToken();
5539 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5540 E->getLocStart() == D->getLocation() &&
5541 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005542 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005543 AdvanceToken();
5544 }
5545 }
5546 }
5547
5548 // Before recursing into the children keep some state that we are going
5549 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5550 // extra work after the child nodes are visited.
5551 // Note that we don't call VisitChildren here to avoid traversing statements
5552 // code-recursively which can blow the stack.
5553
5554 PostChildrenInfo Info;
5555 Info.Cursor = cursor;
5556 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005557 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005558 Info.BeforeChildrenTokenIdx = NextToken();
5559 PostChildrenInfos.push_back(Info);
5560
5561 return CXChildVisit_Recurse;
5562}
5563
5564bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5565 if (PostChildrenInfos.empty())
5566 return false;
5567 const PostChildrenInfo &Info = PostChildrenInfos.back();
5568 if (!clang_equalCursors(Info.Cursor, cursor))
5569 return false;
5570
5571 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5572 const unsigned AfterChildren = NextToken();
5573 SourceRange cursorRange = Info.CursorRange;
5574
5575 // Scan the tokens that are at the end of the cursor, but are not captured
5576 // but the child cursors.
5577 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5578
5579 // Scan the tokens that are at the beginning of the cursor, but are not
5580 // capture by the child cursors.
5581 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5582 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5583 break;
5584
5585 Cursors[I] = cursor;
5586 }
5587
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005588 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5589 // encountered the attribute cursor.
5590 if (clang_isAttribute(cursor.kind))
5591 TokIdx = Info.BeforeReachingCursorIdx;
5592
Guy Benyei11169dd2012-12-18 14:30:41 +00005593 PostChildrenInfos.pop_back();
5594 return false;
5595}
5596
5597static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5598 CXCursor parent,
5599 CXClientData client_data) {
5600 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5601}
5602
5603static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5604 CXClientData client_data) {
5605 return static_cast<AnnotateTokensWorker*>(client_data)->
5606 postVisitChildren(cursor);
5607}
5608
5609namespace {
5610
5611/// \brief Uses the macro expansions in the preprocessing record to find
5612/// and mark tokens that are macro arguments. This info is used by the
5613/// AnnotateTokensWorker.
5614class MarkMacroArgTokensVisitor {
5615 SourceManager &SM;
5616 CXToken *Tokens;
5617 unsigned NumTokens;
5618 unsigned CurIdx;
5619
5620public:
5621 MarkMacroArgTokensVisitor(SourceManager &SM,
5622 CXToken *tokens, unsigned numTokens)
5623 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5624
5625 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5626 if (cursor.kind != CXCursor_MacroExpansion)
5627 return CXChildVisit_Continue;
5628
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005629 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 if (macroRange.getBegin() == macroRange.getEnd())
5631 return CXChildVisit_Continue; // it's not a function macro.
5632
5633 for (; CurIdx < NumTokens; ++CurIdx) {
5634 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5635 macroRange.getBegin()))
5636 break;
5637 }
5638
5639 if (CurIdx == NumTokens)
5640 return CXChildVisit_Break;
5641
5642 for (; CurIdx < NumTokens; ++CurIdx) {
5643 SourceLocation tokLoc = getTokenLoc(CurIdx);
5644 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5645 break;
5646
5647 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5648 }
5649
5650 if (CurIdx == NumTokens)
5651 return CXChildVisit_Break;
5652
5653 return CXChildVisit_Continue;
5654 }
5655
5656private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005657 CXToken &getTok(unsigned Idx) {
5658 assert(Idx < NumTokens);
5659 return Tokens[Idx];
5660 }
5661 const CXToken &getTok(unsigned Idx) const {
5662 assert(Idx < NumTokens);
5663 return Tokens[Idx];
5664 }
5665
Guy Benyei11169dd2012-12-18 14:30:41 +00005666 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005667 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005668 }
5669
5670 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5671 // The third field is reserved and currently not used. Use it here
5672 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005673 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 }
5675};
5676
5677} // end anonymous namespace
5678
5679static CXChildVisitResult
5680MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5681 CXClientData client_data) {
5682 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5683 parent);
5684}
5685
5686namespace {
5687 struct clang_annotateTokens_Data {
5688 CXTranslationUnit TU;
5689 ASTUnit *CXXUnit;
5690 CXToken *Tokens;
5691 unsigned NumTokens;
5692 CXCursor *Cursors;
5693 };
5694}
5695
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005696/// \brief Used by \c annotatePreprocessorTokens.
5697/// \returns true if lexing was finished, false otherwise.
5698static bool lexNext(Lexer &Lex, Token &Tok,
5699 unsigned &NextIdx, unsigned NumTokens) {
5700 if (NextIdx >= NumTokens)
5701 return true;
5702
5703 ++NextIdx;
5704 Lex.LexFromRawLexer(Tok);
5705 if (Tok.is(tok::eof))
5706 return true;
5707
5708 return false;
5709}
5710
Guy Benyei11169dd2012-12-18 14:30:41 +00005711static void annotatePreprocessorTokens(CXTranslationUnit TU,
5712 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005713 CXCursor *Cursors,
5714 CXToken *Tokens,
5715 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005716 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005717
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005718 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005719 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5720 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005721 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005723 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005724
5725 if (BeginLocInfo.first != EndLocInfo.first)
5726 return;
5727
5728 StringRef Buffer;
5729 bool Invalid = false;
5730 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5731 if (Buffer.empty() || Invalid)
5732 return;
5733
5734 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5735 CXXUnit->getASTContext().getLangOpts(),
5736 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5737 Buffer.end());
5738 Lex.SetCommentRetentionState(true);
5739
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005740 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005741 // Lex tokens in raw mode until we hit the end of the range, to avoid
5742 // entering #includes or expanding macros.
5743 while (true) {
5744 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005745 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5746 break;
5747 unsigned TokIdx = NextIdx-1;
5748 assert(Tok.getLocation() ==
5749 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005750
5751 reprocess:
5752 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005753 // We have found a preprocessing directive. Annotate the tokens
5754 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005755 //
5756 // FIXME: Some simple tests here could identify macro definitions and
5757 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005758
5759 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005760 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5761 break;
5762
Craig Topper69186e72014-06-08 08:38:04 +00005763 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005764 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005765 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5766 break;
5767
5768 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005769 IdentifierInfo &II =
5770 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005771 SourceLocation MappedTokLoc =
5772 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5773 MI = getMacroInfo(II, MappedTokLoc, TU);
5774 }
5775 }
5776
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005777 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005779 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5780 finished = true;
5781 break;
5782 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005783 // If we are in a macro definition, check if the token was ever a
5784 // macro name and annotate it if that's the case.
5785 if (MI) {
5786 SourceLocation SaveLoc = Tok.getLocation();
5787 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5788 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5789 Tok.setLocation(SaveLoc);
5790 if (MacroDef)
5791 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5792 Tok.getLocation(), TU);
5793 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005794 } while (!Tok.isAtStartOfLine());
5795
5796 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5797 assert(TokIdx <= LastIdx);
5798 SourceLocation EndLoc =
5799 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5800 CXCursor Cursor =
5801 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5802
5803 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005804 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005805
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005806 if (finished)
5807 break;
5808 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005809 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005810 }
5811}
5812
5813// This gets run a separate thread to avoid stack blowout.
5814static void clang_annotateTokensImpl(void *UserData) {
5815 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5816 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5817 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5818 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5819 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5820
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005821 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005822 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5823 setThreadBackgroundPriority();
5824
5825 // Determine the region of interest, which contains all of the tokens.
5826 SourceRange RegionOfInterest;
5827 RegionOfInterest.setBegin(
5828 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5829 RegionOfInterest.setEnd(
5830 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5831 Tokens[NumTokens-1])));
5832
Guy Benyei11169dd2012-12-18 14:30:41 +00005833 // Relex the tokens within the source range to look for preprocessing
5834 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005835 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005836
5837 // If begin location points inside a macro argument, set it to the expansion
5838 // location so we can have the full context when annotating semantically.
5839 {
5840 SourceManager &SM = CXXUnit->getSourceManager();
5841 SourceLocation Loc =
5842 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5843 if (Loc.isMacroID())
5844 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5845 }
5846
Guy Benyei11169dd2012-12-18 14:30:41 +00005847 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5848 // Search and mark tokens that are macro argument expansions.
5849 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5850 Tokens, NumTokens);
5851 CursorVisitor MacroArgMarker(TU,
5852 MarkMacroArgTokensVisitorDelegate, &Visitor,
5853 /*VisitPreprocessorLast=*/true,
5854 /*VisitIncludedEntities=*/false,
5855 RegionOfInterest);
5856 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5857 }
5858
5859 // Annotate all of the source locations in the region of interest that map to
5860 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005861 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005862
5863 // FIXME: We use a ridiculous stack size here because the data-recursion
5864 // algorithm uses a large stack frame than the non-data recursive version,
5865 // and AnnotationTokensWorker currently transforms the data-recursion
5866 // algorithm back into a traditional recursion by explicitly calling
5867 // VisitChildren(). We will need to remove this explicit recursive call.
5868 W.AnnotateTokens();
5869
5870 // If we ran into any entities that involve context-sensitive keywords,
5871 // take another pass through the tokens to mark them as such.
5872 if (W.hasContextSensitiveKeywords()) {
5873 for (unsigned I = 0; I != NumTokens; ++I) {
5874 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5875 continue;
5876
5877 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5878 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005879 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005880 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5881 if (Property->getPropertyAttributesAsWritten() != 0 &&
5882 llvm::StringSwitch<bool>(II->getName())
5883 .Case("readonly", true)
5884 .Case("assign", true)
5885 .Case("unsafe_unretained", true)
5886 .Case("readwrite", true)
5887 .Case("retain", true)
5888 .Case("copy", true)
5889 .Case("nonatomic", true)
5890 .Case("atomic", true)
5891 .Case("getter", true)
5892 .Case("setter", true)
5893 .Case("strong", true)
5894 .Case("weak", true)
5895 .Default(false))
5896 Tokens[I].int_data[0] = CXToken_Keyword;
5897 }
5898 continue;
5899 }
5900
5901 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5902 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5903 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5904 if (llvm::StringSwitch<bool>(II->getName())
5905 .Case("in", true)
5906 .Case("out", true)
5907 .Case("inout", true)
5908 .Case("oneway", true)
5909 .Case("bycopy", true)
5910 .Case("byref", true)
5911 .Default(false))
5912 Tokens[I].int_data[0] = CXToken_Keyword;
5913 continue;
5914 }
5915
5916 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5917 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5918 Tokens[I].int_data[0] = CXToken_Keyword;
5919 continue;
5920 }
5921 }
5922 }
5923}
5924
5925extern "C" {
5926
5927void clang_annotateTokens(CXTranslationUnit TU,
5928 CXToken *Tokens, unsigned NumTokens,
5929 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005930 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005931 LOG_BAD_TU(TU);
5932 return;
5933 }
5934 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005935 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005936 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005937 }
5938
5939 LOG_FUNC_SECTION {
5940 *Log << TU << ' ';
5941 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5942 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5943 *Log << clang_getRange(bloc, eloc);
5944 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005945
5946 // Any token we don't specifically annotate will have a NULL cursor.
5947 CXCursor C = clang_getNullCursor();
5948 for (unsigned I = 0; I != NumTokens; ++I)
5949 Cursors[I] = C;
5950
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005951 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005952 if (!CXXUnit)
5953 return;
5954
5955 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5956
5957 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5958 llvm::CrashRecoveryContext CRC;
5959 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5960 GetSafetyThreadStackSize() * 2)) {
5961 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5962 }
5963}
5964
5965} // end: extern "C"
5966
5967//===----------------------------------------------------------------------===//
5968// Operations for querying linkage of a cursor.
5969//===----------------------------------------------------------------------===//
5970
5971extern "C" {
5972CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5973 if (!clang_isDeclaration(cursor.kind))
5974 return CXLinkage_Invalid;
5975
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005976 const Decl *D = cxcursor::getCursorDecl(cursor);
5977 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005978 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005979 case NoLinkage:
5980 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005981 case InternalLinkage: return CXLinkage_Internal;
5982 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5983 case ExternalLinkage: return CXLinkage_External;
5984 };
5985
5986 return CXLinkage_Invalid;
5987}
5988} // end: extern "C"
5989
5990//===----------------------------------------------------------------------===//
5991// Operations for querying language of a cursor.
5992//===----------------------------------------------------------------------===//
5993
5994static CXLanguageKind getDeclLanguage(const Decl *D) {
5995 if (!D)
5996 return CXLanguage_C;
5997
5998 switch (D->getKind()) {
5999 default:
6000 break;
6001 case Decl::ImplicitParam:
6002 case Decl::ObjCAtDefsField:
6003 case Decl::ObjCCategory:
6004 case Decl::ObjCCategoryImpl:
6005 case Decl::ObjCCompatibleAlias:
6006 case Decl::ObjCImplementation:
6007 case Decl::ObjCInterface:
6008 case Decl::ObjCIvar:
6009 case Decl::ObjCMethod:
6010 case Decl::ObjCProperty:
6011 case Decl::ObjCPropertyImpl:
6012 case Decl::ObjCProtocol:
6013 return CXLanguage_ObjC;
6014 case Decl::CXXConstructor:
6015 case Decl::CXXConversion:
6016 case Decl::CXXDestructor:
6017 case Decl::CXXMethod:
6018 case Decl::CXXRecord:
6019 case Decl::ClassTemplate:
6020 case Decl::ClassTemplatePartialSpecialization:
6021 case Decl::ClassTemplateSpecialization:
6022 case Decl::Friend:
6023 case Decl::FriendTemplate:
6024 case Decl::FunctionTemplate:
6025 case Decl::LinkageSpec:
6026 case Decl::Namespace:
6027 case Decl::NamespaceAlias:
6028 case Decl::NonTypeTemplateParm:
6029 case Decl::StaticAssert:
6030 case Decl::TemplateTemplateParm:
6031 case Decl::TemplateTypeParm:
6032 case Decl::UnresolvedUsingTypename:
6033 case Decl::UnresolvedUsingValue:
6034 case Decl::Using:
6035 case Decl::UsingDirective:
6036 case Decl::UsingShadow:
6037 return CXLanguage_CPlusPlus;
6038 }
6039
6040 return CXLanguage_C;
6041}
6042
6043extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006044
6045static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6046 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6047 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006048
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006049 switch (D->getAvailability()) {
6050 case AR_Available:
6051 case AR_NotYetIntroduced:
6052 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006053 return getCursorAvailabilityForDecl(
6054 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006055 return CXAvailability_Available;
6056
6057 case AR_Deprecated:
6058 return CXAvailability_Deprecated;
6059
6060 case AR_Unavailable:
6061 return CXAvailability_NotAvailable;
6062 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006063
6064 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006065}
6066
Guy Benyei11169dd2012-12-18 14:30:41 +00006067enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6068 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006069 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6070 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006071
6072 return CXAvailability_Available;
6073}
6074
6075static CXVersion convertVersion(VersionTuple In) {
6076 CXVersion Out = { -1, -1, -1 };
6077 if (In.empty())
6078 return Out;
6079
6080 Out.Major = In.getMajor();
6081
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006082 Optional<unsigned> Minor = In.getMinor();
6083 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006084 Out.Minor = *Minor;
6085 else
6086 return Out;
6087
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006088 Optional<unsigned> Subminor = In.getSubminor();
6089 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006090 Out.Subminor = *Subminor;
6091
6092 return Out;
6093}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006094
6095static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6096 int *always_deprecated,
6097 CXString *deprecated_message,
6098 int *always_unavailable,
6099 CXString *unavailable_message,
6100 CXPlatformAvailability *availability,
6101 int availability_size) {
6102 bool HadAvailAttr = false;
6103 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006104 for (auto A : D->attrs()) {
6105 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006106 HadAvailAttr = true;
6107 if (always_deprecated)
6108 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006109 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006110 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006111 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006112 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006113 continue;
6114 }
6115
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006116 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006117 HadAvailAttr = true;
6118 if (always_unavailable)
6119 *always_unavailable = 1;
6120 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006121 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006122 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6123 }
6124 continue;
6125 }
6126
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006127 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006128 HadAvailAttr = true;
6129 if (N < availability_size) {
6130 availability[N].Platform
6131 = cxstring::createDup(Avail->getPlatform()->getName());
6132 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6133 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6134 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6135 availability[N].Unavailable = Avail->getUnavailable();
6136 availability[N].Message = cxstring::createDup(Avail->getMessage());
6137 }
6138 ++N;
6139 }
6140 }
6141
6142 if (!HadAvailAttr)
6143 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6144 return getCursorPlatformAvailabilityForDecl(
6145 cast<Decl>(EnumConst->getDeclContext()),
6146 always_deprecated,
6147 deprecated_message,
6148 always_unavailable,
6149 unavailable_message,
6150 availability,
6151 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006152
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006153 return N;
6154}
6155
Guy Benyei11169dd2012-12-18 14:30:41 +00006156int clang_getCursorPlatformAvailability(CXCursor cursor,
6157 int *always_deprecated,
6158 CXString *deprecated_message,
6159 int *always_unavailable,
6160 CXString *unavailable_message,
6161 CXPlatformAvailability *availability,
6162 int availability_size) {
6163 if (always_deprecated)
6164 *always_deprecated = 0;
6165 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006166 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006167 if (always_unavailable)
6168 *always_unavailable = 0;
6169 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006170 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006171
Guy Benyei11169dd2012-12-18 14:30:41 +00006172 if (!clang_isDeclaration(cursor.kind))
6173 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006174
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006175 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 if (!D)
6177 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006178
6179 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6180 deprecated_message,
6181 always_unavailable,
6182 unavailable_message,
6183 availability,
6184 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006185}
6186
6187void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6188 clang_disposeString(availability->Platform);
6189 clang_disposeString(availability->Message);
6190}
6191
6192CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6193 if (clang_isDeclaration(cursor.kind))
6194 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6195
6196 return CXLanguage_Invalid;
6197}
6198
6199 /// \brief If the given cursor is the "templated" declaration
6200 /// descibing a class or function template, return the class or
6201 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006202static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006203 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006204 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006205
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006206 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006207 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6208 return FunTmpl;
6209
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006210 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006211 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6212 return ClassTmpl;
6213
6214 return D;
6215}
6216
6217CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6218 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006219 if (const Decl *D = getCursorDecl(cursor)) {
6220 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006221 if (!DC)
6222 return clang_getNullCursor();
6223
6224 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6225 getCursorTU(cursor));
6226 }
6227 }
6228
6229 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006230 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006231 return MakeCXCursor(D, getCursorTU(cursor));
6232 }
6233
6234 return clang_getNullCursor();
6235}
6236
6237CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6238 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006239 if (const Decl *D = getCursorDecl(cursor)) {
6240 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006241 if (!DC)
6242 return clang_getNullCursor();
6243
6244 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6245 getCursorTU(cursor));
6246 }
6247 }
6248
6249 // FIXME: Note that we can't easily compute the lexical context of a
6250 // statement or expression, so we return nothing.
6251 return clang_getNullCursor();
6252}
6253
6254CXFile clang_getIncludedFile(CXCursor cursor) {
6255 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006256 return nullptr;
6257
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006258 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006259 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006260}
6261
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006262unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6263 if (C.kind != CXCursor_ObjCPropertyDecl)
6264 return CXObjCPropertyAttr_noattr;
6265
6266 unsigned Result = CXObjCPropertyAttr_noattr;
6267 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6268 ObjCPropertyDecl::PropertyAttributeKind Attr =
6269 PD->getPropertyAttributesAsWritten();
6270
6271#define SET_CXOBJCPROP_ATTR(A) \
6272 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6273 Result |= CXObjCPropertyAttr_##A
6274 SET_CXOBJCPROP_ATTR(readonly);
6275 SET_CXOBJCPROP_ATTR(getter);
6276 SET_CXOBJCPROP_ATTR(assign);
6277 SET_CXOBJCPROP_ATTR(readwrite);
6278 SET_CXOBJCPROP_ATTR(retain);
6279 SET_CXOBJCPROP_ATTR(copy);
6280 SET_CXOBJCPROP_ATTR(nonatomic);
6281 SET_CXOBJCPROP_ATTR(setter);
6282 SET_CXOBJCPROP_ATTR(atomic);
6283 SET_CXOBJCPROP_ATTR(weak);
6284 SET_CXOBJCPROP_ATTR(strong);
6285 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6286#undef SET_CXOBJCPROP_ATTR
6287
6288 return Result;
6289}
6290
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006291unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6292 if (!clang_isDeclaration(C.kind))
6293 return CXObjCDeclQualifier_None;
6294
6295 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6296 const Decl *D = getCursorDecl(C);
6297 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6298 QT = MD->getObjCDeclQualifier();
6299 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6300 QT = PD->getObjCDeclQualifier();
6301 if (QT == Decl::OBJC_TQ_None)
6302 return CXObjCDeclQualifier_None;
6303
6304 unsigned Result = CXObjCDeclQualifier_None;
6305 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6306 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6307 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6308 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6309 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6310 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6311
6312 return Result;
6313}
6314
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006315unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6316 if (!clang_isDeclaration(C.kind))
6317 return 0;
6318
6319 const Decl *D = getCursorDecl(C);
6320 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6321 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6322 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6323 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6324
6325 return 0;
6326}
6327
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006328unsigned clang_Cursor_isVariadic(CXCursor C) {
6329 if (!clang_isDeclaration(C.kind))
6330 return 0;
6331
6332 const Decl *D = getCursorDecl(C);
6333 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6334 return FD->isVariadic();
6335 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6336 return MD->isVariadic();
6337
6338 return 0;
6339}
6340
Guy Benyei11169dd2012-12-18 14:30:41 +00006341CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6342 if (!clang_isDeclaration(C.kind))
6343 return clang_getNullRange();
6344
6345 const Decl *D = getCursorDecl(C);
6346 ASTContext &Context = getCursorContext(C);
6347 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6348 if (!RC)
6349 return clang_getNullRange();
6350
6351 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6352}
6353
6354CXString clang_Cursor_getRawCommentText(CXCursor C) {
6355 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006356 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006357
6358 const Decl *D = getCursorDecl(C);
6359 ASTContext &Context = getCursorContext(C);
6360 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6361 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6362 StringRef();
6363
6364 // Don't duplicate the string because RawText points directly into source
6365 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006366 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006367}
6368
6369CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6370 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006371 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006372
6373 const Decl *D = getCursorDecl(C);
6374 const ASTContext &Context = getCursorContext(C);
6375 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6376
6377 if (RC) {
6378 StringRef BriefText = RC->getBriefText(Context);
6379
6380 // Don't duplicate the string because RawComment ensures that this memory
6381 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006382 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006383 }
6384
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006385 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006386}
6387
Guy Benyei11169dd2012-12-18 14:30:41 +00006388CXModule clang_Cursor_getModule(CXCursor C) {
6389 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006390 if (const ImportDecl *ImportD =
6391 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006392 return ImportD->getImportedModule();
6393 }
6394
Craig Topper69186e72014-06-08 08:38:04 +00006395 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006396}
6397
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006398CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6399 if (isNotUsableTU(TU)) {
6400 LOG_BAD_TU(TU);
6401 return nullptr;
6402 }
6403 if (!File)
6404 return nullptr;
6405 FileEntry *FE = static_cast<FileEntry *>(File);
6406
6407 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6408 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6409 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6410
6411 if (Module *Mod = Header.getModule()) {
6412 if (Header.getRole() != ModuleMap::ExcludedHeader)
6413 return Mod;
6414 }
6415 return nullptr;
6416}
6417
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006418CXFile clang_Module_getASTFile(CXModule CXMod) {
6419 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006420 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006421 Module *Mod = static_cast<Module*>(CXMod);
6422 return const_cast<FileEntry *>(Mod->getASTFile());
6423}
6424
Guy Benyei11169dd2012-12-18 14:30:41 +00006425CXModule clang_Module_getParent(CXModule CXMod) {
6426 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006427 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006428 Module *Mod = static_cast<Module*>(CXMod);
6429 return Mod->Parent;
6430}
6431
6432CXString clang_Module_getName(CXModule CXMod) {
6433 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006434 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006435 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006436 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006437}
6438
6439CXString clang_Module_getFullName(CXModule CXMod) {
6440 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006441 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006442 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006443 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006444}
6445
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006446int clang_Module_isSystem(CXModule CXMod) {
6447 if (!CXMod)
6448 return 0;
6449 Module *Mod = static_cast<Module*>(CXMod);
6450 return Mod->IsSystem;
6451}
6452
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006453unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6454 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006455 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006456 LOG_BAD_TU(TU);
6457 return 0;
6458 }
6459 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006460 return 0;
6461 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006462 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6463 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6464 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006465}
6466
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006467CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6468 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006469 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006470 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006471 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006472 }
6473 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006474 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006475 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006476 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006477
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006478 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6479 if (Index < TopHeaders.size())
6480 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006481
Craig Topper69186e72014-06-08 08:38:04 +00006482 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006483}
6484
6485} // end: extern "C"
6486
6487//===----------------------------------------------------------------------===//
6488// C++ AST instrospection.
6489//===----------------------------------------------------------------------===//
6490
6491extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006492unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6493 if (!clang_isDeclaration(C.kind))
6494 return 0;
6495
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006496 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006497 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006498 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006499 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6500}
6501
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006502unsigned clang_CXXMethod_isConst(CXCursor C) {
6503 if (!clang_isDeclaration(C.kind))
6504 return 0;
6505
6506 const Decl *D = cxcursor::getCursorDecl(C);
6507 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006508 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006509 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6510}
6511
Guy Benyei11169dd2012-12-18 14:30:41 +00006512unsigned clang_CXXMethod_isStatic(CXCursor C) {
6513 if (!clang_isDeclaration(C.kind))
6514 return 0;
6515
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006516 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006517 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006518 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006519 return (Method && Method->isStatic()) ? 1 : 0;
6520}
6521
6522unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6523 if (!clang_isDeclaration(C.kind))
6524 return 0;
6525
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006526 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006527 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006528 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006529 return (Method && Method->isVirtual()) ? 1 : 0;
6530}
6531} // end: extern "C"
6532
6533//===----------------------------------------------------------------------===//
6534// Attribute introspection.
6535//===----------------------------------------------------------------------===//
6536
6537extern "C" {
6538CXType clang_getIBOutletCollectionType(CXCursor C) {
6539 if (C.kind != CXCursor_IBOutletCollectionAttr)
6540 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6541
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006542 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006543 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6544
6545 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6546}
6547} // end: extern "C"
6548
6549//===----------------------------------------------------------------------===//
6550// Inspecting memory usage.
6551//===----------------------------------------------------------------------===//
6552
6553typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6554
6555static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6556 enum CXTUResourceUsageKind k,
6557 unsigned long amount) {
6558 CXTUResourceUsageEntry entry = { k, amount };
6559 entries.push_back(entry);
6560}
6561
6562extern "C" {
6563
6564const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6565 const char *str = "";
6566 switch (kind) {
6567 case CXTUResourceUsage_AST:
6568 str = "ASTContext: expressions, declarations, and types";
6569 break;
6570 case CXTUResourceUsage_Identifiers:
6571 str = "ASTContext: identifiers";
6572 break;
6573 case CXTUResourceUsage_Selectors:
6574 str = "ASTContext: selectors";
6575 break;
6576 case CXTUResourceUsage_GlobalCompletionResults:
6577 str = "Code completion: cached global results";
6578 break;
6579 case CXTUResourceUsage_SourceManagerContentCache:
6580 str = "SourceManager: content cache allocator";
6581 break;
6582 case CXTUResourceUsage_AST_SideTables:
6583 str = "ASTContext: side tables";
6584 break;
6585 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6586 str = "SourceManager: malloc'ed memory buffers";
6587 break;
6588 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6589 str = "SourceManager: mmap'ed memory buffers";
6590 break;
6591 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6592 str = "ExternalASTSource: malloc'ed memory buffers";
6593 break;
6594 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6595 str = "ExternalASTSource: mmap'ed memory buffers";
6596 break;
6597 case CXTUResourceUsage_Preprocessor:
6598 str = "Preprocessor: malloc'ed memory";
6599 break;
6600 case CXTUResourceUsage_PreprocessingRecord:
6601 str = "Preprocessor: PreprocessingRecord";
6602 break;
6603 case CXTUResourceUsage_SourceManager_DataStructures:
6604 str = "SourceManager: data structures and tables";
6605 break;
6606 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6607 str = "Preprocessor: header search tables";
6608 break;
6609 }
6610 return str;
6611}
6612
6613CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006614 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006615 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006616 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006617 return usage;
6618 }
6619
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006620 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006621 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006622 ASTContext &astContext = astUnit->getASTContext();
6623
6624 // How much memory is used by AST nodes and types?
6625 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6626 (unsigned long) astContext.getASTAllocatedMemory());
6627
6628 // How much memory is used by identifiers?
6629 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6630 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6631
6632 // How much memory is used for selectors?
6633 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6634 (unsigned long) astContext.Selectors.getTotalMemory());
6635
6636 // How much memory is used by ASTContext's side tables?
6637 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6638 (unsigned long) astContext.getSideTableAllocatedMemory());
6639
6640 // How much memory is used for caching global code completion results?
6641 unsigned long completionBytes = 0;
6642 if (GlobalCodeCompletionAllocator *completionAllocator =
6643 astUnit->getCachedCompletionAllocator().getPtr()) {
6644 completionBytes = completionAllocator->getTotalMemory();
6645 }
6646 createCXTUResourceUsageEntry(*entries,
6647 CXTUResourceUsage_GlobalCompletionResults,
6648 completionBytes);
6649
6650 // How much memory is being used by SourceManager's content cache?
6651 createCXTUResourceUsageEntry(*entries,
6652 CXTUResourceUsage_SourceManagerContentCache,
6653 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6654
6655 // How much memory is being used by the MemoryBuffer's in SourceManager?
6656 const SourceManager::MemoryBufferSizes &srcBufs =
6657 astUnit->getSourceManager().getMemoryBufferSizes();
6658
6659 createCXTUResourceUsageEntry(*entries,
6660 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6661 (unsigned long) srcBufs.malloc_bytes);
6662 createCXTUResourceUsageEntry(*entries,
6663 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6664 (unsigned long) srcBufs.mmap_bytes);
6665 createCXTUResourceUsageEntry(*entries,
6666 CXTUResourceUsage_SourceManager_DataStructures,
6667 (unsigned long) astContext.getSourceManager()
6668 .getDataStructureSizes());
6669
6670 // How much memory is being used by the ExternalASTSource?
6671 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6672 const ExternalASTSource::MemoryBufferSizes &sizes =
6673 esrc->getMemoryBufferSizes();
6674
6675 createCXTUResourceUsageEntry(*entries,
6676 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6677 (unsigned long) sizes.malloc_bytes);
6678 createCXTUResourceUsageEntry(*entries,
6679 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6680 (unsigned long) sizes.mmap_bytes);
6681 }
6682
6683 // How much memory is being used by the Preprocessor?
6684 Preprocessor &pp = astUnit->getPreprocessor();
6685 createCXTUResourceUsageEntry(*entries,
6686 CXTUResourceUsage_Preprocessor,
6687 pp.getTotalMemory());
6688
6689 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6690 createCXTUResourceUsageEntry(*entries,
6691 CXTUResourceUsage_PreprocessingRecord,
6692 pRec->getTotalMemory());
6693 }
6694
6695 createCXTUResourceUsageEntry(*entries,
6696 CXTUResourceUsage_Preprocessor_HeaderSearch,
6697 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006698
Guy Benyei11169dd2012-12-18 14:30:41 +00006699 CXTUResourceUsage usage = { (void*) entries.get(),
6700 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006701 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006702 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006703 return usage;
6704}
6705
6706void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6707 if (usage.data)
6708 delete (MemUsageEntries*) usage.data;
6709}
6710
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006711CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6712 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006713 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006714 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006715
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006716 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006717 LOG_BAD_TU(TU);
6718 return skipped;
6719 }
6720
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006721 if (!file)
6722 return skipped;
6723
6724 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6725 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6726 if (!ppRec)
6727 return skipped;
6728
6729 ASTContext &Ctx = astUnit->getASTContext();
6730 SourceManager &sm = Ctx.getSourceManager();
6731 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6732 FileID wantedFileID = sm.translateFile(fileEntry);
6733
6734 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6735 std::vector<SourceRange> wantedRanges;
6736 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6737 i != ei; ++i) {
6738 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6739 wantedRanges.push_back(*i);
6740 }
6741
6742 skipped->count = wantedRanges.size();
6743 skipped->ranges = new CXSourceRange[skipped->count];
6744 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6745 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6746
6747 return skipped;
6748}
6749
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006750void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6751 if (ranges) {
6752 delete[] ranges->ranges;
6753 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006754 }
6755}
6756
Guy Benyei11169dd2012-12-18 14:30:41 +00006757} // end extern "C"
6758
6759void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6760 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6761 for (unsigned I = 0; I != Usage.numEntries; ++I)
6762 fprintf(stderr, " %s: %lu\n",
6763 clang_getTUResourceUsageName(Usage.entries[I].kind),
6764 Usage.entries[I].amount);
6765
6766 clang_disposeCXTUResourceUsage(Usage);
6767}
6768
6769//===----------------------------------------------------------------------===//
6770// Misc. utility functions.
6771//===----------------------------------------------------------------------===//
6772
6773/// Default to using an 8 MB stack size on "safety" threads.
6774static unsigned SafetyStackThreadSize = 8 << 20;
6775
6776namespace clang {
6777
6778bool RunSafely(llvm::CrashRecoveryContext &CRC,
6779 void (*Fn)(void*), void *UserData,
6780 unsigned Size) {
6781 if (!Size)
6782 Size = GetSafetyThreadStackSize();
6783 if (Size)
6784 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6785 return CRC.RunSafely(Fn, UserData);
6786}
6787
6788unsigned GetSafetyThreadStackSize() {
6789 return SafetyStackThreadSize;
6790}
6791
6792void SetSafetyThreadStackSize(unsigned Value) {
6793 SafetyStackThreadSize = Value;
6794}
6795
6796}
6797
6798void clang::setThreadBackgroundPriority() {
6799 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6800 return;
6801
6802 // FIXME: Move to llvm/Support and make it cross-platform.
6803#ifdef __APPLE__
6804 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6805#endif
6806}
6807
6808void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6809 if (!Unit)
6810 return;
6811
6812 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6813 DEnd = Unit->stored_diag_end();
6814 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006815 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006816 CXString Msg = clang_formatDiagnostic(&Diag,
6817 clang_defaultDiagnosticDisplayOptions());
6818 fprintf(stderr, "%s\n", clang_getCString(Msg));
6819 clang_disposeString(Msg);
6820 }
6821#ifdef LLVM_ON_WIN32
6822 // On Windows, force a flush, since there may be multiple copies of
6823 // stderr and stdout in the file system, all with different buffers
6824 // but writing to the same device.
6825 fflush(stderr);
6826#endif
6827}
6828
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006829MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6830 SourceLocation MacroDefLoc,
6831 CXTranslationUnit TU){
6832 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006833 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006834 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006835 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006836
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006837 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006838 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006839 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006840 if (MD) {
6841 for (MacroDirective::DefInfo
6842 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6843 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6844 return Def.getMacroInfo();
6845 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006846 }
6847
Craig Topper69186e72014-06-08 08:38:04 +00006848 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006849}
6850
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006851const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6852 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006853 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006854 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006855 const IdentifierInfo *II = MacroDef->getName();
6856 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006857 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006858
6859 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6860}
6861
6862MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6863 const Token &Tok,
6864 CXTranslationUnit TU) {
6865 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006866 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006867 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006868 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006869
6870 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006871 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006872 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6873 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006874 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006875
6876 // Check that the token is inside the definition and not its argument list.
6877 SourceManager &SM = Unit->getSourceManager();
6878 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006879 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006880 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006881 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006882
6883 Preprocessor &PP = Unit->getPreprocessor();
6884 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6885 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006886 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006887
Alp Toker2d57cea2014-05-17 04:53:25 +00006888 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006889 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006890 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006891
6892 // Check that the identifier is not one of the macro arguments.
6893 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006894 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006895
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006896 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6897 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006898 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006899
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006900 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006901}
6902
6903MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6904 SourceLocation Loc,
6905 CXTranslationUnit TU) {
6906 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006907 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006908
6909 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006910 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006911 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006912 Preprocessor &PP = Unit->getPreprocessor();
6913 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006914 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006915 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6916 Token Tok;
6917 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006918 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006919
6920 return checkForMacroInMacroDefinition(MI, Tok, TU);
6921}
6922
Guy Benyei11169dd2012-12-18 14:30:41 +00006923extern "C" {
6924
6925CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006926 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006927}
6928
6929} // end: extern "C"
6930
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006931Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6932 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006933 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006934 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006935 if (Unit->isMainFileAST())
6936 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006937 return *this;
6938 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006939 } else {
6940 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006941 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006942 return *this;
6943}
6944
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006945Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6946 *this << FE->getName();
6947 return *this;
6948}
6949
6950Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6951 CXString cursorName = clang_getCursorDisplayName(cursor);
6952 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6953 clang_disposeString(cursorName);
6954 return *this;
6955}
6956
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006957Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6958 CXFile File;
6959 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006960 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006961 CXString FileName = clang_getFileName(File);
6962 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6963 clang_disposeString(FileName);
6964 return *this;
6965}
6966
6967Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6968 CXSourceLocation BLoc = clang_getRangeStart(range);
6969 CXSourceLocation ELoc = clang_getRangeEnd(range);
6970
6971 CXFile BFile;
6972 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006973 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006974
6975 CXFile EFile;
6976 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006977 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006978
6979 CXString BFileName = clang_getFileName(BFile);
6980 if (BFile == EFile) {
6981 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6982 BLine, BColumn, ELine, EColumn);
6983 } else {
6984 CXString EFileName = clang_getFileName(EFile);
6985 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6986 BLine, BColumn)
6987 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6988 ELine, EColumn);
6989 clang_disposeString(EFileName);
6990 }
6991 clang_disposeString(BFileName);
6992 return *this;
6993}
6994
6995Logger &cxindex::Logger::operator<<(CXString Str) {
6996 *this << clang_getCString(Str);
6997 return *this;
6998}
6999
7000Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7001 LogOS << Fmt;
7002 return *this;
7003}
7004
Chandler Carruth37ad2582014-06-27 15:14:39 +00007005static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7006
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007007cxindex::Logger::~Logger() {
7008 LogOS.flush();
7009
Chandler Carruth37ad2582014-06-27 15:14:39 +00007010 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007011
7012 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7013
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007014 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007015 OS << "[libclang:" << Name << ':';
7016
7017 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00007018#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007019 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7020 OS << tid << ':';
7021#endif
7022
7023 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7024 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7025 OS << Msg.str() << '\n';
7026
7027 if (Trace) {
7028 llvm::sys::PrintStackTrace(stderr);
7029 OS << "--------------------------------------------------\n";
7030 }
7031}