blob: 85b20f343a65c30b4f44e8592cb3d2a9cd285356 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000033#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Lex/HeaderSearch.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/Lex/PreprocessingRecord.h"
37#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000038#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000039#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000042#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000043#include "llvm/Support/Compiler.h"
44#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000045#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000046#include "llvm/Support/MemoryBuffer.h"
47#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000048#include "llvm/Support/Program.h"
49#include "llvm/Support/SaveAndRestore.h"
50#include "llvm/Support/Signals.h"
51#include "llvm/Support/Threading.h"
52#include "llvm/Support/Timer.h"
53#include "llvm/Support/raw_ostream.h"
Zachary Turnerf68823b2014-06-17 19:57:15 +000054#include <mutex>
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);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001856
Guy Benyei11169dd2012-12-18 14:30:41 +00001857private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001859 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1860 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001861 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1862 void AddStmt(const Stmt *S);
1863 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001864 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001867};
1868} // end anonyous namespace
1869
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001870void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001871 // 'S' should always be non-null, since it comes from the
1872 // statement we are visiting.
1873 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1874}
1875
1876void
1877EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1878 if (Qualifier)
1879 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1880}
1881
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001882void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001883 if (S)
1884 WL.push_back(StmtVisit(S, Parent));
1885}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001886void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001887 if (D)
1888 WL.push_back(DeclVisit(D, Parent, isFirst));
1889}
1890void EnqueueVisitor::
1891 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1892 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001894}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001895void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001896 if (D)
1897 WL.push_back(MemberRefVisit(D, L, Parent));
1898}
1899void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1900 if (TI)
1901 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1902 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001904 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001905 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001906 AddStmt(*Child);
1907 }
1908 if (size == WL.size())
1909 return;
1910 // Now reverse the entries we just added. This will match the DFS
1911 // ordering performed by the worklist.
1912 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1913 std::reverse(I, E);
1914}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001915namespace {
1916class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1917 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001918 /// \brief Process clauses with list of variables.
1919 template <typename T>
1920 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001921public:
1922 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1923#define OPENMP_CLAUSE(Name, Class) \
1924 void Visit##Class(const Class *C);
1925#include "clang/Basic/OpenMPKinds.def"
1926};
1927
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001928void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1929 Visitor->AddStmt(C->getCondition());
1930}
1931
Alexey Bataev568a8332014-03-06 06:15:19 +00001932void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1933 Visitor->AddStmt(C->getNumThreads());
1934}
1935
Alexey Bataev62c87d22014-03-21 04:51:18 +00001936void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1937 Visitor->AddStmt(C->getSafelen());
1938}
1939
Alexander Musman8bd31e62014-05-27 15:12:19 +00001940void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1941 Visitor->AddStmt(C->getNumForLoops());
1942}
1943
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001944void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001945
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001946void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1947
Alexey Bataev56dafe82014-06-20 07:16:17 +00001948void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1949 Visitor->AddStmt(C->getChunkSize());
1950}
1951
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001952void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1953
Alexey Bataev756c1962013-09-24 03:17:45 +00001954template<typename T>
1955void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001956 for (const auto *I : Node->varlists())
1957 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001958}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001959
1960void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001961 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001962}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001963void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1964 const OMPFirstprivateClause *C) {
1965 VisitOMPClauseList(C);
1966}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001967void OMPClauseEnqueue::VisitOMPLastprivateClause(
1968 const OMPLastprivateClause *C) {
1969 VisitOMPClauseList(C);
1970}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001971void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001972 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001973}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001974void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1975 VisitOMPClauseList(C);
1976}
Alexander Musman8dba6642014-04-22 13:09:42 +00001977void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1978 VisitOMPClauseList(C);
1979 Visitor->AddStmt(C->getStep());
1980}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001981void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1982 VisitOMPClauseList(C);
1983 Visitor->AddStmt(C->getAlignment());
1984}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001985void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1986 VisitOMPClauseList(C);
1987}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001988}
Alexey Bataev756c1962013-09-24 03:17:45 +00001989
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001990void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1991 unsigned size = WL.size();
1992 OMPClauseEnqueue Visitor(this);
1993 Visitor.Visit(S);
1994 if (size == WL.size())
1995 return;
1996 // Now reverse the entries we just added. This will match the DFS
1997 // ordering performed by the worklist.
1998 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1999 std::reverse(I, E);
2000}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002001void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002002 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2003}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002004void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002005 AddDecl(B->getBlockDecl());
2006}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002007void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002008 EnqueueChildren(E);
2009 AddTypeLoc(E->getTypeSourceInfo());
2010}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002011void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2012 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002013 E = S->body_rend(); I != E; ++I) {
2014 AddStmt(*I);
2015 }
2016}
2017void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002018VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002019 AddStmt(S->getSubStmt());
2020 AddDeclarationNameInfo(S);
2021 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2022 AddNestedNameSpecifierLoc(QualifierLoc);
2023}
2024
2025void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002026VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002027 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2028 AddDeclarationNameInfo(E);
2029 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2030 AddNestedNameSpecifierLoc(QualifierLoc);
2031 if (!E->isImplicitAccess())
2032 AddStmt(E->getBase());
2033}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002035 // Enqueue the initializer , if any.
2036 AddStmt(E->getInitializer());
2037 // Enqueue the array size, if any.
2038 AddStmt(E->getArraySize());
2039 // Enqueue the allocated type.
2040 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2041 // Enqueue the placement arguments.
2042 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2043 AddStmt(E->getPlacementArg(I-1));
2044}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002045void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002046 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2047 AddStmt(CE->getArg(I-1));
2048 AddStmt(CE->getCallee());
2049 AddStmt(CE->getArg(0));
2050}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002051void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2052 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002053 // Visit the name of the type being destroyed.
2054 AddTypeLoc(E->getDestroyedTypeInfo());
2055 // Visit the scope type that looks disturbingly like the nested-name-specifier
2056 // but isn't.
2057 AddTypeLoc(E->getScopeTypeInfo());
2058 // Visit the nested-name-specifier.
2059 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2060 AddNestedNameSpecifierLoc(QualifierLoc);
2061 // Visit base expression.
2062 AddStmt(E->getBase());
2063}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2065 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 AddTypeLoc(E->getTypeSourceInfo());
2067}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2069 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 EnqueueChildren(E);
2071 AddTypeLoc(E->getTypeSourceInfo());
2072}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 EnqueueChildren(E);
2075 if (E->isTypeOperand())
2076 AddTypeLoc(E->getTypeOperandSourceInfo());
2077}
2078
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2080 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 EnqueueChildren(E);
2082 AddTypeLoc(E->getTypeSourceInfo());
2083}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002084void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002085 EnqueueChildren(E);
2086 if (E->isTypeOperand())
2087 AddTypeLoc(E->getTypeOperandSourceInfo());
2088}
2089
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002090void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002091 EnqueueChildren(S);
2092 AddDecl(S->getExceptionDecl());
2093}
2094
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002095void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002096 if (DR->hasExplicitTemplateArgs()) {
2097 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2098 }
2099 WL.push_back(DeclRefExprParts(DR, Parent));
2100}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002101void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2102 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002103 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2104 AddDeclarationNameInfo(E);
2105 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2106}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002108 unsigned size = WL.size();
2109 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002110 for (const auto *D : S->decls()) {
2111 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002112 isFirst = false;
2113 }
2114 if (size == WL.size())
2115 return;
2116 // Now reverse the entries we just added. This will match the DFS
2117 // ordering performed by the worklist.
2118 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2119 std::reverse(I, E);
2120}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002122 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 D = E->designators_rbegin(), DEnd = E->designators_rend();
2125 D != DEnd; ++D) {
2126 if (D->isFieldDesignator()) {
2127 if (FieldDecl *Field = D->getField())
2128 AddMemberRef(Field, D->getFieldLoc());
2129 continue;
2130 }
2131 if (D->isArrayDesignator()) {
2132 AddStmt(E->getArrayIndex(*D));
2133 continue;
2134 }
2135 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2136 AddStmt(E->getArrayRangeEnd(*D));
2137 AddStmt(E->getArrayRangeStart(*D));
2138 }
2139}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002141 EnqueueChildren(E);
2142 AddTypeLoc(E->getTypeInfoAsWritten());
2143}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002144void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002145 AddStmt(FS->getBody());
2146 AddStmt(FS->getInc());
2147 AddStmt(FS->getCond());
2148 AddDecl(FS->getConditionVariable());
2149 AddStmt(FS->getInit());
2150}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002152 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 AddStmt(If->getElse());
2156 AddStmt(If->getThen());
2157 AddStmt(If->getCond());
2158 AddDecl(If->getConditionVariable());
2159}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002160void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002161 // We care about the syntactic form of the initializer list, only.
2162 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2163 IE = Syntactic;
2164 EnqueueChildren(IE);
2165}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002166void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002167 WL.push_back(MemberExprParts(M, Parent));
2168
2169 // If the base of the member access expression is an implicit 'this', don't
2170 // visit it.
2171 // FIXME: If we ever want to show these implicit accesses, this will be
2172 // unfortunate. However, clang_getCursor() relies on this behavior.
2173 if (!M->isImplicitAccess())
2174 AddStmt(M->getBase());
2175}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002176void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002177 AddTypeLoc(E->getEncodedTypeSourceInfo());
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 EnqueueChildren(M);
2181 AddTypeLoc(M->getClassReceiverTypeInfo());
2182}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002184 // Visit the components of the offsetof expression.
2185 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2186 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2187 const OffsetOfNode &Node = E->getComponent(I-1);
2188 switch (Node.getKind()) {
2189 case OffsetOfNode::Array:
2190 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2191 break;
2192 case OffsetOfNode::Field:
2193 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2194 break;
2195 case OffsetOfNode::Identifier:
2196 case OffsetOfNode::Base:
2197 continue;
2198 }
2199 }
2200 // Visit the type into which we're computing the offset.
2201 AddTypeLoc(E->getTypeSourceInfo());
2202}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2205 WL.push_back(OverloadExprParts(E, Parent));
2206}
2207void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 EnqueueChildren(E);
2210 if (E->isArgumentType())
2211 AddTypeLoc(E->getArgumentTypeInfo());
2212}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 EnqueueChildren(S);
2215}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 AddStmt(S->getBody());
2218 AddStmt(S->getCond());
2219 AddDecl(S->getConditionVariable());
2220}
2221
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 AddStmt(W->getBody());
2224 AddStmt(W->getCond());
2225 AddDecl(W->getConditionVariable());
2226}
2227
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 for (unsigned I = E->getNumArgs(); I > 0; --I)
2230 AddTypeLoc(E->getArg(I-1));
2231}
2232
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002233void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002234 AddTypeLoc(E->getQueriedTypeSourceInfo());
2235}
2236
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002238 EnqueueChildren(E);
2239}
2240
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002242 VisitOverloadExpr(U);
2243 if (!U->isImplicitAccess())
2244 AddStmt(U->getBase());
2245}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002246void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 AddStmt(E->getSubExpr());
2248 AddTypeLoc(E->getWrittenTypeInfo());
2249}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 WL.push_back(SizeOfPackExprParts(E, Parent));
2252}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 // If the opaque value has a source expression, just transparently
2255 // visit that. This is useful for (e.g.) pseudo-object expressions.
2256 if (Expr *SourceExpr = E->getSourceExpr())
2257 return Visit(SourceExpr);
2258}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 AddStmt(E->getBody());
2261 WL.push_back(LambdaExprParts(E, Parent));
2262}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 // Treat the expression like its syntactic form.
2265 Visit(E->getSyntacticForm());
2266}
2267
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002268void EnqueueVisitor::VisitOMPExecutableDirective(
2269 const OMPExecutableDirective *D) {
2270 EnqueueChildren(D);
2271 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2272 E = D->clauses().end();
2273 I != E; ++I)
2274 EnqueueChildren(*I);
2275}
2276
2277void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2278 VisitOMPExecutableDirective(D);
2279}
2280
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002281void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2282 VisitOMPExecutableDirective(D);
2283}
2284
Alexey Bataevf29276e2014-06-18 04:14:57 +00002285void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2286 VisitOMPExecutableDirective(D);
2287}
2288
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002289void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002290 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2291}
2292
2293bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2294 if (RegionOfInterest.isValid()) {
2295 SourceRange Range = getRawCursorExtent(C);
2296 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2297 return false;
2298 }
2299 return true;
2300}
2301
2302bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2303 while (!WL.empty()) {
2304 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002305 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002306
2307 // Set the Parent field, then back to its old value once we're done.
2308 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2309
2310 switch (LI.getKind()) {
2311 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 if (!D)
2314 continue;
2315
2316 // For now, perform default visitation for Decls.
2317 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2318 cast<DeclVisit>(&LI)->isFirst())))
2319 return true;
2320
2321 continue;
2322 }
2323 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2324 const ASTTemplateArgumentListInfo *ArgList =
2325 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2326 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2327 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2328 Arg != ArgEnd; ++Arg) {
2329 if (VisitTemplateArgumentLoc(*Arg))
2330 return true;
2331 }
2332 continue;
2333 }
2334 case VisitorJob::TypeLocVisitKind: {
2335 // Perform default visitation for TypeLocs.
2336 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2337 return true;
2338 continue;
2339 }
2340 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002341 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002342 if (LabelStmt *stmt = LS->getStmt()) {
2343 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2344 TU))) {
2345 return true;
2346 }
2347 }
2348 continue;
2349 }
2350
2351 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2352 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2353 if (VisitNestedNameSpecifierLoc(V->get()))
2354 return true;
2355 continue;
2356 }
2357
2358 case VisitorJob::DeclarationNameInfoVisitKind: {
2359 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2360 ->get()))
2361 return true;
2362 continue;
2363 }
2364 case VisitorJob::MemberRefVisitKind: {
2365 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2366 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2367 return true;
2368 continue;
2369 }
2370 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002371 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002372 if (!S)
2373 continue;
2374
2375 // Update the current cursor.
2376 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2377 if (!IsInRegionOfInterest(Cursor))
2378 continue;
2379 switch (Visitor(Cursor, Parent, ClientData)) {
2380 case CXChildVisit_Break: return true;
2381 case CXChildVisit_Continue: break;
2382 case CXChildVisit_Recurse:
2383 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002384 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002385 EnqueueWorkList(WL, S);
2386 break;
2387 }
2388 continue;
2389 }
2390 case VisitorJob::MemberExprPartsKind: {
2391 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002392 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002393
2394 // Visit the nested-name-specifier
2395 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2396 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2397 return true;
2398
2399 // Visit the declaration name.
2400 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2401 return true;
2402
2403 // Visit the explicitly-specified template arguments, if any.
2404 if (M->hasExplicitTemplateArgs()) {
2405 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2406 *ArgEnd = Arg + M->getNumTemplateArgs();
2407 Arg != ArgEnd; ++Arg) {
2408 if (VisitTemplateArgumentLoc(*Arg))
2409 return true;
2410 }
2411 }
2412 continue;
2413 }
2414 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002415 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002416 // Visit nested-name-specifier, if present.
2417 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2418 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2419 return true;
2420 // Visit declaration name.
2421 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2422 return true;
2423 continue;
2424 }
2425 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002426 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 // Visit the nested-name-specifier.
2428 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2429 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2430 return true;
2431 // Visit the declaration name.
2432 if (VisitDeclarationNameInfo(O->getNameInfo()))
2433 return true;
2434 // Visit the overloaded declaration reference.
2435 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2436 return true;
2437 continue;
2438 }
2439 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002440 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 NamedDecl *Pack = E->getPack();
2442 if (isa<TemplateTypeParmDecl>(Pack)) {
2443 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2444 E->getPackLoc(), TU)))
2445 return true;
2446
2447 continue;
2448 }
2449
2450 if (isa<TemplateTemplateParmDecl>(Pack)) {
2451 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2452 E->getPackLoc(), TU)))
2453 return true;
2454
2455 continue;
2456 }
2457
2458 // Non-type template parameter packs and function parameter packs are
2459 // treated like DeclRefExpr cursors.
2460 continue;
2461 }
2462
2463 case VisitorJob::LambdaExprPartsKind: {
2464 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002465 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002466 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2467 CEnd = E->explicit_capture_end();
2468 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002469 // FIXME: Lambda init-captures.
2470 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002471 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002472
Guy Benyei11169dd2012-12-18 14:30:41 +00002473 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2474 C->getLocation(),
2475 TU)))
2476 return true;
2477 }
2478
2479 // Visit parameters and return type, if present.
2480 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2481 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2482 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2483 // Visit the whole type.
2484 if (Visit(TL))
2485 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002486 } else if (FunctionProtoTypeLoc Proto =
2487 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002488 if (E->hasExplicitParameters()) {
2489 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002490 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2491 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002492 return true;
2493 } else {
2494 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002495 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002496 return true;
2497 }
2498 }
2499 }
2500 break;
2501 }
2502
2503 case VisitorJob::PostChildrenVisitKind:
2504 if (PostChildrenVisitor(Parent, ClientData))
2505 return true;
2506 break;
2507 }
2508 }
2509 return false;
2510}
2511
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002512bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002513 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002514 if (!WorkListFreeList.empty()) {
2515 WL = WorkListFreeList.back();
2516 WL->clear();
2517 WorkListFreeList.pop_back();
2518 }
2519 else {
2520 WL = new VisitorWorkList();
2521 WorkListCache.push_back(WL);
2522 }
2523 EnqueueWorkList(*WL, S);
2524 bool result = RunVisitorWorkList(*WL);
2525 WorkListFreeList.push_back(WL);
2526 return result;
2527}
2528
2529namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002530typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002531RefNamePieces
2532buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2533 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2534 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002535 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2536 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2537 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2538
2539 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2540
2541 RefNamePieces Pieces;
2542
2543 if (WantQualifier && QLoc.isValid())
2544 Pieces.push_back(QLoc);
2545
2546 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2547 Pieces.push_back(NI.getLoc());
2548
2549 if (WantTemplateArgs && TemplateArgs)
2550 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2551 TemplateArgs->RAngleLoc));
2552
2553 if (Kind == DeclarationName::CXXOperatorName) {
2554 Pieces.push_back(SourceLocation::getFromRawEncoding(
2555 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2556 Pieces.push_back(SourceLocation::getFromRawEncoding(
2557 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2558 }
2559
2560 if (WantSinglePiece) {
2561 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2562 Pieces.clear();
2563 Pieces.push_back(R);
2564 }
2565
2566 return Pieces;
2567}
2568}
2569
2570//===----------------------------------------------------------------------===//
2571// Misc. API hooks.
2572//===----------------------------------------------------------------------===//
2573
Zachary Turnerf68823b2014-06-17 19:57:15 +00002574static llvm::sys::Mutex LoggingMutex;
2575static std::once_flag LibclangGlobalInitFlag;
Guy Benyei11169dd2012-12-18 14:30:41 +00002576
Chad Rosier05c71aa2013-03-27 18:28:23 +00002577static void fatal_error_handler(void *user_data, const std::string& reason,
2578 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002579 // Write the result out to stderr avoiding errs() because raw_ostreams can
2580 // call report_fatal_error.
2581 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2582 ::abort();
2583}
2584
Zachary Turnerf68823b2014-06-17 19:57:15 +00002585static void initializeLibClang() {
Zachary Turnerf68823b2014-06-17 19:57:15 +00002586 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2587}
2588
Guy Benyei11169dd2012-12-18 14:30:41 +00002589extern "C" {
2590CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2591 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002592 // We use crash recovery to make some of our APIs more reliable, implicitly
2593 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002594 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2595 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002596
Zachary Turnerf68823b2014-06-17 19:57:15 +00002597 std::call_once(LibclangGlobalInitFlag, initializeLibClang);
Guy Benyei11169dd2012-12-18 14:30:41 +00002598
2599 CIndexer *CIdxr = new CIndexer();
2600 if (excludeDeclarationsFromPCH)
2601 CIdxr->setOnlyLocalDecls();
2602 if (displayDiagnostics)
2603 CIdxr->setDisplayDiagnostics();
2604
2605 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2606 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2607 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2608 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2609 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2610 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2611
2612 return CIdxr;
2613}
2614
2615void clang_disposeIndex(CXIndex CIdx) {
2616 if (CIdx)
2617 delete static_cast<CIndexer *>(CIdx);
2618}
2619
2620void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2621 if (CIdx)
2622 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2623}
2624
2625unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2626 if (CIdx)
2627 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2628 return 0;
2629}
2630
2631void clang_toggleCrashRecovery(unsigned isEnabled) {
2632 if (isEnabled)
2633 llvm::CrashRecoveryContext::Enable();
2634 else
2635 llvm::CrashRecoveryContext::Disable();
2636}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002637
Guy Benyei11169dd2012-12-18 14:30:41 +00002638CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2639 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002640 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002641 enum CXErrorCode Result =
2642 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002643 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002644 assert((TU && Result == CXError_Success) ||
2645 (!TU && Result != CXError_Success));
2646 return TU;
2647}
2648
2649enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2650 const char *ast_filename,
2651 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002652 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002653 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002654
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002655 if (!CIdx || !ast_filename || !out_TU)
2656 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002657
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002658 LOG_FUNC_SECTION {
2659 *Log << ast_filename;
2660 }
2661
Guy Benyei11169dd2012-12-18 14:30:41 +00002662 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2663 FileSystemOptions FileSystemOpts;
2664
2665 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002666 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002667 CXXIdx->getOnlyLocalDecls(), None,
2668 /*CaptureDiagnostics=*/true,
2669 /*AllowPCHWithCompilerErrors=*/true,
2670 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002671 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2672 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002673}
2674
2675unsigned clang_defaultEditingTranslationUnitOptions() {
2676 return CXTranslationUnit_PrecompiledPreamble |
2677 CXTranslationUnit_CacheCompletionResults;
2678}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002679
Guy Benyei11169dd2012-12-18 14:30:41 +00002680CXTranslationUnit
2681clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2682 const char *source_filename,
2683 int num_command_line_args,
2684 const char * const *command_line_args,
2685 unsigned num_unsaved_files,
2686 struct CXUnsavedFile *unsaved_files) {
2687 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2688 return clang_parseTranslationUnit(CIdx, source_filename,
2689 command_line_args, num_command_line_args,
2690 unsaved_files, num_unsaved_files,
2691 Options);
2692}
2693
2694struct ParseTranslationUnitInfo {
2695 CXIndex CIdx;
2696 const char *source_filename;
2697 const char *const *command_line_args;
2698 int num_command_line_args;
2699 struct CXUnsavedFile *unsaved_files;
2700 unsigned num_unsaved_files;
2701 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002702 CXTranslationUnit *out_TU;
2703 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002704};
2705static void clang_parseTranslationUnit_Impl(void *UserData) {
2706 ParseTranslationUnitInfo *PTUI =
2707 static_cast<ParseTranslationUnitInfo*>(UserData);
2708 CXIndex CIdx = PTUI->CIdx;
2709 const char *source_filename = PTUI->source_filename;
2710 const char * const *command_line_args = PTUI->command_line_args;
2711 int num_command_line_args = PTUI->num_command_line_args;
2712 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2713 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2714 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002715 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002716
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002717 // Set up the initial return values.
2718 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002719 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002720 PTUI->result = CXError_Failure;
2721
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002722 // Check arguments.
2723 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002724 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002725 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002726 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002727 }
2728
Guy Benyei11169dd2012-12-18 14:30:41 +00002729 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2730
2731 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2732 setThreadBackgroundPriority();
2733
2734 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2735 // FIXME: Add a flag for modules.
2736 TranslationUnitKind TUKind
2737 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002738 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002739 = options & CXTranslationUnit_CacheCompletionResults;
2740 bool IncludeBriefCommentsInCodeCompletion
2741 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2742 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2743 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2744
2745 // Configure the diagnostics.
2746 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002747 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002748
2749 // Recover resources if we crash before exiting this function.
2750 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2751 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2752 DiagCleanup(Diags.getPtr());
2753
Ahmed Charlesb8984322014-03-07 20:03:18 +00002754 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2755 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002756
2757 // Recover resources if we crash before exiting this function.
2758 llvm::CrashRecoveryContextCleanupRegistrar<
2759 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2760
2761 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2762 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2763 const llvm::MemoryBuffer *Buffer
2764 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2765 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2766 Buffer));
2767 }
2768
Ahmed Charlesb8984322014-03-07 20:03:18 +00002769 std::unique_ptr<std::vector<const char *>> Args(
2770 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002771
2772 // Recover resources if we crash before exiting this method.
2773 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2774 ArgsCleanup(Args.get());
2775
2776 // Since the Clang C library is primarily used by batch tools dealing with
2777 // (often very broken) source code, where spell-checking can have a
2778 // significant negative impact on performance (particularly when
2779 // precompiled headers are involved), we disable it by default.
2780 // Only do this if we haven't found a spell-checking-related argument.
2781 bool FoundSpellCheckingArgument = false;
2782 for (int I = 0; I != num_command_line_args; ++I) {
2783 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2784 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2785 FoundSpellCheckingArgument = true;
2786 break;
2787 }
2788 }
2789 if (!FoundSpellCheckingArgument)
2790 Args->push_back("-fno-spell-checking");
2791
2792 Args->insert(Args->end(), command_line_args,
2793 command_line_args + num_command_line_args);
2794
2795 // The 'source_filename' argument is optional. If the caller does not
2796 // specify it then it is assumed that the source file is specified
2797 // in the actual argument list.
2798 // Put the source file after command_line_args otherwise if '-x' flag is
2799 // present it will be unused.
2800 if (source_filename)
2801 Args->push_back(source_filename);
2802
2803 // Do we need the detailed preprocessing record?
2804 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2805 Args->push_back("-Xclang");
2806 Args->push_back("-detailed-preprocessing-record");
2807 }
2808
2809 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002810 std::unique_ptr<ASTUnit> ErrUnit;
2811 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002812 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002813 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2814 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2815 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2816 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2817 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2818 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002819
2820 if (NumErrors != Diags->getClient()->getNumErrors()) {
2821 // Make sure to check that 'Unit' is non-NULL.
2822 if (CXXIdx->getDisplayDiagnostics())
2823 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2824 }
2825
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002826 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2827 PTUI->result = CXError_ASTReadError;
2828 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002829 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002830 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2831 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002832}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002833
2834CXTranslationUnit
2835clang_parseTranslationUnit(CXIndex CIdx,
2836 const char *source_filename,
2837 const char *const *command_line_args,
2838 int num_command_line_args,
2839 struct CXUnsavedFile *unsaved_files,
2840 unsigned num_unsaved_files,
2841 unsigned options) {
2842 CXTranslationUnit TU;
2843 enum CXErrorCode Result = clang_parseTranslationUnit2(
2844 CIdx, source_filename, command_line_args, num_command_line_args,
2845 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002846 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002847 assert((TU && Result == CXError_Success) ||
2848 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002849 return TU;
2850}
2851
2852enum CXErrorCode clang_parseTranslationUnit2(
2853 CXIndex CIdx,
2854 const char *source_filename,
2855 const char *const *command_line_args,
2856 int num_command_line_args,
2857 struct CXUnsavedFile *unsaved_files,
2858 unsigned num_unsaved_files,
2859 unsigned options,
2860 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002861 LOG_FUNC_SECTION {
2862 *Log << source_filename << ": ";
2863 for (int i = 0; i != num_command_line_args; ++i)
2864 *Log << command_line_args[i] << " ";
2865 }
2866
Guy Benyei11169dd2012-12-18 14:30:41 +00002867 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2868 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002869 num_unsaved_files, options, out_TU,
2870 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002871 llvm::CrashRecoveryContext CRC;
2872
2873 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2874 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2875 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2876 fprintf(stderr, " 'command_line_args' : [");
2877 for (int i = 0; i != num_command_line_args; ++i) {
2878 if (i)
2879 fprintf(stderr, ", ");
2880 fprintf(stderr, "'%s'", command_line_args[i]);
2881 }
2882 fprintf(stderr, "],\n");
2883 fprintf(stderr, " 'unsaved_files' : [");
2884 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2885 if (i)
2886 fprintf(stderr, ", ");
2887 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2888 unsaved_files[i].Length);
2889 }
2890 fprintf(stderr, "],\n");
2891 fprintf(stderr, " 'options' : %d,\n", options);
2892 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002893
2894 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002895 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002896 if (CXTranslationUnit *TU = PTUI.out_TU)
2897 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002898 }
2899
2900 return PTUI.result;
2901}
2902
2903unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2904 return CXSaveTranslationUnit_None;
2905}
2906
2907namespace {
2908
2909struct SaveTranslationUnitInfo {
2910 CXTranslationUnit TU;
2911 const char *FileName;
2912 unsigned options;
2913 CXSaveError result;
2914};
2915
2916}
2917
2918static void clang_saveTranslationUnit_Impl(void *UserData) {
2919 SaveTranslationUnitInfo *STUI =
2920 static_cast<SaveTranslationUnitInfo*>(UserData);
2921
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002922 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002923 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2924 setThreadBackgroundPriority();
2925
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002926 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002927 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2928}
2929
2930int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2931 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002932 LOG_FUNC_SECTION {
2933 *Log << TU << ' ' << FileName;
2934 }
2935
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002936 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002937 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002938 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002939 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002940
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002941 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002942 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2943 if (!CXXUnit->hasSema())
2944 return CXSaveError_InvalidTU;
2945
2946 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2947
2948 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2949 getenv("LIBCLANG_NOTHREADS")) {
2950 clang_saveTranslationUnit_Impl(&STUI);
2951
2952 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2953 PrintLibclangResourceUsage(TU);
2954
2955 return STUI.result;
2956 }
2957
2958 // We have an AST that has invalid nodes due to compiler errors.
2959 // Use a crash recovery thread for protection.
2960
2961 llvm::CrashRecoveryContext CRC;
2962
2963 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2964 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2965 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2966 fprintf(stderr, " 'options' : %d,\n", options);
2967 fprintf(stderr, "}\n");
2968
2969 return CXSaveError_Unknown;
2970
2971 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2972 PrintLibclangResourceUsage(TU);
2973 }
2974
2975 return STUI.result;
2976}
2977
2978void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2979 if (CTUnit) {
2980 // If the translation unit has been marked as unsafe to free, just discard
2981 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002982 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2983 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002984 return;
2985
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002986 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002987 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002988 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2989 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002990 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002991 delete CTUnit;
2992 }
2993}
2994
2995unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2996 return CXReparse_None;
2997}
2998
2999struct ReparseTranslationUnitInfo {
3000 CXTranslationUnit TU;
3001 unsigned num_unsaved_files;
3002 struct CXUnsavedFile *unsaved_files;
3003 unsigned options;
3004 int result;
3005};
3006
3007static void clang_reparseTranslationUnit_Impl(void *UserData) {
3008 ReparseTranslationUnitInfo *RTUI =
3009 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003010 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003011
Guy Benyei11169dd2012-12-18 14:30:41 +00003012 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003013 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3014 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3015 unsigned options = RTUI->options;
3016 (void) options;
3017
3018 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003019 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003020 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003021 RTUI->result = CXError_InvalidArguments;
3022 return;
3023 }
Craig Topper69186e72014-06-08 08:38:04 +00003024 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003025 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003026 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003027 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003028
3029 // Reset the associated diagnostics.
3030 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003031 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003032
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003033 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003034 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3035 setThreadBackgroundPriority();
3036
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003037 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003038 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003039
3040 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3041 new std::vector<ASTUnit::RemappedFile>());
3042
Guy Benyei11169dd2012-12-18 14:30:41 +00003043 // Recover resources if we crash before exiting this function.
3044 llvm::CrashRecoveryContextCleanupRegistrar<
3045 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3046
3047 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3048 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3049 const llvm::MemoryBuffer *Buffer
3050 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3051 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3052 Buffer));
3053 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003054
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003055 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003056 RTUI->result = CXError_Success;
3057 else if (isASTReadError(CXXUnit))
3058 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003059}
3060
3061int clang_reparseTranslationUnit(CXTranslationUnit TU,
3062 unsigned num_unsaved_files,
3063 struct CXUnsavedFile *unsaved_files,
3064 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003065 LOG_FUNC_SECTION {
3066 *Log << TU;
3067 }
3068
Guy Benyei11169dd2012-12-18 14:30:41 +00003069 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003070 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003071
3072 if (getenv("LIBCLANG_NOTHREADS")) {
3073 clang_reparseTranslationUnit_Impl(&RTUI);
3074 return RTUI.result;
3075 }
3076
3077 llvm::CrashRecoveryContext CRC;
3078
3079 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3080 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003081 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003082 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003083 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3084 PrintLibclangResourceUsage(TU);
3085
3086 return RTUI.result;
3087}
3088
3089
3090CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003091 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003092 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003093 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003094 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003095
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003096 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003097 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003098}
3099
3100CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003101 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003102 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003103 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003104 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003105
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003106 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3108}
3109
3110} // end: extern "C"
3111
3112//===----------------------------------------------------------------------===//
3113// CXFile Operations.
3114//===----------------------------------------------------------------------===//
3115
3116extern "C" {
3117CXString clang_getFileName(CXFile SFile) {
3118 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003119 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003120
3121 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003122 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003123}
3124
3125time_t clang_getFileTime(CXFile SFile) {
3126 if (!SFile)
3127 return 0;
3128
3129 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3130 return FEnt->getModificationTime();
3131}
3132
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003133CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003134 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003135 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003136 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003137 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003138
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003139 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003140
3141 FileManager &FMgr = CXXUnit->getFileManager();
3142 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3143}
3144
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003145unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3146 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003147 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003148 LOG_BAD_TU(TU);
3149 return 0;
3150 }
3151
3152 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003153 return 0;
3154
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003155 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 FileEntry *FEnt = static_cast<FileEntry *>(file);
3157 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3158 .isFileMultipleIncludeGuarded(FEnt);
3159}
3160
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003161int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3162 if (!file || !outID)
3163 return 1;
3164
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003165 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003166 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3167 outID->data[0] = ID.getDevice();
3168 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003169 outID->data[2] = FEnt->getModificationTime();
3170 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003171}
3172
Guy Benyei11169dd2012-12-18 14:30:41 +00003173} // end: extern "C"
3174
3175//===----------------------------------------------------------------------===//
3176// CXCursor Operations.
3177//===----------------------------------------------------------------------===//
3178
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003179static const Decl *getDeclFromExpr(const Stmt *E) {
3180 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 return getDeclFromExpr(CE->getSubExpr());
3182
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003183 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003187 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 if (PRE->isExplicitProperty())
3191 return PRE->getExplicitProperty();
3192 // It could be messaging both getter and setter as in:
3193 // ++myobj.myprop;
3194 // in which case prefer to associate the setter since it is less obvious
3195 // from inspecting the source that the setter is going to get called.
3196 if (PRE->isMessagingSetter())
3197 return PRE->getImplicitPropertySetter();
3198 return PRE->getImplicitPropertyGetter();
3199 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003200 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003202 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 if (Expr *Src = OVE->getSourceExpr())
3204 return getDeclFromExpr(Src);
3205
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003206 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003207 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003208 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 if (!CE->isElidable())
3210 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003211 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return OME->getMethodDecl();
3213
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003214 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003216 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3218 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003219 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3221 isa<ParmVarDecl>(SizeOfPack->getPack()))
3222 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003223
3224 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003225}
3226
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003227static SourceLocation getLocationFromExpr(const Expr *E) {
3228 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 return getLocationFromExpr(CE->getSubExpr());
3230
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003231 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003233 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003235 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003237 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003239 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003241 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003242 return PropRef->getLocation();
3243
3244 return E->getLocStart();
3245}
3246
3247extern "C" {
3248
3249unsigned clang_visitChildren(CXCursor parent,
3250 CXCursorVisitor visitor,
3251 CXClientData client_data) {
3252 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3253 /*VisitPreprocessorLast=*/false);
3254 return CursorVis.VisitChildren(parent);
3255}
3256
3257#ifndef __has_feature
3258#define __has_feature(x) 0
3259#endif
3260#if __has_feature(blocks)
3261typedef enum CXChildVisitResult
3262 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3263
3264static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3265 CXClientData client_data) {
3266 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3267 return block(cursor, parent);
3268}
3269#else
3270// If we are compiled with a compiler that doesn't have native blocks support,
3271// define and call the block manually, so the
3272typedef struct _CXChildVisitResult
3273{
3274 void *isa;
3275 int flags;
3276 int reserved;
3277 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3278 CXCursor);
3279} *CXCursorVisitorBlock;
3280
3281static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3282 CXClientData client_data) {
3283 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3284 return block->invoke(block, cursor, parent);
3285}
3286#endif
3287
3288
3289unsigned clang_visitChildrenWithBlock(CXCursor parent,
3290 CXCursorVisitorBlock block) {
3291 return clang_visitChildren(parent, visitWithBlock, block);
3292}
3293
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003294static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003296 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003298 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003300 if (const ObjCPropertyImplDecl *PropImpl =
3301 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003303 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003304
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003305 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003307 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003308
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003309 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 }
3311
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003312 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003313 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003314
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003315 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3317 // and returns different names. NamedDecl returns the class name and
3318 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003319 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003320
3321 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003322 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003323
3324 SmallString<1024> S;
3325 llvm::raw_svector_ostream os(S);
3326 ND->printName(os);
3327
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003328 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003329}
3330
3331CXString clang_getCursorSpelling(CXCursor C) {
3332 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003333 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003334
3335 if (clang_isReference(C.kind)) {
3336 switch (C.kind) {
3337 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003338 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003339 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 }
3341 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003342 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003343 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 }
3345 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003346 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003348 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 }
3350 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003351 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003352 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 }
3354 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003355 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003356 assert(Type && "Missing type decl");
3357
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003358 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 getAsString());
3360 }
3361 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003362 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 assert(Template && "Missing template decl");
3364
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003365 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 }
3367
3368 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003369 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 assert(NS && "Missing namespace decl");
3371
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003372 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 }
3374
3375 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003376 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 assert(Field && "Missing member decl");
3378
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003379 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 }
3381
3382 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003383 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 assert(Label && "Missing label");
3385
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003386 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 }
3388
3389 case CXCursor_OverloadedDeclRef: {
3390 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003391 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3392 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003393 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003394 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003395 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003396 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003397 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003398 OverloadedTemplateStorage *Ovl
3399 = Storage.get<OverloadedTemplateStorage*>();
3400 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003401 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003402 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 }
3404
3405 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003406 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 assert(Var && "Missing variable decl");
3408
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003409 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003410 }
3411
3412 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003413 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003414 }
3415 }
3416
3417 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003418 const Expr *E = getCursorExpr(C);
3419
3420 if (C.kind == CXCursor_ObjCStringLiteral ||
3421 C.kind == CXCursor_StringLiteral) {
3422 const StringLiteral *SLit;
3423 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3424 SLit = OSL->getString();
3425 } else {
3426 SLit = cast<StringLiteral>(E);
3427 }
3428 SmallString<256> Buf;
3429 llvm::raw_svector_ostream OS(Buf);
3430 SLit->outputString(OS);
3431 return cxstring::createDup(OS.str());
3432 }
3433
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003434 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 if (D)
3436 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003437 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 }
3439
3440 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003441 const Stmt *S = getCursorStmt(C);
3442 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003443 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003444
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003445 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 }
3447
3448 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003449 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 ->getNameStart());
3451
3452 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003453 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 ->getNameStart());
3455
3456 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003457 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003458
3459 if (clang_isDeclaration(C.kind))
3460 return getDeclSpelling(getCursorDecl(C));
3461
3462 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003463 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003464 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 }
3466
3467 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003468 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003469 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 }
3471
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003472 if (C.kind == CXCursor_PackedAttr) {
3473 return cxstring::createRef("packed");
3474 }
3475
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003476 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003477}
3478
3479CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3480 unsigned pieceIndex,
3481 unsigned options) {
3482 if (clang_Cursor_isNull(C))
3483 return clang_getNullRange();
3484
3485 ASTContext &Ctx = getCursorContext(C);
3486
3487 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003488 const Stmt *S = getCursorStmt(C);
3489 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 if (pieceIndex > 0)
3491 return clang_getNullRange();
3492 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3493 }
3494
3495 return clang_getNullRange();
3496 }
3497
3498 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003499 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3501 if (pieceIndex >= ME->getNumSelectorLocs())
3502 return clang_getNullRange();
3503 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3504 }
3505 }
3506
3507 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3508 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003509 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3511 if (pieceIndex >= MD->getNumSelectorLocs())
3512 return clang_getNullRange();
3513 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3514 }
3515 }
3516
3517 if (C.kind == CXCursor_ObjCCategoryDecl ||
3518 C.kind == CXCursor_ObjCCategoryImplDecl) {
3519 if (pieceIndex > 0)
3520 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003521 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3523 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003524 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3526 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3527 }
3528
3529 if (C.kind == CXCursor_ModuleImportDecl) {
3530 if (pieceIndex > 0)
3531 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003532 if (const ImportDecl *ImportD =
3533 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3535 if (!Locs.empty())
3536 return cxloc::translateSourceRange(Ctx,
3537 SourceRange(Locs.front(), Locs.back()));
3538 }
3539 return clang_getNullRange();
3540 }
3541
3542 // FIXME: A CXCursor_InclusionDirective should give the location of the
3543 // filename, but we don't keep track of this.
3544
3545 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3546 // but we don't keep track of this.
3547
3548 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3549 // but we don't keep track of this.
3550
3551 // Default handling, give the location of the cursor.
3552
3553 if (pieceIndex > 0)
3554 return clang_getNullRange();
3555
3556 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3557 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3558 return cxloc::translateSourceRange(Ctx, Loc);
3559}
3560
3561CXString clang_getCursorDisplayName(CXCursor C) {
3562 if (!clang_isDeclaration(C.kind))
3563 return clang_getCursorSpelling(C);
3564
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003565 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003567 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003568
3569 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003570 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 D = FunTmpl->getTemplatedDecl();
3572
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003573 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 SmallString<64> Str;
3575 llvm::raw_svector_ostream OS(Str);
3576 OS << *Function;
3577 if (Function->getPrimaryTemplate())
3578 OS << "<>";
3579 OS << "(";
3580 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3581 if (I)
3582 OS << ", ";
3583 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3584 }
3585
3586 if (Function->isVariadic()) {
3587 if (Function->getNumParams())
3588 OS << ", ";
3589 OS << "...";
3590 }
3591 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003592 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 }
3594
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003595 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 SmallString<64> Str;
3597 llvm::raw_svector_ostream OS(Str);
3598 OS << *ClassTemplate;
3599 OS << "<";
3600 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3601 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3602 if (I)
3603 OS << ", ";
3604
3605 NamedDecl *Param = Params->getParam(I);
3606 if (Param->getIdentifier()) {
3607 OS << Param->getIdentifier()->getName();
3608 continue;
3609 }
3610
3611 // There is no parameter name, which makes this tricky. Try to come up
3612 // with something useful that isn't too long.
3613 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3614 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3615 else if (NonTypeTemplateParmDecl *NTTP
3616 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3617 OS << NTTP->getType().getAsString(Policy);
3618 else
3619 OS << "template<...> class";
3620 }
3621
3622 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003623 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 }
3625
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003626 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3628 // If the type was explicitly written, use that.
3629 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003630 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003631
Benjamin Kramer9170e912013-02-22 15:46:01 +00003632 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 llvm::raw_svector_ostream OS(Str);
3634 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003635 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 ClassSpec->getTemplateArgs().data(),
3637 ClassSpec->getTemplateArgs().size(),
3638 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003639 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 }
3641
3642 return clang_getCursorSpelling(C);
3643}
3644
3645CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3646 switch (Kind) {
3647 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003775 case CXCursor_ObjCSelfExpr:
3776 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003893 case CXCursor_PackedAttr:
3894 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003895 case CXCursor_PureAttr:
3896 return cxstring::createRef("attribute(pure)");
3897 case CXCursor_ConstAttr:
3898 return cxstring::createRef("attribute(const)");
3899 case CXCursor_NoDuplicateAttr:
3900 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003901 case CXCursor_CUDAConstantAttr:
3902 return cxstring::createRef("attribute(constant)");
3903 case CXCursor_CUDADeviceAttr:
3904 return cxstring::createRef("attribute(device)");
3905 case CXCursor_CUDAGlobalAttr:
3906 return cxstring::createRef("attribute(global)");
3907 case CXCursor_CUDAHostAttr:
3908 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003957 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003958 return cxstring::createRef("OMPParallelDirective");
3959 case CXCursor_OMPSimdDirective:
3960 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003961 case CXCursor_OMPForDirective:
3962 return cxstring::createRef("OMPForDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 }
3964
3965 llvm_unreachable("Unhandled CXCursorKind");
3966}
3967
3968struct GetCursorData {
3969 SourceLocation TokenBeginLoc;
3970 bool PointsAtMacroArgExpansion;
3971 bool VisitedObjCPropertyImplDecl;
3972 SourceLocation VisitedDeclaratorDeclStartLoc;
3973 CXCursor &BestCursor;
3974
3975 GetCursorData(SourceManager &SM,
3976 SourceLocation tokenBegin, CXCursor &outputCursor)
3977 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3978 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3979 VisitedObjCPropertyImplDecl = false;
3980 }
3981};
3982
3983static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3984 CXCursor parent,
3985 CXClientData client_data) {
3986 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3987 CXCursor *BestCursor = &Data->BestCursor;
3988
3989 // If we point inside a macro argument we should provide info of what the
3990 // token is so use the actual cursor, don't replace it with a macro expansion
3991 // cursor.
3992 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3993 return CXChildVisit_Recurse;
3994
3995 if (clang_isDeclaration(cursor.kind)) {
3996 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003997 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3999 if (MD->isImplicit())
4000 return CXChildVisit_Break;
4001
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004002 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4004 // Check that when we have multiple @class references in the same line,
4005 // that later ones do not override the previous ones.
4006 // If we have:
4007 // @class Foo, Bar;
4008 // source ranges for both start at '@', so 'Bar' will end up overriding
4009 // 'Foo' even though the cursor location was at 'Foo'.
4010 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4011 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004012 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4014 if (PrevID != ID &&
4015 !PrevID->isThisDeclarationADefinition() &&
4016 !ID->isThisDeclarationADefinition())
4017 return CXChildVisit_Break;
4018 }
4019
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004020 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4022 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4023 // Check that when we have multiple declarators in the same line,
4024 // that later ones do not override the previous ones.
4025 // If we have:
4026 // int Foo, Bar;
4027 // source ranges for both start at 'int', so 'Bar' will end up overriding
4028 // 'Foo' even though the cursor location was at 'Foo'.
4029 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4030 return CXChildVisit_Break;
4031 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4032
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004033 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4035 (void)PropImp;
4036 // Check that when we have multiple @synthesize in the same line,
4037 // that later ones do not override the previous ones.
4038 // If we have:
4039 // @synthesize Foo, Bar;
4040 // source ranges for both start at '@', so 'Bar' will end up overriding
4041 // 'Foo' even though the cursor location was at 'Foo'.
4042 if (Data->VisitedObjCPropertyImplDecl)
4043 return CXChildVisit_Break;
4044 Data->VisitedObjCPropertyImplDecl = true;
4045 }
4046 }
4047
4048 if (clang_isExpression(cursor.kind) &&
4049 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004050 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 // Avoid having the cursor of an expression replace the declaration cursor
4052 // when the expression source range overlaps the declaration range.
4053 // This can happen for C++ constructor expressions whose range generally
4054 // include the variable declaration, e.g.:
4055 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4056 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4057 D->getLocation() == Data->TokenBeginLoc)
4058 return CXChildVisit_Break;
4059 }
4060 }
4061
4062 // If our current best cursor is the construction of a temporary object,
4063 // don't replace that cursor with a type reference, because we want
4064 // clang_getCursor() to point at the constructor.
4065 if (clang_isExpression(BestCursor->kind) &&
4066 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4067 cursor.kind == CXCursor_TypeRef) {
4068 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4069 // as having the actual point on the type reference.
4070 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4071 return CXChildVisit_Recurse;
4072 }
4073
4074 *BestCursor = cursor;
4075 return CXChildVisit_Recurse;
4076}
4077
4078CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004079 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004080 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004082 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004083
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004084 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4086
4087 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4088 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4089
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004090 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 CXFile SearchFile;
4092 unsigned SearchLine, SearchColumn;
4093 CXFile ResultFile;
4094 unsigned ResultLine, ResultColumn;
4095 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4096 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4097 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004098
4099 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4100 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004101 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004102 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 SearchFileName = clang_getFileName(SearchFile);
4104 ResultFileName = clang_getFileName(ResultFile);
4105 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4106 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004107 *Log << llvm::format("(%s:%d:%d) = %s",
4108 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4109 clang_getCString(KindSpelling))
4110 << llvm::format("(%s:%d:%d):%s%s",
4111 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4112 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 clang_disposeString(SearchFileName);
4114 clang_disposeString(ResultFileName);
4115 clang_disposeString(KindSpelling);
4116 clang_disposeString(USR);
4117
4118 CXCursor Definition = clang_getCursorDefinition(Result);
4119 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4120 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4121 CXString DefinitionKindSpelling
4122 = clang_getCursorKindSpelling(Definition.kind);
4123 CXFile DefinitionFile;
4124 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004125 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004126 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004128 *Log << llvm::format(" -> %s(%s:%d:%d)",
4129 clang_getCString(DefinitionKindSpelling),
4130 clang_getCString(DefinitionFileName),
4131 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 clang_disposeString(DefinitionFileName);
4133 clang_disposeString(DefinitionKindSpelling);
4134 }
4135 }
4136
4137 return Result;
4138}
4139
4140CXCursor clang_getNullCursor(void) {
4141 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4142}
4143
4144unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004145 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4146 // can't set consistently. For example, when visiting a DeclStmt we will set
4147 // it but we don't set it on the result of clang_getCursorDefinition for
4148 // a reference of the same declaration.
4149 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4150 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4151 // to provide that kind of info.
4152 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004153 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004154 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004155 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004156
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 return X == Y;
4158}
4159
4160unsigned clang_hashCursor(CXCursor C) {
4161 unsigned Index = 0;
4162 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4163 Index = 1;
4164
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004165 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 std::make_pair(C.kind, C.data[Index]));
4167}
4168
4169unsigned clang_isInvalid(enum CXCursorKind K) {
4170 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4171}
4172
4173unsigned clang_isDeclaration(enum CXCursorKind K) {
4174 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4175 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4176}
4177
4178unsigned clang_isReference(enum CXCursorKind K) {
4179 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4180}
4181
4182unsigned clang_isExpression(enum CXCursorKind K) {
4183 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4184}
4185
4186unsigned clang_isStatement(enum CXCursorKind K) {
4187 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4188}
4189
4190unsigned clang_isAttribute(enum CXCursorKind K) {
4191 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4192}
4193
4194unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4195 return K == CXCursor_TranslationUnit;
4196}
4197
4198unsigned clang_isPreprocessing(enum CXCursorKind K) {
4199 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4200}
4201
4202unsigned clang_isUnexposed(enum CXCursorKind K) {
4203 switch (K) {
4204 case CXCursor_UnexposedDecl:
4205 case CXCursor_UnexposedExpr:
4206 case CXCursor_UnexposedStmt:
4207 case CXCursor_UnexposedAttr:
4208 return true;
4209 default:
4210 return false;
4211 }
4212}
4213
4214CXCursorKind clang_getCursorKind(CXCursor C) {
4215 return C.kind;
4216}
4217
4218CXSourceLocation clang_getCursorLocation(CXCursor C) {
4219 if (clang_isReference(C.kind)) {
4220 switch (C.kind) {
4221 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004222 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 = getCursorObjCSuperClassRef(C);
4224 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4225 }
4226
4227 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004228 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 = getCursorObjCProtocolRef(C);
4230 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4231 }
4232
4233 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004234 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 = getCursorObjCClassRef(C);
4236 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4237 }
4238
4239 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004240 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4242 }
4243
4244 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004245 std::pair<const TemplateDecl *, SourceLocation> P =
4246 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4248 }
4249
4250 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004251 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4253 }
4254
4255 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004256 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4258 }
4259
4260 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004261 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4263 }
4264
4265 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004266 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 if (!BaseSpec)
4268 return clang_getNullLocation();
4269
4270 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4271 return cxloc::translateSourceLocation(getCursorContext(C),
4272 TSInfo->getTypeLoc().getBeginLoc());
4273
4274 return cxloc::translateSourceLocation(getCursorContext(C),
4275 BaseSpec->getLocStart());
4276 }
4277
4278 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004279 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4281 }
4282
4283 case CXCursor_OverloadedDeclRef:
4284 return cxloc::translateSourceLocation(getCursorContext(C),
4285 getCursorOverloadedDeclRef(C).second);
4286
4287 default:
4288 // FIXME: Need a way to enumerate all non-reference cases.
4289 llvm_unreachable("Missed a reference kind");
4290 }
4291 }
4292
4293 if (clang_isExpression(C.kind))
4294 return cxloc::translateSourceLocation(getCursorContext(C),
4295 getLocationFromExpr(getCursorExpr(C)));
4296
4297 if (clang_isStatement(C.kind))
4298 return cxloc::translateSourceLocation(getCursorContext(C),
4299 getCursorStmt(C)->getLocStart());
4300
4301 if (C.kind == CXCursor_PreprocessingDirective) {
4302 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4303 return cxloc::translateSourceLocation(getCursorContext(C), L);
4304 }
4305
4306 if (C.kind == CXCursor_MacroExpansion) {
4307 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004308 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 return cxloc::translateSourceLocation(getCursorContext(C), L);
4310 }
4311
4312 if (C.kind == CXCursor_MacroDefinition) {
4313 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4314 return cxloc::translateSourceLocation(getCursorContext(C), L);
4315 }
4316
4317 if (C.kind == CXCursor_InclusionDirective) {
4318 SourceLocation L
4319 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4320 return cxloc::translateSourceLocation(getCursorContext(C), L);
4321 }
4322
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004323 if (clang_isAttribute(C.kind)) {
4324 SourceLocation L
4325 = cxcursor::getCursorAttr(C)->getLocation();
4326 return cxloc::translateSourceLocation(getCursorContext(C), L);
4327 }
4328
Guy Benyei11169dd2012-12-18 14:30:41 +00004329 if (!clang_isDeclaration(C.kind))
4330 return clang_getNullLocation();
4331
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004332 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 if (!D)
4334 return clang_getNullLocation();
4335
4336 SourceLocation Loc = D->getLocation();
4337 // FIXME: Multiple variables declared in a single declaration
4338 // currently lack the information needed to correctly determine their
4339 // ranges when accounting for the type-specifier. We use context
4340 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4341 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004342 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004343 if (!cxcursor::isFirstInDeclGroup(C))
4344 Loc = VD->getLocation();
4345 }
4346
4347 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004348 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004349 Loc = MD->getSelectorStartLoc();
4350
4351 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4352}
4353
4354} // end extern "C"
4355
4356CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4357 assert(TU);
4358
4359 // Guard against an invalid SourceLocation, or we may assert in one
4360 // of the following calls.
4361 if (SLoc.isInvalid())
4362 return clang_getNullCursor();
4363
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004364 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004365
4366 // Translate the given source location to make it point at the beginning of
4367 // the token under the cursor.
4368 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4369 CXXUnit->getASTContext().getLangOpts());
4370
4371 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4372 if (SLoc.isValid()) {
4373 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4374 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4375 /*VisitPreprocessorLast=*/true,
4376 /*VisitIncludedEntities=*/false,
4377 SourceLocation(SLoc));
4378 CursorVis.visitFileRegion();
4379 }
4380
4381 return Result;
4382}
4383
4384static SourceRange getRawCursorExtent(CXCursor C) {
4385 if (clang_isReference(C.kind)) {
4386 switch (C.kind) {
4387 case CXCursor_ObjCSuperClassRef:
4388 return getCursorObjCSuperClassRef(C).second;
4389
4390 case CXCursor_ObjCProtocolRef:
4391 return getCursorObjCProtocolRef(C).second;
4392
4393 case CXCursor_ObjCClassRef:
4394 return getCursorObjCClassRef(C).second;
4395
4396 case CXCursor_TypeRef:
4397 return getCursorTypeRef(C).second;
4398
4399 case CXCursor_TemplateRef:
4400 return getCursorTemplateRef(C).second;
4401
4402 case CXCursor_NamespaceRef:
4403 return getCursorNamespaceRef(C).second;
4404
4405 case CXCursor_MemberRef:
4406 return getCursorMemberRef(C).second;
4407
4408 case CXCursor_CXXBaseSpecifier:
4409 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4410
4411 case CXCursor_LabelRef:
4412 return getCursorLabelRef(C).second;
4413
4414 case CXCursor_OverloadedDeclRef:
4415 return getCursorOverloadedDeclRef(C).second;
4416
4417 case CXCursor_VariableRef:
4418 return getCursorVariableRef(C).second;
4419
4420 default:
4421 // FIXME: Need a way to enumerate all non-reference cases.
4422 llvm_unreachable("Missed a reference kind");
4423 }
4424 }
4425
4426 if (clang_isExpression(C.kind))
4427 return getCursorExpr(C)->getSourceRange();
4428
4429 if (clang_isStatement(C.kind))
4430 return getCursorStmt(C)->getSourceRange();
4431
4432 if (clang_isAttribute(C.kind))
4433 return getCursorAttr(C)->getRange();
4434
4435 if (C.kind == CXCursor_PreprocessingDirective)
4436 return cxcursor::getCursorPreprocessingDirective(C);
4437
4438 if (C.kind == CXCursor_MacroExpansion) {
4439 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004440 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 return TU->mapRangeFromPreamble(Range);
4442 }
4443
4444 if (C.kind == CXCursor_MacroDefinition) {
4445 ASTUnit *TU = getCursorASTUnit(C);
4446 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4447 return TU->mapRangeFromPreamble(Range);
4448 }
4449
4450 if (C.kind == CXCursor_InclusionDirective) {
4451 ASTUnit *TU = getCursorASTUnit(C);
4452 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4453 return TU->mapRangeFromPreamble(Range);
4454 }
4455
4456 if (C.kind == CXCursor_TranslationUnit) {
4457 ASTUnit *TU = getCursorASTUnit(C);
4458 FileID MainID = TU->getSourceManager().getMainFileID();
4459 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4460 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4461 return SourceRange(Start, End);
4462 }
4463
4464 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004465 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 if (!D)
4467 return SourceRange();
4468
4469 SourceRange R = D->getSourceRange();
4470 // FIXME: Multiple variables declared in a single declaration
4471 // currently lack the information needed to correctly determine their
4472 // ranges when accounting for the type-specifier. We use context
4473 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4474 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004475 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 if (!cxcursor::isFirstInDeclGroup(C))
4477 R.setBegin(VD->getLocation());
4478 }
4479 return R;
4480 }
4481 return SourceRange();
4482}
4483
4484/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4485/// the decl-specifier-seq for declarations.
4486static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4487 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004488 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 if (!D)
4490 return SourceRange();
4491
4492 SourceRange R = D->getSourceRange();
4493
4494 // Adjust the start of the location for declarations preceded by
4495 // declaration specifiers.
4496 SourceLocation StartLoc;
4497 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4498 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4499 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004500 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4502 StartLoc = TI->getTypeLoc().getLocStart();
4503 }
4504
4505 if (StartLoc.isValid() && R.getBegin().isValid() &&
4506 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4507 R.setBegin(StartLoc);
4508
4509 // FIXME: Multiple variables declared in a single declaration
4510 // currently lack the information needed to correctly determine their
4511 // ranges when accounting for the type-specifier. We use context
4512 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4513 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004514 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 if (!cxcursor::isFirstInDeclGroup(C))
4516 R.setBegin(VD->getLocation());
4517 }
4518
4519 return R;
4520 }
4521
4522 return getRawCursorExtent(C);
4523}
4524
4525extern "C" {
4526
4527CXSourceRange clang_getCursorExtent(CXCursor C) {
4528 SourceRange R = getRawCursorExtent(C);
4529 if (R.isInvalid())
4530 return clang_getNullRange();
4531
4532 return cxloc::translateSourceRange(getCursorContext(C), R);
4533}
4534
4535CXCursor clang_getCursorReferenced(CXCursor C) {
4536 if (clang_isInvalid(C.kind))
4537 return clang_getNullCursor();
4538
4539 CXTranslationUnit tu = getCursorTU(C);
4540 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004541 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 if (!D)
4543 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004544 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004546 if (const ObjCPropertyImplDecl *PropImpl =
4547 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4549 return MakeCXCursor(Property, tu);
4550
4551 return C;
4552 }
4553
4554 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004555 const Expr *E = getCursorExpr(C);
4556 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 if (D) {
4558 CXCursor declCursor = MakeCXCursor(D, tu);
4559 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4560 declCursor);
4561 return declCursor;
4562 }
4563
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004564 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 return MakeCursorOverloadedDeclRef(Ovl, tu);
4566
4567 return clang_getNullCursor();
4568 }
4569
4570 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004571 const Stmt *S = getCursorStmt(C);
4572 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 if (LabelDecl *label = Goto->getLabel())
4574 if (LabelStmt *labelS = label->getStmt())
4575 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4576
4577 return clang_getNullCursor();
4578 }
4579
4580 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004581 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 return MakeMacroDefinitionCursor(Def, tu);
4583 }
4584
4585 if (!clang_isReference(C.kind))
4586 return clang_getNullCursor();
4587
4588 switch (C.kind) {
4589 case CXCursor_ObjCSuperClassRef:
4590 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4591
4592 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004593 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4594 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 return MakeCXCursor(Def, tu);
4596
4597 return MakeCXCursor(Prot, tu);
4598 }
4599
4600 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004601 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4602 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 return MakeCXCursor(Def, tu);
4604
4605 return MakeCXCursor(Class, tu);
4606 }
4607
4608 case CXCursor_TypeRef:
4609 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4610
4611 case CXCursor_TemplateRef:
4612 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4613
4614 case CXCursor_NamespaceRef:
4615 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4616
4617 case CXCursor_MemberRef:
4618 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4619
4620 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004621 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004622 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4623 tu ));
4624 }
4625
4626 case CXCursor_LabelRef:
4627 // FIXME: We end up faking the "parent" declaration here because we
4628 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004629 return MakeCXCursor(getCursorLabelRef(C).first,
4630 cxtu::getASTUnit(tu)->getASTContext()
4631 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 tu);
4633
4634 case CXCursor_OverloadedDeclRef:
4635 return C;
4636
4637 case CXCursor_VariableRef:
4638 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4639
4640 default:
4641 // We would prefer to enumerate all non-reference cursor kinds here.
4642 llvm_unreachable("Unhandled reference cursor kind");
4643 }
4644}
4645
4646CXCursor clang_getCursorDefinition(CXCursor C) {
4647 if (clang_isInvalid(C.kind))
4648 return clang_getNullCursor();
4649
4650 CXTranslationUnit TU = getCursorTU(C);
4651
4652 bool WasReference = false;
4653 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4654 C = clang_getCursorReferenced(C);
4655 WasReference = true;
4656 }
4657
4658 if (C.kind == CXCursor_MacroExpansion)
4659 return clang_getCursorReferenced(C);
4660
4661 if (!clang_isDeclaration(C.kind))
4662 return clang_getNullCursor();
4663
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004664 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 if (!D)
4666 return clang_getNullCursor();
4667
4668 switch (D->getKind()) {
4669 // Declaration kinds that don't really separate the notions of
4670 // declaration and definition.
4671 case Decl::Namespace:
4672 case Decl::Typedef:
4673 case Decl::TypeAlias:
4674 case Decl::TypeAliasTemplate:
4675 case Decl::TemplateTypeParm:
4676 case Decl::EnumConstant:
4677 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004678 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 case Decl::IndirectField:
4680 case Decl::ObjCIvar:
4681 case Decl::ObjCAtDefsField:
4682 case Decl::ImplicitParam:
4683 case Decl::ParmVar:
4684 case Decl::NonTypeTemplateParm:
4685 case Decl::TemplateTemplateParm:
4686 case Decl::ObjCCategoryImpl:
4687 case Decl::ObjCImplementation:
4688 case Decl::AccessSpec:
4689 case Decl::LinkageSpec:
4690 case Decl::ObjCPropertyImpl:
4691 case Decl::FileScopeAsm:
4692 case Decl::StaticAssert:
4693 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004694 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 case Decl::Label: // FIXME: Is this right??
4696 case Decl::ClassScopeFunctionSpecialization:
4697 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004698 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 return C;
4700
4701 // Declaration kinds that don't make any sense here, but are
4702 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004703 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004704 case Decl::TranslationUnit:
4705 break;
4706
4707 // Declaration kinds for which the definition is not resolvable.
4708 case Decl::UnresolvedUsingTypename:
4709 case Decl::UnresolvedUsingValue:
4710 break;
4711
4712 case Decl::UsingDirective:
4713 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4714 TU);
4715
4716 case Decl::NamespaceAlias:
4717 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4718
4719 case Decl::Enum:
4720 case Decl::Record:
4721 case Decl::CXXRecord:
4722 case Decl::ClassTemplateSpecialization:
4723 case Decl::ClassTemplatePartialSpecialization:
4724 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4725 return MakeCXCursor(Def, TU);
4726 return clang_getNullCursor();
4727
4728 case Decl::Function:
4729 case Decl::CXXMethod:
4730 case Decl::CXXConstructor:
4731 case Decl::CXXDestructor:
4732 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004733 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004735 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 return clang_getNullCursor();
4737 }
4738
Larisse Voufo39a1e502013-08-06 01:03:05 +00004739 case Decl::Var:
4740 case Decl::VarTemplateSpecialization:
4741 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004743 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 return MakeCXCursor(Def, TU);
4745 return clang_getNullCursor();
4746 }
4747
4748 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004749 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4751 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4752 return clang_getNullCursor();
4753 }
4754
4755 case Decl::ClassTemplate: {
4756 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4757 ->getDefinition())
4758 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4759 TU);
4760 return clang_getNullCursor();
4761 }
4762
Larisse Voufo39a1e502013-08-06 01:03:05 +00004763 case Decl::VarTemplate: {
4764 if (VarDecl *Def =
4765 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4766 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4767 return clang_getNullCursor();
4768 }
4769
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 case Decl::Using:
4771 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4772 D->getLocation(), TU);
4773
4774 case Decl::UsingShadow:
4775 return clang_getCursorDefinition(
4776 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4777 TU));
4778
4779 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004780 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 if (Method->isThisDeclarationADefinition())
4782 return C;
4783
4784 // Dig out the method definition in the associated
4785 // @implementation, if we have it.
4786 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004787 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004788 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4789 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4790 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4791 Method->isInstanceMethod()))
4792 if (Def->isThisDeclarationADefinition())
4793 return MakeCXCursor(Def, TU);
4794
4795 return clang_getNullCursor();
4796 }
4797
4798 case Decl::ObjCCategory:
4799 if (ObjCCategoryImplDecl *Impl
4800 = cast<ObjCCategoryDecl>(D)->getImplementation())
4801 return MakeCXCursor(Impl, TU);
4802 return clang_getNullCursor();
4803
4804 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004805 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004806 return MakeCXCursor(Def, TU);
4807 return clang_getNullCursor();
4808
4809 case Decl::ObjCInterface: {
4810 // There are two notions of a "definition" for an Objective-C
4811 // class: the interface and its implementation. When we resolved a
4812 // reference to an Objective-C class, produce the @interface as
4813 // the definition; when we were provided with the interface,
4814 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004815 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004816 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004817 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 return MakeCXCursor(Def, TU);
4819 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4820 return MakeCXCursor(Impl, TU);
4821 return clang_getNullCursor();
4822 }
4823
4824 case Decl::ObjCProperty:
4825 // FIXME: We don't really know where to find the
4826 // ObjCPropertyImplDecls that implement this property.
4827 return clang_getNullCursor();
4828
4829 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004830 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004831 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004832 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004833 return MakeCXCursor(Def, TU);
4834
4835 return clang_getNullCursor();
4836
4837 case Decl::Friend:
4838 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4839 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4840 return clang_getNullCursor();
4841
4842 case Decl::FriendTemplate:
4843 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4844 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4845 return clang_getNullCursor();
4846 }
4847
4848 return clang_getNullCursor();
4849}
4850
4851unsigned clang_isCursorDefinition(CXCursor C) {
4852 if (!clang_isDeclaration(C.kind))
4853 return 0;
4854
4855 return clang_getCursorDefinition(C) == C;
4856}
4857
4858CXCursor clang_getCanonicalCursor(CXCursor C) {
4859 if (!clang_isDeclaration(C.kind))
4860 return C;
4861
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004862 if (const Decl *D = getCursorDecl(C)) {
4863 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004864 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4865 return MakeCXCursor(CatD, getCursorTU(C));
4866
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004867 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4868 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 return MakeCXCursor(IFD, getCursorTU(C));
4870
4871 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4872 }
4873
4874 return C;
4875}
4876
4877int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4878 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4879}
4880
4881unsigned clang_getNumOverloadedDecls(CXCursor C) {
4882 if (C.kind != CXCursor_OverloadedDeclRef)
4883 return 0;
4884
4885 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004886 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 return E->getNumDecls();
4888
4889 if (OverloadedTemplateStorage *S
4890 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4891 return S->size();
4892
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004893 const Decl *D = Storage.get<const Decl *>();
4894 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004895 return Using->shadow_size();
4896
4897 return 0;
4898}
4899
4900CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4901 if (cursor.kind != CXCursor_OverloadedDeclRef)
4902 return clang_getNullCursor();
4903
4904 if (index >= clang_getNumOverloadedDecls(cursor))
4905 return clang_getNullCursor();
4906
4907 CXTranslationUnit TU = getCursorTU(cursor);
4908 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004909 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004910 return MakeCXCursor(E->decls_begin()[index], TU);
4911
4912 if (OverloadedTemplateStorage *S
4913 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4914 return MakeCXCursor(S->begin()[index], TU);
4915
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004916 const Decl *D = Storage.get<const Decl *>();
4917 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004918 // FIXME: This is, unfortunately, linear time.
4919 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4920 std::advance(Pos, index);
4921 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4922 }
4923
4924 return clang_getNullCursor();
4925}
4926
4927void clang_getDefinitionSpellingAndExtent(CXCursor C,
4928 const char **startBuf,
4929 const char **endBuf,
4930 unsigned *startLine,
4931 unsigned *startColumn,
4932 unsigned *endLine,
4933 unsigned *endColumn) {
4934 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004935 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004936 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4937
4938 SourceManager &SM = FD->getASTContext().getSourceManager();
4939 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4940 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4941 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4942 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4943 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4944 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4945}
4946
4947
4948CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4949 unsigned PieceIndex) {
4950 RefNamePieces Pieces;
4951
4952 switch (C.kind) {
4953 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004954 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4956 E->getQualifierLoc().getSourceRange());
4957 break;
4958
4959 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004960 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004961 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4962 E->getQualifierLoc().getSourceRange(),
4963 E->getOptionalExplicitTemplateArgs());
4964 break;
4965
4966 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004967 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004968 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004969 const Expr *Callee = OCE->getCallee();
4970 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004971 Callee = ICE->getSubExpr();
4972
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004973 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004974 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4975 DRE->getQualifierLoc().getSourceRange());
4976 }
4977 break;
4978
4979 default:
4980 break;
4981 }
4982
4983 if (Pieces.empty()) {
4984 if (PieceIndex == 0)
4985 return clang_getCursorExtent(C);
4986 } else if (PieceIndex < Pieces.size()) {
4987 SourceRange R = Pieces[PieceIndex];
4988 if (R.isValid())
4989 return cxloc::translateSourceRange(getCursorContext(C), R);
4990 }
4991
4992 return clang_getNullRange();
4993}
4994
4995void clang_enableStackTraces(void) {
4996 llvm::sys::PrintStackTraceOnErrorSignal();
4997}
4998
4999void clang_executeOnThread(void (*fn)(void*), void *user_data,
5000 unsigned stack_size) {
5001 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5002}
5003
5004} // end: extern "C"
5005
5006//===----------------------------------------------------------------------===//
5007// Token-based Operations.
5008//===----------------------------------------------------------------------===//
5009
5010/* CXToken layout:
5011 * int_data[0]: a CXTokenKind
5012 * int_data[1]: starting token location
5013 * int_data[2]: token length
5014 * int_data[3]: reserved
5015 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5016 * otherwise unused.
5017 */
5018extern "C" {
5019
5020CXTokenKind clang_getTokenKind(CXToken CXTok) {
5021 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5022}
5023
5024CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5025 switch (clang_getTokenKind(CXTok)) {
5026 case CXToken_Identifier:
5027 case CXToken_Keyword:
5028 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005029 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005030 ->getNameStart());
5031
5032 case CXToken_Literal: {
5033 // We have stashed the starting pointer in the ptr_data field. Use it.
5034 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005035 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005036 }
5037
5038 case CXToken_Punctuation:
5039 case CXToken_Comment:
5040 break;
5041 }
5042
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005043 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005044 LOG_BAD_TU(TU);
5045 return cxstring::createEmpty();
5046 }
5047
Guy Benyei11169dd2012-12-18 14:30:41 +00005048 // We have to find the starting buffer pointer the hard way, by
5049 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005050 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005051 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005052 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005053
5054 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5055 std::pair<FileID, unsigned> LocInfo
5056 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5057 bool Invalid = false;
5058 StringRef Buffer
5059 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5060 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005061 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005062
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005063 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005064}
5065
5066CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005067 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005068 LOG_BAD_TU(TU);
5069 return clang_getNullLocation();
5070 }
5071
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005072 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005073 if (!CXXUnit)
5074 return clang_getNullLocation();
5075
5076 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5077 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5078}
5079
5080CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005081 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005082 LOG_BAD_TU(TU);
5083 return clang_getNullRange();
5084 }
5085
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005086 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 if (!CXXUnit)
5088 return clang_getNullRange();
5089
5090 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5091 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5092}
5093
5094static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5095 SmallVectorImpl<CXToken> &CXTokens) {
5096 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5097 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005098 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005100 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005101
5102 // Cannot tokenize across files.
5103 if (BeginLocInfo.first != EndLocInfo.first)
5104 return;
5105
5106 // Create a lexer
5107 bool Invalid = false;
5108 StringRef Buffer
5109 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5110 if (Invalid)
5111 return;
5112
5113 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5114 CXXUnit->getASTContext().getLangOpts(),
5115 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5116 Lex.SetCommentRetentionState(true);
5117
5118 // Lex tokens until we hit the end of the range.
5119 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5120 Token Tok;
5121 bool previousWasAt = false;
5122 do {
5123 // Lex the next token
5124 Lex.LexFromRawLexer(Tok);
5125 if (Tok.is(tok::eof))
5126 break;
5127
5128 // Initialize the CXToken.
5129 CXToken CXTok;
5130
5131 // - Common fields
5132 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5133 CXTok.int_data[2] = Tok.getLength();
5134 CXTok.int_data[3] = 0;
5135
5136 // - Kind-specific fields
5137 if (Tok.isLiteral()) {
5138 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005139 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 } else if (Tok.is(tok::raw_identifier)) {
5141 // Lookup the identifier to determine whether we have a keyword.
5142 IdentifierInfo *II
5143 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5144
5145 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5146 CXTok.int_data[0] = CXToken_Keyword;
5147 }
5148 else {
5149 CXTok.int_data[0] = Tok.is(tok::identifier)
5150 ? CXToken_Identifier
5151 : CXToken_Keyword;
5152 }
5153 CXTok.ptr_data = II;
5154 } else if (Tok.is(tok::comment)) {
5155 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005156 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005157 } else {
5158 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005159 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 }
5161 CXTokens.push_back(CXTok);
5162 previousWasAt = Tok.is(tok::at);
5163 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5164}
5165
5166void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5167 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005168 LOG_FUNC_SECTION {
5169 *Log << TU << ' ' << Range;
5170 }
5171
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005173 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 if (NumTokens)
5175 *NumTokens = 0;
5176
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005177 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005178 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005179 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005180 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005181
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005182 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005183 if (!CXXUnit || !Tokens || !NumTokens)
5184 return;
5185
5186 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5187
5188 SourceRange R = cxloc::translateCXSourceRange(Range);
5189 if (R.isInvalid())
5190 return;
5191
5192 SmallVector<CXToken, 32> CXTokens;
5193 getTokens(CXXUnit, R, CXTokens);
5194
5195 if (CXTokens.empty())
5196 return;
5197
5198 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5199 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5200 *NumTokens = CXTokens.size();
5201}
5202
5203void clang_disposeTokens(CXTranslationUnit TU,
5204 CXToken *Tokens, unsigned NumTokens) {
5205 free(Tokens);
5206}
5207
5208} // end: extern "C"
5209
5210//===----------------------------------------------------------------------===//
5211// Token annotation APIs.
5212//===----------------------------------------------------------------------===//
5213
Guy Benyei11169dd2012-12-18 14:30:41 +00005214static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5215 CXCursor parent,
5216 CXClientData client_data);
5217static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5218 CXClientData client_data);
5219
5220namespace {
5221class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 CXToken *Tokens;
5223 CXCursor *Cursors;
5224 unsigned NumTokens;
5225 unsigned TokIdx;
5226 unsigned PreprocessingTokIdx;
5227 CursorVisitor AnnotateVis;
5228 SourceManager &SrcMgr;
5229 bool HasContextSensitiveKeywords;
5230
5231 struct PostChildrenInfo {
5232 CXCursor Cursor;
5233 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005234 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005235 unsigned BeforeChildrenTokenIdx;
5236 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005237 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005238
5239 CXToken &getTok(unsigned Idx) {
5240 assert(Idx < NumTokens);
5241 return Tokens[Idx];
5242 }
5243 const CXToken &getTok(unsigned Idx) const {
5244 assert(Idx < NumTokens);
5245 return Tokens[Idx];
5246 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005247 bool MoreTokens() const { return TokIdx < NumTokens; }
5248 unsigned NextToken() const { return TokIdx; }
5249 void AdvanceToken() { ++TokIdx; }
5250 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005251 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 }
5253 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005254 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 }
5256 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005257 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 }
5259
5260 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005261 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 SourceRange);
5263
5264public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005265 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005266 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005267 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005269 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 AnnotateTokensVisitor, this,
5271 /*VisitPreprocessorLast=*/true,
5272 /*VisitIncludedEntities=*/false,
5273 RegionOfInterest,
5274 /*VisitDeclsOnly=*/false,
5275 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005276 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 HasContextSensitiveKeywords(false) { }
5278
5279 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5280 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5281 bool postVisitChildren(CXCursor cursor);
5282 void AnnotateTokens();
5283
5284 /// \brief Determine whether the annotator saw any cursors that have
5285 /// context-sensitive keywords.
5286 bool hasContextSensitiveKeywords() const {
5287 return HasContextSensitiveKeywords;
5288 }
5289
5290 ~AnnotateTokensWorker() {
5291 assert(PostChildrenInfos.empty());
5292 }
5293};
5294}
5295
5296void AnnotateTokensWorker::AnnotateTokens() {
5297 // Walk the AST within the region of interest, annotating tokens
5298 // along the way.
5299 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005300}
Guy Benyei11169dd2012-12-18 14:30:41 +00005301
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005302static inline void updateCursorAnnotation(CXCursor &Cursor,
5303 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005304 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005306 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005307}
5308
5309/// \brief It annotates and advances tokens with a cursor until the comparison
5310//// between the cursor location and the source range is the same as
5311/// \arg compResult.
5312///
5313/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5314/// Pass RangeOverlap to annotate tokens inside a range.
5315void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5316 RangeComparisonResult compResult,
5317 SourceRange range) {
5318 while (MoreTokens()) {
5319 const unsigned I = NextToken();
5320 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005321 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5322 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005323
5324 SourceLocation TokLoc = GetTokenLoc(I);
5325 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005326 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005327 AdvanceToken();
5328 continue;
5329 }
5330 break;
5331 }
5332}
5333
5334/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005335/// \returns true if it advanced beyond all macro tokens, false otherwise.
5336bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005337 CXCursor updateC,
5338 RangeComparisonResult compResult,
5339 SourceRange range) {
5340 assert(MoreTokens());
5341 assert(isFunctionMacroToken(NextToken()) &&
5342 "Should be called only for macro arg tokens");
5343
5344 // This works differently than annotateAndAdvanceTokens; because expanded
5345 // macro arguments can have arbitrary translation-unit source order, we do not
5346 // advance the token index one by one until a token fails the range test.
5347 // We only advance once past all of the macro arg tokens if all of them
5348 // pass the range test. If one of them fails we keep the token index pointing
5349 // at the start of the macro arg tokens so that the failing token will be
5350 // annotated by a subsequent annotation try.
5351
5352 bool atLeastOneCompFail = false;
5353
5354 unsigned I = NextToken();
5355 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5356 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5357 if (TokLoc.isFileID())
5358 continue; // not macro arg token, it's parens or comma.
5359 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5360 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5361 Cursors[I] = updateC;
5362 } else
5363 atLeastOneCompFail = true;
5364 }
5365
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005366 if (atLeastOneCompFail)
5367 return false;
5368
5369 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5370 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005371}
5372
5373enum CXChildVisitResult
5374AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005375 SourceRange cursorRange = getRawCursorExtent(cursor);
5376 if (cursorRange.isInvalid())
5377 return CXChildVisit_Recurse;
5378
5379 if (!HasContextSensitiveKeywords) {
5380 // Objective-C properties can have context-sensitive keywords.
5381 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005382 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005383 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5384 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5385 }
5386 // Objective-C methods can have context-sensitive keywords.
5387 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5388 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005389 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005390 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5391 if (Method->getObjCDeclQualifier())
5392 HasContextSensitiveKeywords = true;
5393 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005394 for (const auto *P : Method->params()) {
5395 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005396 HasContextSensitiveKeywords = true;
5397 break;
5398 }
5399 }
5400 }
5401 }
5402 }
5403 // C++ methods can have context-sensitive keywords.
5404 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005405 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005406 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5407 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5408 HasContextSensitiveKeywords = true;
5409 }
5410 }
5411 // C++ classes can have context-sensitive keywords.
5412 else if (cursor.kind == CXCursor_StructDecl ||
5413 cursor.kind == CXCursor_ClassDecl ||
5414 cursor.kind == CXCursor_ClassTemplate ||
5415 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005416 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005417 if (D->hasAttr<FinalAttr>())
5418 HasContextSensitiveKeywords = true;
5419 }
5420 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005421
5422 // Don't override a property annotation with its getter/setter method.
5423 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5424 parent.kind == CXCursor_ObjCPropertyDecl)
5425 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005426
5427 if (clang_isPreprocessing(cursor.kind)) {
5428 // Items in the preprocessing record are kept separate from items in
5429 // declarations, so we keep a separate token index.
5430 unsigned SavedTokIdx = TokIdx;
5431 TokIdx = PreprocessingTokIdx;
5432
5433 // Skip tokens up until we catch up to the beginning of the preprocessing
5434 // entry.
5435 while (MoreTokens()) {
5436 const unsigned I = NextToken();
5437 SourceLocation TokLoc = GetTokenLoc(I);
5438 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5439 case RangeBefore:
5440 AdvanceToken();
5441 continue;
5442 case RangeAfter:
5443 case RangeOverlap:
5444 break;
5445 }
5446 break;
5447 }
5448
5449 // Look at all of the tokens within this range.
5450 while (MoreTokens()) {
5451 const unsigned I = NextToken();
5452 SourceLocation TokLoc = GetTokenLoc(I);
5453 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5454 case RangeBefore:
5455 llvm_unreachable("Infeasible");
5456 case RangeAfter:
5457 break;
5458 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005459 // For macro expansions, just note where the beginning of the macro
5460 // expansion occurs.
5461 if (cursor.kind == CXCursor_MacroExpansion) {
5462 if (TokLoc == cursorRange.getBegin())
5463 Cursors[I] = cursor;
5464 AdvanceToken();
5465 break;
5466 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005467 // We may have already annotated macro names inside macro definitions.
5468 if (Cursors[I].kind != CXCursor_MacroExpansion)
5469 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005470 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 continue;
5472 }
5473 break;
5474 }
5475
5476 // Save the preprocessing token index; restore the non-preprocessing
5477 // token index.
5478 PreprocessingTokIdx = TokIdx;
5479 TokIdx = SavedTokIdx;
5480 return CXChildVisit_Recurse;
5481 }
5482
5483 if (cursorRange.isInvalid())
5484 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005485
5486 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005488 const enum CXCursorKind K = clang_getCursorKind(parent);
5489 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005490 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5491 // Attributes are annotated out-of-order, skip tokens until we reach it.
5492 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005493 ? clang_getNullCursor() : parent;
5494
5495 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5496
5497 // Avoid having the cursor of an expression "overwrite" the annotation of the
5498 // variable declaration that it belongs to.
5499 // This can happen for C++ constructor expressions whose range generally
5500 // include the variable declaration, e.g.:
5501 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005502 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005503 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005504 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005505 const unsigned I = NextToken();
5506 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5507 E->getLocStart() == D->getLocation() &&
5508 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005509 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005510 AdvanceToken();
5511 }
5512 }
5513 }
5514
5515 // Before recursing into the children keep some state that we are going
5516 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5517 // extra work after the child nodes are visited.
5518 // Note that we don't call VisitChildren here to avoid traversing statements
5519 // code-recursively which can blow the stack.
5520
5521 PostChildrenInfo Info;
5522 Info.Cursor = cursor;
5523 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005524 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 Info.BeforeChildrenTokenIdx = NextToken();
5526 PostChildrenInfos.push_back(Info);
5527
5528 return CXChildVisit_Recurse;
5529}
5530
5531bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5532 if (PostChildrenInfos.empty())
5533 return false;
5534 const PostChildrenInfo &Info = PostChildrenInfos.back();
5535 if (!clang_equalCursors(Info.Cursor, cursor))
5536 return false;
5537
5538 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5539 const unsigned AfterChildren = NextToken();
5540 SourceRange cursorRange = Info.CursorRange;
5541
5542 // Scan the tokens that are at the end of the cursor, but are not captured
5543 // but the child cursors.
5544 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5545
5546 // Scan the tokens that are at the beginning of the cursor, but are not
5547 // capture by the child cursors.
5548 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5549 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5550 break;
5551
5552 Cursors[I] = cursor;
5553 }
5554
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005555 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5556 // encountered the attribute cursor.
5557 if (clang_isAttribute(cursor.kind))
5558 TokIdx = Info.BeforeReachingCursorIdx;
5559
Guy Benyei11169dd2012-12-18 14:30:41 +00005560 PostChildrenInfos.pop_back();
5561 return false;
5562}
5563
5564static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5565 CXCursor parent,
5566 CXClientData client_data) {
5567 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5568}
5569
5570static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5571 CXClientData client_data) {
5572 return static_cast<AnnotateTokensWorker*>(client_data)->
5573 postVisitChildren(cursor);
5574}
5575
5576namespace {
5577
5578/// \brief Uses the macro expansions in the preprocessing record to find
5579/// and mark tokens that are macro arguments. This info is used by the
5580/// AnnotateTokensWorker.
5581class MarkMacroArgTokensVisitor {
5582 SourceManager &SM;
5583 CXToken *Tokens;
5584 unsigned NumTokens;
5585 unsigned CurIdx;
5586
5587public:
5588 MarkMacroArgTokensVisitor(SourceManager &SM,
5589 CXToken *tokens, unsigned numTokens)
5590 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5591
5592 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5593 if (cursor.kind != CXCursor_MacroExpansion)
5594 return CXChildVisit_Continue;
5595
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005596 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005597 if (macroRange.getBegin() == macroRange.getEnd())
5598 return CXChildVisit_Continue; // it's not a function macro.
5599
5600 for (; CurIdx < NumTokens; ++CurIdx) {
5601 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5602 macroRange.getBegin()))
5603 break;
5604 }
5605
5606 if (CurIdx == NumTokens)
5607 return CXChildVisit_Break;
5608
5609 for (; CurIdx < NumTokens; ++CurIdx) {
5610 SourceLocation tokLoc = getTokenLoc(CurIdx);
5611 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5612 break;
5613
5614 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5615 }
5616
5617 if (CurIdx == NumTokens)
5618 return CXChildVisit_Break;
5619
5620 return CXChildVisit_Continue;
5621 }
5622
5623private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005624 CXToken &getTok(unsigned Idx) {
5625 assert(Idx < NumTokens);
5626 return Tokens[Idx];
5627 }
5628 const CXToken &getTok(unsigned Idx) const {
5629 assert(Idx < NumTokens);
5630 return Tokens[Idx];
5631 }
5632
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005634 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 }
5636
5637 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5638 // The third field is reserved and currently not used. Use it here
5639 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005640 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005641 }
5642};
5643
5644} // end anonymous namespace
5645
5646static CXChildVisitResult
5647MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5648 CXClientData client_data) {
5649 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5650 parent);
5651}
5652
5653namespace {
5654 struct clang_annotateTokens_Data {
5655 CXTranslationUnit TU;
5656 ASTUnit *CXXUnit;
5657 CXToken *Tokens;
5658 unsigned NumTokens;
5659 CXCursor *Cursors;
5660 };
5661}
5662
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005663/// \brief Used by \c annotatePreprocessorTokens.
5664/// \returns true if lexing was finished, false otherwise.
5665static bool lexNext(Lexer &Lex, Token &Tok,
5666 unsigned &NextIdx, unsigned NumTokens) {
5667 if (NextIdx >= NumTokens)
5668 return true;
5669
5670 ++NextIdx;
5671 Lex.LexFromRawLexer(Tok);
5672 if (Tok.is(tok::eof))
5673 return true;
5674
5675 return false;
5676}
5677
Guy Benyei11169dd2012-12-18 14:30:41 +00005678static void annotatePreprocessorTokens(CXTranslationUnit TU,
5679 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005680 CXCursor *Cursors,
5681 CXToken *Tokens,
5682 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005683 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005684
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005685 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005686 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5687 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005688 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005689 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005690 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005691
5692 if (BeginLocInfo.first != EndLocInfo.first)
5693 return;
5694
5695 StringRef Buffer;
5696 bool Invalid = false;
5697 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5698 if (Buffer.empty() || Invalid)
5699 return;
5700
5701 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5702 CXXUnit->getASTContext().getLangOpts(),
5703 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5704 Buffer.end());
5705 Lex.SetCommentRetentionState(true);
5706
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005707 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005708 // Lex tokens in raw mode until we hit the end of the range, to avoid
5709 // entering #includes or expanding macros.
5710 while (true) {
5711 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005712 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5713 break;
5714 unsigned TokIdx = NextIdx-1;
5715 assert(Tok.getLocation() ==
5716 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005717
5718 reprocess:
5719 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005720 // We have found a preprocessing directive. Annotate the tokens
5721 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 //
5723 // FIXME: Some simple tests here could identify macro definitions and
5724 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005725
5726 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005727 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5728 break;
5729
Craig Topper69186e72014-06-08 08:38:04 +00005730 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005731 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005732 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5733 break;
5734
5735 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005736 IdentifierInfo &II =
5737 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005738 SourceLocation MappedTokLoc =
5739 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5740 MI = getMacroInfo(II, MappedTokLoc, TU);
5741 }
5742 }
5743
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005744 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005745 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005746 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5747 finished = true;
5748 break;
5749 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005750 // If we are in a macro definition, check if the token was ever a
5751 // macro name and annotate it if that's the case.
5752 if (MI) {
5753 SourceLocation SaveLoc = Tok.getLocation();
5754 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5755 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5756 Tok.setLocation(SaveLoc);
5757 if (MacroDef)
5758 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5759 Tok.getLocation(), TU);
5760 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005761 } while (!Tok.isAtStartOfLine());
5762
5763 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5764 assert(TokIdx <= LastIdx);
5765 SourceLocation EndLoc =
5766 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5767 CXCursor Cursor =
5768 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5769
5770 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005771 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005772
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005773 if (finished)
5774 break;
5775 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005776 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005777 }
5778}
5779
5780// This gets run a separate thread to avoid stack blowout.
5781static void clang_annotateTokensImpl(void *UserData) {
5782 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5783 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5784 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5785 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5786 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5787
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005788 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005789 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5790 setThreadBackgroundPriority();
5791
5792 // Determine the region of interest, which contains all of the tokens.
5793 SourceRange RegionOfInterest;
5794 RegionOfInterest.setBegin(
5795 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5796 RegionOfInterest.setEnd(
5797 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5798 Tokens[NumTokens-1])));
5799
Guy Benyei11169dd2012-12-18 14:30:41 +00005800 // Relex the tokens within the source range to look for preprocessing
5801 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005802 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005803
5804 // If begin location points inside a macro argument, set it to the expansion
5805 // location so we can have the full context when annotating semantically.
5806 {
5807 SourceManager &SM = CXXUnit->getSourceManager();
5808 SourceLocation Loc =
5809 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5810 if (Loc.isMacroID())
5811 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5812 }
5813
Guy Benyei11169dd2012-12-18 14:30:41 +00005814 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5815 // Search and mark tokens that are macro argument expansions.
5816 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5817 Tokens, NumTokens);
5818 CursorVisitor MacroArgMarker(TU,
5819 MarkMacroArgTokensVisitorDelegate, &Visitor,
5820 /*VisitPreprocessorLast=*/true,
5821 /*VisitIncludedEntities=*/false,
5822 RegionOfInterest);
5823 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5824 }
5825
5826 // Annotate all of the source locations in the region of interest that map to
5827 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005828 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005829
5830 // FIXME: We use a ridiculous stack size here because the data-recursion
5831 // algorithm uses a large stack frame than the non-data recursive version,
5832 // and AnnotationTokensWorker currently transforms the data-recursion
5833 // algorithm back into a traditional recursion by explicitly calling
5834 // VisitChildren(). We will need to remove this explicit recursive call.
5835 W.AnnotateTokens();
5836
5837 // If we ran into any entities that involve context-sensitive keywords,
5838 // take another pass through the tokens to mark them as such.
5839 if (W.hasContextSensitiveKeywords()) {
5840 for (unsigned I = 0; I != NumTokens; ++I) {
5841 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5842 continue;
5843
5844 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5845 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005846 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005847 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5848 if (Property->getPropertyAttributesAsWritten() != 0 &&
5849 llvm::StringSwitch<bool>(II->getName())
5850 .Case("readonly", true)
5851 .Case("assign", true)
5852 .Case("unsafe_unretained", true)
5853 .Case("readwrite", true)
5854 .Case("retain", true)
5855 .Case("copy", true)
5856 .Case("nonatomic", true)
5857 .Case("atomic", true)
5858 .Case("getter", true)
5859 .Case("setter", true)
5860 .Case("strong", true)
5861 .Case("weak", true)
5862 .Default(false))
5863 Tokens[I].int_data[0] = CXToken_Keyword;
5864 }
5865 continue;
5866 }
5867
5868 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5869 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5870 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5871 if (llvm::StringSwitch<bool>(II->getName())
5872 .Case("in", true)
5873 .Case("out", true)
5874 .Case("inout", true)
5875 .Case("oneway", true)
5876 .Case("bycopy", true)
5877 .Case("byref", true)
5878 .Default(false))
5879 Tokens[I].int_data[0] = CXToken_Keyword;
5880 continue;
5881 }
5882
5883 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5884 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5885 Tokens[I].int_data[0] = CXToken_Keyword;
5886 continue;
5887 }
5888 }
5889 }
5890}
5891
5892extern "C" {
5893
5894void clang_annotateTokens(CXTranslationUnit TU,
5895 CXToken *Tokens, unsigned NumTokens,
5896 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005897 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005898 LOG_BAD_TU(TU);
5899 return;
5900 }
5901 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005902 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005903 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005904 }
5905
5906 LOG_FUNC_SECTION {
5907 *Log << TU << ' ';
5908 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5909 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5910 *Log << clang_getRange(bloc, eloc);
5911 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005912
5913 // Any token we don't specifically annotate will have a NULL cursor.
5914 CXCursor C = clang_getNullCursor();
5915 for (unsigned I = 0; I != NumTokens; ++I)
5916 Cursors[I] = C;
5917
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005918 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005919 if (!CXXUnit)
5920 return;
5921
5922 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5923
5924 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5925 llvm::CrashRecoveryContext CRC;
5926 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5927 GetSafetyThreadStackSize() * 2)) {
5928 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5929 }
5930}
5931
5932} // end: extern "C"
5933
5934//===----------------------------------------------------------------------===//
5935// Operations for querying linkage of a cursor.
5936//===----------------------------------------------------------------------===//
5937
5938extern "C" {
5939CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5940 if (!clang_isDeclaration(cursor.kind))
5941 return CXLinkage_Invalid;
5942
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005943 const Decl *D = cxcursor::getCursorDecl(cursor);
5944 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005945 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005946 case NoLinkage:
5947 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005948 case InternalLinkage: return CXLinkage_Internal;
5949 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5950 case ExternalLinkage: return CXLinkage_External;
5951 };
5952
5953 return CXLinkage_Invalid;
5954}
5955} // end: extern "C"
5956
5957//===----------------------------------------------------------------------===//
5958// Operations for querying language of a cursor.
5959//===----------------------------------------------------------------------===//
5960
5961static CXLanguageKind getDeclLanguage(const Decl *D) {
5962 if (!D)
5963 return CXLanguage_C;
5964
5965 switch (D->getKind()) {
5966 default:
5967 break;
5968 case Decl::ImplicitParam:
5969 case Decl::ObjCAtDefsField:
5970 case Decl::ObjCCategory:
5971 case Decl::ObjCCategoryImpl:
5972 case Decl::ObjCCompatibleAlias:
5973 case Decl::ObjCImplementation:
5974 case Decl::ObjCInterface:
5975 case Decl::ObjCIvar:
5976 case Decl::ObjCMethod:
5977 case Decl::ObjCProperty:
5978 case Decl::ObjCPropertyImpl:
5979 case Decl::ObjCProtocol:
5980 return CXLanguage_ObjC;
5981 case Decl::CXXConstructor:
5982 case Decl::CXXConversion:
5983 case Decl::CXXDestructor:
5984 case Decl::CXXMethod:
5985 case Decl::CXXRecord:
5986 case Decl::ClassTemplate:
5987 case Decl::ClassTemplatePartialSpecialization:
5988 case Decl::ClassTemplateSpecialization:
5989 case Decl::Friend:
5990 case Decl::FriendTemplate:
5991 case Decl::FunctionTemplate:
5992 case Decl::LinkageSpec:
5993 case Decl::Namespace:
5994 case Decl::NamespaceAlias:
5995 case Decl::NonTypeTemplateParm:
5996 case Decl::StaticAssert:
5997 case Decl::TemplateTemplateParm:
5998 case Decl::TemplateTypeParm:
5999 case Decl::UnresolvedUsingTypename:
6000 case Decl::UnresolvedUsingValue:
6001 case Decl::Using:
6002 case Decl::UsingDirective:
6003 case Decl::UsingShadow:
6004 return CXLanguage_CPlusPlus;
6005 }
6006
6007 return CXLanguage_C;
6008}
6009
6010extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006011
6012static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6013 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6014 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006015
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006016 switch (D->getAvailability()) {
6017 case AR_Available:
6018 case AR_NotYetIntroduced:
6019 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006020 return getCursorAvailabilityForDecl(
6021 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006022 return CXAvailability_Available;
6023
6024 case AR_Deprecated:
6025 return CXAvailability_Deprecated;
6026
6027 case AR_Unavailable:
6028 return CXAvailability_NotAvailable;
6029 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006030
6031 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006032}
6033
Guy Benyei11169dd2012-12-18 14:30:41 +00006034enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6035 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006036 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6037 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006038
6039 return CXAvailability_Available;
6040}
6041
6042static CXVersion convertVersion(VersionTuple In) {
6043 CXVersion Out = { -1, -1, -1 };
6044 if (In.empty())
6045 return Out;
6046
6047 Out.Major = In.getMajor();
6048
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006049 Optional<unsigned> Minor = In.getMinor();
6050 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006051 Out.Minor = *Minor;
6052 else
6053 return Out;
6054
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006055 Optional<unsigned> Subminor = In.getSubminor();
6056 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006057 Out.Subminor = *Subminor;
6058
6059 return Out;
6060}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006061
6062static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6063 int *always_deprecated,
6064 CXString *deprecated_message,
6065 int *always_unavailable,
6066 CXString *unavailable_message,
6067 CXPlatformAvailability *availability,
6068 int availability_size) {
6069 bool HadAvailAttr = false;
6070 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006071 for (auto A : D->attrs()) {
6072 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006073 HadAvailAttr = true;
6074 if (always_deprecated)
6075 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006076 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006077 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006078 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006079 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006080 continue;
6081 }
6082
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006083 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006084 HadAvailAttr = true;
6085 if (always_unavailable)
6086 *always_unavailable = 1;
6087 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006088 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006089 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6090 }
6091 continue;
6092 }
6093
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006094 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006095 HadAvailAttr = true;
6096 if (N < availability_size) {
6097 availability[N].Platform
6098 = cxstring::createDup(Avail->getPlatform()->getName());
6099 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6100 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6101 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6102 availability[N].Unavailable = Avail->getUnavailable();
6103 availability[N].Message = cxstring::createDup(Avail->getMessage());
6104 }
6105 ++N;
6106 }
6107 }
6108
6109 if (!HadAvailAttr)
6110 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6111 return getCursorPlatformAvailabilityForDecl(
6112 cast<Decl>(EnumConst->getDeclContext()),
6113 always_deprecated,
6114 deprecated_message,
6115 always_unavailable,
6116 unavailable_message,
6117 availability,
6118 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006119
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006120 return N;
6121}
6122
Guy Benyei11169dd2012-12-18 14:30:41 +00006123int clang_getCursorPlatformAvailability(CXCursor cursor,
6124 int *always_deprecated,
6125 CXString *deprecated_message,
6126 int *always_unavailable,
6127 CXString *unavailable_message,
6128 CXPlatformAvailability *availability,
6129 int availability_size) {
6130 if (always_deprecated)
6131 *always_deprecated = 0;
6132 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006133 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006134 if (always_unavailable)
6135 *always_unavailable = 0;
6136 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006137 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006138
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 if (!clang_isDeclaration(cursor.kind))
6140 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006141
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006142 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006143 if (!D)
6144 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006145
6146 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6147 deprecated_message,
6148 always_unavailable,
6149 unavailable_message,
6150 availability,
6151 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006152}
6153
6154void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6155 clang_disposeString(availability->Platform);
6156 clang_disposeString(availability->Message);
6157}
6158
6159CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6160 if (clang_isDeclaration(cursor.kind))
6161 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6162
6163 return CXLanguage_Invalid;
6164}
6165
6166 /// \brief If the given cursor is the "templated" declaration
6167 /// descibing a class or function template, return the class or
6168 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006169static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006170 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006171 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006172
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006173 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006174 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6175 return FunTmpl;
6176
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006177 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006178 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6179 return ClassTmpl;
6180
6181 return D;
6182}
6183
6184CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6185 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006186 if (const Decl *D = getCursorDecl(cursor)) {
6187 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006188 if (!DC)
6189 return clang_getNullCursor();
6190
6191 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6192 getCursorTU(cursor));
6193 }
6194 }
6195
6196 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006197 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006198 return MakeCXCursor(D, getCursorTU(cursor));
6199 }
6200
6201 return clang_getNullCursor();
6202}
6203
6204CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6205 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006206 if (const Decl *D = getCursorDecl(cursor)) {
6207 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006208 if (!DC)
6209 return clang_getNullCursor();
6210
6211 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6212 getCursorTU(cursor));
6213 }
6214 }
6215
6216 // FIXME: Note that we can't easily compute the lexical context of a
6217 // statement or expression, so we return nothing.
6218 return clang_getNullCursor();
6219}
6220
6221CXFile clang_getIncludedFile(CXCursor cursor) {
6222 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006223 return nullptr;
6224
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006225 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006226 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006227}
6228
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006229unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6230 if (C.kind != CXCursor_ObjCPropertyDecl)
6231 return CXObjCPropertyAttr_noattr;
6232
6233 unsigned Result = CXObjCPropertyAttr_noattr;
6234 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6235 ObjCPropertyDecl::PropertyAttributeKind Attr =
6236 PD->getPropertyAttributesAsWritten();
6237
6238#define SET_CXOBJCPROP_ATTR(A) \
6239 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6240 Result |= CXObjCPropertyAttr_##A
6241 SET_CXOBJCPROP_ATTR(readonly);
6242 SET_CXOBJCPROP_ATTR(getter);
6243 SET_CXOBJCPROP_ATTR(assign);
6244 SET_CXOBJCPROP_ATTR(readwrite);
6245 SET_CXOBJCPROP_ATTR(retain);
6246 SET_CXOBJCPROP_ATTR(copy);
6247 SET_CXOBJCPROP_ATTR(nonatomic);
6248 SET_CXOBJCPROP_ATTR(setter);
6249 SET_CXOBJCPROP_ATTR(atomic);
6250 SET_CXOBJCPROP_ATTR(weak);
6251 SET_CXOBJCPROP_ATTR(strong);
6252 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6253#undef SET_CXOBJCPROP_ATTR
6254
6255 return Result;
6256}
6257
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006258unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6259 if (!clang_isDeclaration(C.kind))
6260 return CXObjCDeclQualifier_None;
6261
6262 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6263 const Decl *D = getCursorDecl(C);
6264 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6265 QT = MD->getObjCDeclQualifier();
6266 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6267 QT = PD->getObjCDeclQualifier();
6268 if (QT == Decl::OBJC_TQ_None)
6269 return CXObjCDeclQualifier_None;
6270
6271 unsigned Result = CXObjCDeclQualifier_None;
6272 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6273 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6274 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6275 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6276 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6277 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6278
6279 return Result;
6280}
6281
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006282unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6283 if (!clang_isDeclaration(C.kind))
6284 return 0;
6285
6286 const Decl *D = getCursorDecl(C);
6287 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6288 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6289 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6290 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6291
6292 return 0;
6293}
6294
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006295unsigned clang_Cursor_isVariadic(CXCursor C) {
6296 if (!clang_isDeclaration(C.kind))
6297 return 0;
6298
6299 const Decl *D = getCursorDecl(C);
6300 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6301 return FD->isVariadic();
6302 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6303 return MD->isVariadic();
6304
6305 return 0;
6306}
6307
Guy Benyei11169dd2012-12-18 14:30:41 +00006308CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6309 if (!clang_isDeclaration(C.kind))
6310 return clang_getNullRange();
6311
6312 const Decl *D = getCursorDecl(C);
6313 ASTContext &Context = getCursorContext(C);
6314 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6315 if (!RC)
6316 return clang_getNullRange();
6317
6318 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6319}
6320
6321CXString clang_Cursor_getRawCommentText(CXCursor C) {
6322 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006323 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006324
6325 const Decl *D = getCursorDecl(C);
6326 ASTContext &Context = getCursorContext(C);
6327 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6328 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6329 StringRef();
6330
6331 // Don't duplicate the string because RawText points directly into source
6332 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006333 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006334}
6335
6336CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6337 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006338 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006339
6340 const Decl *D = getCursorDecl(C);
6341 const ASTContext &Context = getCursorContext(C);
6342 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6343
6344 if (RC) {
6345 StringRef BriefText = RC->getBriefText(Context);
6346
6347 // Don't duplicate the string because RawComment ensures that this memory
6348 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006349 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006350 }
6351
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006352 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006353}
6354
Guy Benyei11169dd2012-12-18 14:30:41 +00006355CXModule clang_Cursor_getModule(CXCursor C) {
6356 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006357 if (const ImportDecl *ImportD =
6358 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006359 return ImportD->getImportedModule();
6360 }
6361
Craig Topper69186e72014-06-08 08:38:04 +00006362 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006363}
6364
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006365CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6366 if (isNotUsableTU(TU)) {
6367 LOG_BAD_TU(TU);
6368 return nullptr;
6369 }
6370 if (!File)
6371 return nullptr;
6372 FileEntry *FE = static_cast<FileEntry *>(File);
6373
6374 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6375 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6376 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6377
6378 if (Module *Mod = Header.getModule()) {
6379 if (Header.getRole() != ModuleMap::ExcludedHeader)
6380 return Mod;
6381 }
6382 return nullptr;
6383}
6384
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006385CXFile clang_Module_getASTFile(CXModule CXMod) {
6386 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006387 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006388 Module *Mod = static_cast<Module*>(CXMod);
6389 return const_cast<FileEntry *>(Mod->getASTFile());
6390}
6391
Guy Benyei11169dd2012-12-18 14:30:41 +00006392CXModule clang_Module_getParent(CXModule CXMod) {
6393 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006394 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006395 Module *Mod = static_cast<Module*>(CXMod);
6396 return Mod->Parent;
6397}
6398
6399CXString clang_Module_getName(CXModule CXMod) {
6400 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006401 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006402 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006403 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006404}
6405
6406CXString clang_Module_getFullName(CXModule CXMod) {
6407 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006408 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006409 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006410 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006411}
6412
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006413int clang_Module_isSystem(CXModule CXMod) {
6414 if (!CXMod)
6415 return 0;
6416 Module *Mod = static_cast<Module*>(CXMod);
6417 return Mod->IsSystem;
6418}
6419
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006420unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6421 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006422 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006423 LOG_BAD_TU(TU);
6424 return 0;
6425 }
6426 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006427 return 0;
6428 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006429 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6430 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6431 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006432}
6433
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006434CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6435 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006436 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006437 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006438 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006439 }
6440 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006441 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006442 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006443 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006444
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006445 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6446 if (Index < TopHeaders.size())
6447 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006448
Craig Topper69186e72014-06-08 08:38:04 +00006449 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006450}
6451
6452} // end: extern "C"
6453
6454//===----------------------------------------------------------------------===//
6455// C++ AST instrospection.
6456//===----------------------------------------------------------------------===//
6457
6458extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006459unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6460 if (!clang_isDeclaration(C.kind))
6461 return 0;
6462
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006463 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006464 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006465 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006466 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6467}
6468
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006469unsigned clang_CXXMethod_isConst(CXCursor C) {
6470 if (!clang_isDeclaration(C.kind))
6471 return 0;
6472
6473 const Decl *D = cxcursor::getCursorDecl(C);
6474 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006475 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006476 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6477}
6478
Guy Benyei11169dd2012-12-18 14:30:41 +00006479unsigned clang_CXXMethod_isStatic(CXCursor C) {
6480 if (!clang_isDeclaration(C.kind))
6481 return 0;
6482
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006483 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006484 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006485 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006486 return (Method && Method->isStatic()) ? 1 : 0;
6487}
6488
6489unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6490 if (!clang_isDeclaration(C.kind))
6491 return 0;
6492
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006493 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006494 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006495 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006496 return (Method && Method->isVirtual()) ? 1 : 0;
6497}
6498} // end: extern "C"
6499
6500//===----------------------------------------------------------------------===//
6501// Attribute introspection.
6502//===----------------------------------------------------------------------===//
6503
6504extern "C" {
6505CXType clang_getIBOutletCollectionType(CXCursor C) {
6506 if (C.kind != CXCursor_IBOutletCollectionAttr)
6507 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6508
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006509 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006510 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6511
6512 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6513}
6514} // end: extern "C"
6515
6516//===----------------------------------------------------------------------===//
6517// Inspecting memory usage.
6518//===----------------------------------------------------------------------===//
6519
6520typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6521
6522static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6523 enum CXTUResourceUsageKind k,
6524 unsigned long amount) {
6525 CXTUResourceUsageEntry entry = { k, amount };
6526 entries.push_back(entry);
6527}
6528
6529extern "C" {
6530
6531const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6532 const char *str = "";
6533 switch (kind) {
6534 case CXTUResourceUsage_AST:
6535 str = "ASTContext: expressions, declarations, and types";
6536 break;
6537 case CXTUResourceUsage_Identifiers:
6538 str = "ASTContext: identifiers";
6539 break;
6540 case CXTUResourceUsage_Selectors:
6541 str = "ASTContext: selectors";
6542 break;
6543 case CXTUResourceUsage_GlobalCompletionResults:
6544 str = "Code completion: cached global results";
6545 break;
6546 case CXTUResourceUsage_SourceManagerContentCache:
6547 str = "SourceManager: content cache allocator";
6548 break;
6549 case CXTUResourceUsage_AST_SideTables:
6550 str = "ASTContext: side tables";
6551 break;
6552 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6553 str = "SourceManager: malloc'ed memory buffers";
6554 break;
6555 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6556 str = "SourceManager: mmap'ed memory buffers";
6557 break;
6558 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6559 str = "ExternalASTSource: malloc'ed memory buffers";
6560 break;
6561 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6562 str = "ExternalASTSource: mmap'ed memory buffers";
6563 break;
6564 case CXTUResourceUsage_Preprocessor:
6565 str = "Preprocessor: malloc'ed memory";
6566 break;
6567 case CXTUResourceUsage_PreprocessingRecord:
6568 str = "Preprocessor: PreprocessingRecord";
6569 break;
6570 case CXTUResourceUsage_SourceManager_DataStructures:
6571 str = "SourceManager: data structures and tables";
6572 break;
6573 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6574 str = "Preprocessor: header search tables";
6575 break;
6576 }
6577 return str;
6578}
6579
6580CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006581 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006582 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006583 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006584 return usage;
6585 }
6586
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006587 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006588 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006589 ASTContext &astContext = astUnit->getASTContext();
6590
6591 // How much memory is used by AST nodes and types?
6592 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6593 (unsigned long) astContext.getASTAllocatedMemory());
6594
6595 // How much memory is used by identifiers?
6596 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6597 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6598
6599 // How much memory is used for selectors?
6600 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6601 (unsigned long) astContext.Selectors.getTotalMemory());
6602
6603 // How much memory is used by ASTContext's side tables?
6604 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6605 (unsigned long) astContext.getSideTableAllocatedMemory());
6606
6607 // How much memory is used for caching global code completion results?
6608 unsigned long completionBytes = 0;
6609 if (GlobalCodeCompletionAllocator *completionAllocator =
6610 astUnit->getCachedCompletionAllocator().getPtr()) {
6611 completionBytes = completionAllocator->getTotalMemory();
6612 }
6613 createCXTUResourceUsageEntry(*entries,
6614 CXTUResourceUsage_GlobalCompletionResults,
6615 completionBytes);
6616
6617 // How much memory is being used by SourceManager's content cache?
6618 createCXTUResourceUsageEntry(*entries,
6619 CXTUResourceUsage_SourceManagerContentCache,
6620 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6621
6622 // How much memory is being used by the MemoryBuffer's in SourceManager?
6623 const SourceManager::MemoryBufferSizes &srcBufs =
6624 astUnit->getSourceManager().getMemoryBufferSizes();
6625
6626 createCXTUResourceUsageEntry(*entries,
6627 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6628 (unsigned long) srcBufs.malloc_bytes);
6629 createCXTUResourceUsageEntry(*entries,
6630 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6631 (unsigned long) srcBufs.mmap_bytes);
6632 createCXTUResourceUsageEntry(*entries,
6633 CXTUResourceUsage_SourceManager_DataStructures,
6634 (unsigned long) astContext.getSourceManager()
6635 .getDataStructureSizes());
6636
6637 // How much memory is being used by the ExternalASTSource?
6638 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6639 const ExternalASTSource::MemoryBufferSizes &sizes =
6640 esrc->getMemoryBufferSizes();
6641
6642 createCXTUResourceUsageEntry(*entries,
6643 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6644 (unsigned long) sizes.malloc_bytes);
6645 createCXTUResourceUsageEntry(*entries,
6646 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6647 (unsigned long) sizes.mmap_bytes);
6648 }
6649
6650 // How much memory is being used by the Preprocessor?
6651 Preprocessor &pp = astUnit->getPreprocessor();
6652 createCXTUResourceUsageEntry(*entries,
6653 CXTUResourceUsage_Preprocessor,
6654 pp.getTotalMemory());
6655
6656 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6657 createCXTUResourceUsageEntry(*entries,
6658 CXTUResourceUsage_PreprocessingRecord,
6659 pRec->getTotalMemory());
6660 }
6661
6662 createCXTUResourceUsageEntry(*entries,
6663 CXTUResourceUsage_Preprocessor_HeaderSearch,
6664 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006665
Guy Benyei11169dd2012-12-18 14:30:41 +00006666 CXTUResourceUsage usage = { (void*) entries.get(),
6667 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006668 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006669 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006670 return usage;
6671}
6672
6673void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6674 if (usage.data)
6675 delete (MemUsageEntries*) usage.data;
6676}
6677
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006678CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6679 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006680 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006681 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006682
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006683 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006684 LOG_BAD_TU(TU);
6685 return skipped;
6686 }
6687
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006688 if (!file)
6689 return skipped;
6690
6691 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6692 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6693 if (!ppRec)
6694 return skipped;
6695
6696 ASTContext &Ctx = astUnit->getASTContext();
6697 SourceManager &sm = Ctx.getSourceManager();
6698 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6699 FileID wantedFileID = sm.translateFile(fileEntry);
6700
6701 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6702 std::vector<SourceRange> wantedRanges;
6703 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6704 i != ei; ++i) {
6705 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6706 wantedRanges.push_back(*i);
6707 }
6708
6709 skipped->count = wantedRanges.size();
6710 skipped->ranges = new CXSourceRange[skipped->count];
6711 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6712 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6713
6714 return skipped;
6715}
6716
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006717void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6718 if (ranges) {
6719 delete[] ranges->ranges;
6720 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006721 }
6722}
6723
Guy Benyei11169dd2012-12-18 14:30:41 +00006724} // end extern "C"
6725
6726void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6727 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6728 for (unsigned I = 0; I != Usage.numEntries; ++I)
6729 fprintf(stderr, " %s: %lu\n",
6730 clang_getTUResourceUsageName(Usage.entries[I].kind),
6731 Usage.entries[I].amount);
6732
6733 clang_disposeCXTUResourceUsage(Usage);
6734}
6735
6736//===----------------------------------------------------------------------===//
6737// Misc. utility functions.
6738//===----------------------------------------------------------------------===//
6739
6740/// Default to using an 8 MB stack size on "safety" threads.
6741static unsigned SafetyStackThreadSize = 8 << 20;
6742
6743namespace clang {
6744
6745bool RunSafely(llvm::CrashRecoveryContext &CRC,
6746 void (*Fn)(void*), void *UserData,
6747 unsigned Size) {
6748 if (!Size)
6749 Size = GetSafetyThreadStackSize();
6750 if (Size)
6751 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6752 return CRC.RunSafely(Fn, UserData);
6753}
6754
6755unsigned GetSafetyThreadStackSize() {
6756 return SafetyStackThreadSize;
6757}
6758
6759void SetSafetyThreadStackSize(unsigned Value) {
6760 SafetyStackThreadSize = Value;
6761}
6762
6763}
6764
6765void clang::setThreadBackgroundPriority() {
6766 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6767 return;
6768
6769 // FIXME: Move to llvm/Support and make it cross-platform.
6770#ifdef __APPLE__
6771 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6772#endif
6773}
6774
6775void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6776 if (!Unit)
6777 return;
6778
6779 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6780 DEnd = Unit->stored_diag_end();
6781 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006782 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006783 CXString Msg = clang_formatDiagnostic(&Diag,
6784 clang_defaultDiagnosticDisplayOptions());
6785 fprintf(stderr, "%s\n", clang_getCString(Msg));
6786 clang_disposeString(Msg);
6787 }
6788#ifdef LLVM_ON_WIN32
6789 // On Windows, force a flush, since there may be multiple copies of
6790 // stderr and stdout in the file system, all with different buffers
6791 // but writing to the same device.
6792 fflush(stderr);
6793#endif
6794}
6795
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006796MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6797 SourceLocation MacroDefLoc,
6798 CXTranslationUnit TU){
6799 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006800 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006801 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006802 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006803
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006804 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006805 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006806 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006807 if (MD) {
6808 for (MacroDirective::DefInfo
6809 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6810 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6811 return Def.getMacroInfo();
6812 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006813 }
6814
Craig Topper69186e72014-06-08 08:38:04 +00006815 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006816}
6817
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006818const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6819 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006820 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006821 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006822 const IdentifierInfo *II = MacroDef->getName();
6823 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006824 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006825
6826 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6827}
6828
6829MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6830 const Token &Tok,
6831 CXTranslationUnit TU) {
6832 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006833 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006834 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006835 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006836
6837 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006838 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006839 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6840 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006841 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006842
6843 // Check that the token is inside the definition and not its argument list.
6844 SourceManager &SM = Unit->getSourceManager();
6845 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006846 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006847 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006848 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006849
6850 Preprocessor &PP = Unit->getPreprocessor();
6851 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6852 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006853 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006854
Alp Toker2d57cea2014-05-17 04:53:25 +00006855 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006856 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006857 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006858
6859 // Check that the identifier is not one of the macro arguments.
6860 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006861 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006862
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006863 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6864 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006865 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006866
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006867 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006868}
6869
6870MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6871 SourceLocation Loc,
6872 CXTranslationUnit TU) {
6873 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006874 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006875
6876 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006877 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006878 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006879 Preprocessor &PP = Unit->getPreprocessor();
6880 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006881 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006882 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6883 Token Tok;
6884 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006885 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006886
6887 return checkForMacroInMacroDefinition(MI, Tok, TU);
6888}
6889
Guy Benyei11169dd2012-12-18 14:30:41 +00006890extern "C" {
6891
6892CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006893 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006894}
6895
6896} // end: extern "C"
6897
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006898Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6899 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006900 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006901 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006902 if (Unit->isMainFileAST())
6903 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006904 return *this;
6905 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006906 } else {
6907 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006908 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006909 return *this;
6910}
6911
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006912Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6913 *this << FE->getName();
6914 return *this;
6915}
6916
6917Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6918 CXString cursorName = clang_getCursorDisplayName(cursor);
6919 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6920 clang_disposeString(cursorName);
6921 return *this;
6922}
6923
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006924Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6925 CXFile File;
6926 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006927 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006928 CXString FileName = clang_getFileName(File);
6929 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6930 clang_disposeString(FileName);
6931 return *this;
6932}
6933
6934Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6935 CXSourceLocation BLoc = clang_getRangeStart(range);
6936 CXSourceLocation ELoc = clang_getRangeEnd(range);
6937
6938 CXFile BFile;
6939 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006940 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006941
6942 CXFile EFile;
6943 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006944 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006945
6946 CXString BFileName = clang_getFileName(BFile);
6947 if (BFile == EFile) {
6948 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6949 BLine, BColumn, ELine, EColumn);
6950 } else {
6951 CXString EFileName = clang_getFileName(EFile);
6952 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6953 BLine, BColumn)
6954 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6955 ELine, EColumn);
6956 clang_disposeString(EFileName);
6957 }
6958 clang_disposeString(BFileName);
6959 return *this;
6960}
6961
6962Logger &cxindex::Logger::operator<<(CXString Str) {
6963 *this << clang_getCString(Str);
6964 return *this;
6965}
6966
6967Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6968 LogOS << Fmt;
6969 return *this;
6970}
6971
6972cxindex::Logger::~Logger() {
6973 LogOS.flush();
6974
Zachary Turnerf68823b2014-06-17 19:57:15 +00006975 llvm::sys::ScopedLock L(LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006976
6977 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6978
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006979 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006980 OS << "[libclang:" << Name << ':';
6981
6982 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00006983#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006984 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6985 OS << tid << ':';
6986#endif
6987
6988 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6989 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6990 OS << Msg.str() << '\n';
6991
6992 if (Trace) {
6993 llvm::sys::PrintStackTrace(stderr);
6994 OS << "--------------------------------------------------\n";
6995 }
6996}