blob: 45e578609599ac6df7d98f62b9dce580887e0c06 [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 Bataev236070f2014-06-20 11:19:47 +00001954void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1955
Alexey Bataev756c1962013-09-24 03:17:45 +00001956template<typename T>
1957void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001958 for (const auto *I : Node->varlists())
1959 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001960}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001961
1962void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001963 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001964}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001965void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1966 const OMPFirstprivateClause *C) {
1967 VisitOMPClauseList(C);
1968}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001969void OMPClauseEnqueue::VisitOMPLastprivateClause(
1970 const OMPLastprivateClause *C) {
1971 VisitOMPClauseList(C);
1972}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001973void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001974 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001975}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001976void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1977 VisitOMPClauseList(C);
1978}
Alexander Musman8dba6642014-04-22 13:09:42 +00001979void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1980 VisitOMPClauseList(C);
1981 Visitor->AddStmt(C->getStep());
1982}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001983void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1984 VisitOMPClauseList(C);
1985 Visitor->AddStmt(C->getAlignment());
1986}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001987void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1988 VisitOMPClauseList(C);
1989}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001990}
Alexey Bataev756c1962013-09-24 03:17:45 +00001991
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001992void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1993 unsigned size = WL.size();
1994 OMPClauseEnqueue Visitor(this);
1995 Visitor.Visit(S);
1996 if (size == WL.size())
1997 return;
1998 // Now reverse the entries we just added. This will match the DFS
1999 // ordering performed by the worklist.
2000 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2001 std::reverse(I, E);
2002}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002003void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002004 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2005}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002006void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002007 AddDecl(B->getBlockDecl());
2008}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002009void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002010 EnqueueChildren(E);
2011 AddTypeLoc(E->getTypeSourceInfo());
2012}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002013void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2014 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002015 E = S->body_rend(); I != E; ++I) {
2016 AddStmt(*I);
2017 }
2018}
2019void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002020VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002021 AddStmt(S->getSubStmt());
2022 AddDeclarationNameInfo(S);
2023 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2024 AddNestedNameSpecifierLoc(QualifierLoc);
2025}
2026
2027void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002028VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002029 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2030 AddDeclarationNameInfo(E);
2031 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2032 AddNestedNameSpecifierLoc(QualifierLoc);
2033 if (!E->isImplicitAccess())
2034 AddStmt(E->getBase());
2035}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002036void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002037 // Enqueue the initializer , if any.
2038 AddStmt(E->getInitializer());
2039 // Enqueue the array size, if any.
2040 AddStmt(E->getArraySize());
2041 // Enqueue the allocated type.
2042 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2043 // Enqueue the placement arguments.
2044 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2045 AddStmt(E->getPlacementArg(I-1));
2046}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002047void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002048 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2049 AddStmt(CE->getArg(I-1));
2050 AddStmt(CE->getCallee());
2051 AddStmt(CE->getArg(0));
2052}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2054 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 // Visit the name of the type being destroyed.
2056 AddTypeLoc(E->getDestroyedTypeInfo());
2057 // Visit the scope type that looks disturbingly like the nested-name-specifier
2058 // but isn't.
2059 AddTypeLoc(E->getScopeTypeInfo());
2060 // Visit the nested-name-specifier.
2061 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2062 AddNestedNameSpecifierLoc(QualifierLoc);
2063 // Visit base expression.
2064 AddStmt(E->getBase());
2065}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2067 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 AddTypeLoc(E->getTypeSourceInfo());
2069}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002070void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2071 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002072 EnqueueChildren(E);
2073 AddTypeLoc(E->getTypeSourceInfo());
2074}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002075void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002076 EnqueueChildren(E);
2077 if (E->isTypeOperand())
2078 AddTypeLoc(E->getTypeOperandSourceInfo());
2079}
2080
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2082 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 EnqueueChildren(E);
2084 AddTypeLoc(E->getTypeSourceInfo());
2085}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002086void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002087 EnqueueChildren(E);
2088 if (E->isTypeOperand())
2089 AddTypeLoc(E->getTypeOperandSourceInfo());
2090}
2091
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002093 EnqueueChildren(S);
2094 AddDecl(S->getExceptionDecl());
2095}
2096
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 if (DR->hasExplicitTemplateArgs()) {
2099 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2100 }
2101 WL.push_back(DeclRefExprParts(DR, Parent));
2102}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002103void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2104 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2106 AddDeclarationNameInfo(E);
2107 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2108}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002110 unsigned size = WL.size();
2111 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002112 for (const auto *D : S->decls()) {
2113 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002114 isFirst = false;
2115 }
2116 if (size == WL.size())
2117 return;
2118 // Now reverse the entries we just added. This will match the DFS
2119 // ordering performed by the worklist.
2120 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2121 std::reverse(I, E);
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 D = E->designators_rbegin(), DEnd = E->designators_rend();
2127 D != DEnd; ++D) {
2128 if (D->isFieldDesignator()) {
2129 if (FieldDecl *Field = D->getField())
2130 AddMemberRef(Field, D->getFieldLoc());
2131 continue;
2132 }
2133 if (D->isArrayDesignator()) {
2134 AddStmt(E->getArrayIndex(*D));
2135 continue;
2136 }
2137 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2138 AddStmt(E->getArrayRangeEnd(*D));
2139 AddStmt(E->getArrayRangeStart(*D));
2140 }
2141}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 EnqueueChildren(E);
2144 AddTypeLoc(E->getTypeInfoAsWritten());
2145}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 AddStmt(FS->getBody());
2148 AddStmt(FS->getInc());
2149 AddStmt(FS->getCond());
2150 AddDecl(FS->getConditionVariable());
2151 AddStmt(FS->getInit());
2152}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2155}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002157 AddStmt(If->getElse());
2158 AddStmt(If->getThen());
2159 AddStmt(If->getCond());
2160 AddDecl(If->getConditionVariable());
2161}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002162void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002163 // We care about the syntactic form of the initializer list, only.
2164 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2165 IE = Syntactic;
2166 EnqueueChildren(IE);
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 WL.push_back(MemberExprParts(M, Parent));
2170
2171 // If the base of the member access expression is an implicit 'this', don't
2172 // visit it.
2173 // FIXME: If we ever want to show these implicit accesses, this will be
2174 // unfortunate. However, clang_getCursor() relies on this behavior.
2175 if (!M->isImplicitAccess())
2176 AddStmt(M->getBase());
2177}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 AddTypeLoc(E->getEncodedTypeSourceInfo());
2180}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 EnqueueChildren(M);
2183 AddTypeLoc(M->getClassReceiverTypeInfo());
2184}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 // Visit the components of the offsetof expression.
2187 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2188 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2189 const OffsetOfNode &Node = E->getComponent(I-1);
2190 switch (Node.getKind()) {
2191 case OffsetOfNode::Array:
2192 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2193 break;
2194 case OffsetOfNode::Field:
2195 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2196 break;
2197 case OffsetOfNode::Identifier:
2198 case OffsetOfNode::Base:
2199 continue;
2200 }
2201 }
2202 // Visit the type into which we're computing the offset.
2203 AddTypeLoc(E->getTypeSourceInfo());
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2207 WL.push_back(OverloadExprParts(E, Parent));
2208}
2209void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002210 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002211 EnqueueChildren(E);
2212 if (E->isArgumentType())
2213 AddTypeLoc(E->getArgumentTypeInfo());
2214}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 EnqueueChildren(S);
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 AddStmt(S->getBody());
2220 AddStmt(S->getCond());
2221 AddDecl(S->getConditionVariable());
2222}
2223
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 AddStmt(W->getBody());
2226 AddStmt(W->getCond());
2227 AddDecl(W->getConditionVariable());
2228}
2229
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 for (unsigned I = E->getNumArgs(); I > 0; --I)
2232 AddTypeLoc(E->getArg(I-1));
2233}
2234
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 AddTypeLoc(E->getQueriedTypeSourceInfo());
2237}
2238
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 EnqueueChildren(E);
2241}
2242
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002243void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002244 VisitOverloadExpr(U);
2245 if (!U->isImplicitAccess())
2246 AddStmt(U->getBase());
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 AddStmt(E->getSubExpr());
2250 AddTypeLoc(E->getWrittenTypeInfo());
2251}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 WL.push_back(SizeOfPackExprParts(E, Parent));
2254}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 // If the opaque value has a source expression, just transparently
2257 // visit that. This is useful for (e.g.) pseudo-object expressions.
2258 if (Expr *SourceExpr = E->getSourceExpr())
2259 return Visit(SourceExpr);
2260}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 AddStmt(E->getBody());
2263 WL.push_back(LambdaExprParts(E, Parent));
2264}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 // Treat the expression like its syntactic form.
2267 Visit(E->getSyntacticForm());
2268}
2269
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002270void EnqueueVisitor::VisitOMPExecutableDirective(
2271 const OMPExecutableDirective *D) {
2272 EnqueueChildren(D);
2273 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2274 E = D->clauses().end();
2275 I != E; ++I)
2276 EnqueueChildren(*I);
2277}
2278
2279void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2280 VisitOMPExecutableDirective(D);
2281}
2282
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002283void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2284 VisitOMPExecutableDirective(D);
2285}
2286
Alexey Bataevf29276e2014-06-18 04:14:57 +00002287void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2288 VisitOMPExecutableDirective(D);
2289}
2290
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2293}
2294
2295bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2296 if (RegionOfInterest.isValid()) {
2297 SourceRange Range = getRawCursorExtent(C);
2298 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2299 return false;
2300 }
2301 return true;
2302}
2303
2304bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2305 while (!WL.empty()) {
2306 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002307 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002308
2309 // Set the Parent field, then back to its old value once we're done.
2310 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2311
2312 switch (LI.getKind()) {
2313 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 if (!D)
2316 continue;
2317
2318 // For now, perform default visitation for Decls.
2319 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2320 cast<DeclVisit>(&LI)->isFirst())))
2321 return true;
2322
2323 continue;
2324 }
2325 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2326 const ASTTemplateArgumentListInfo *ArgList =
2327 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2328 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2329 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2330 Arg != ArgEnd; ++Arg) {
2331 if (VisitTemplateArgumentLoc(*Arg))
2332 return true;
2333 }
2334 continue;
2335 }
2336 case VisitorJob::TypeLocVisitKind: {
2337 // Perform default visitation for TypeLocs.
2338 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2339 return true;
2340 continue;
2341 }
2342 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002343 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002344 if (LabelStmt *stmt = LS->getStmt()) {
2345 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2346 TU))) {
2347 return true;
2348 }
2349 }
2350 continue;
2351 }
2352
2353 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2354 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2355 if (VisitNestedNameSpecifierLoc(V->get()))
2356 return true;
2357 continue;
2358 }
2359
2360 case VisitorJob::DeclarationNameInfoVisitKind: {
2361 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2362 ->get()))
2363 return true;
2364 continue;
2365 }
2366 case VisitorJob::MemberRefVisitKind: {
2367 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2368 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2369 return true;
2370 continue;
2371 }
2372 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002373 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002374 if (!S)
2375 continue;
2376
2377 // Update the current cursor.
2378 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2379 if (!IsInRegionOfInterest(Cursor))
2380 continue;
2381 switch (Visitor(Cursor, Parent, ClientData)) {
2382 case CXChildVisit_Break: return true;
2383 case CXChildVisit_Continue: break;
2384 case CXChildVisit_Recurse:
2385 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002386 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002387 EnqueueWorkList(WL, S);
2388 break;
2389 }
2390 continue;
2391 }
2392 case VisitorJob::MemberExprPartsKind: {
2393 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002395
2396 // Visit the nested-name-specifier
2397 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2398 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2399 return true;
2400
2401 // Visit the declaration name.
2402 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2403 return true;
2404
2405 // Visit the explicitly-specified template arguments, if any.
2406 if (M->hasExplicitTemplateArgs()) {
2407 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2408 *ArgEnd = Arg + M->getNumTemplateArgs();
2409 Arg != ArgEnd; ++Arg) {
2410 if (VisitTemplateArgumentLoc(*Arg))
2411 return true;
2412 }
2413 }
2414 continue;
2415 }
2416 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002417 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002418 // Visit nested-name-specifier, if present.
2419 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2420 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2421 return true;
2422 // Visit declaration name.
2423 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2424 return true;
2425 continue;
2426 }
2427 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002428 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002429 // Visit the nested-name-specifier.
2430 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2431 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2432 return true;
2433 // Visit the declaration name.
2434 if (VisitDeclarationNameInfo(O->getNameInfo()))
2435 return true;
2436 // Visit the overloaded declaration reference.
2437 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2438 return true;
2439 continue;
2440 }
2441 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002442 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002443 NamedDecl *Pack = E->getPack();
2444 if (isa<TemplateTypeParmDecl>(Pack)) {
2445 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2446 E->getPackLoc(), TU)))
2447 return true;
2448
2449 continue;
2450 }
2451
2452 if (isa<TemplateTemplateParmDecl>(Pack)) {
2453 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2454 E->getPackLoc(), TU)))
2455 return true;
2456
2457 continue;
2458 }
2459
2460 // Non-type template parameter packs and function parameter packs are
2461 // treated like DeclRefExpr cursors.
2462 continue;
2463 }
2464
2465 case VisitorJob::LambdaExprPartsKind: {
2466 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002467 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002468 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2469 CEnd = E->explicit_capture_end();
2470 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002471 // FIXME: Lambda init-captures.
2472 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002473 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002474
Guy Benyei11169dd2012-12-18 14:30:41 +00002475 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2476 C->getLocation(),
2477 TU)))
2478 return true;
2479 }
2480
2481 // Visit parameters and return type, if present.
2482 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2483 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2484 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2485 // Visit the whole type.
2486 if (Visit(TL))
2487 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002488 } else if (FunctionProtoTypeLoc Proto =
2489 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002490 if (E->hasExplicitParameters()) {
2491 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002492 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2493 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002494 return true;
2495 } else {
2496 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002497 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002498 return true;
2499 }
2500 }
2501 }
2502 break;
2503 }
2504
2505 case VisitorJob::PostChildrenVisitKind:
2506 if (PostChildrenVisitor(Parent, ClientData))
2507 return true;
2508 break;
2509 }
2510 }
2511 return false;
2512}
2513
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002514bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002515 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002516 if (!WorkListFreeList.empty()) {
2517 WL = WorkListFreeList.back();
2518 WL->clear();
2519 WorkListFreeList.pop_back();
2520 }
2521 else {
2522 WL = new VisitorWorkList();
2523 WorkListCache.push_back(WL);
2524 }
2525 EnqueueWorkList(*WL, S);
2526 bool result = RunVisitorWorkList(*WL);
2527 WorkListFreeList.push_back(WL);
2528 return result;
2529}
2530
2531namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002532typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002533RefNamePieces
2534buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2535 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2536 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002537 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2538 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2539 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2540
2541 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2542
2543 RefNamePieces Pieces;
2544
2545 if (WantQualifier && QLoc.isValid())
2546 Pieces.push_back(QLoc);
2547
2548 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2549 Pieces.push_back(NI.getLoc());
2550
2551 if (WantTemplateArgs && TemplateArgs)
2552 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2553 TemplateArgs->RAngleLoc));
2554
2555 if (Kind == DeclarationName::CXXOperatorName) {
2556 Pieces.push_back(SourceLocation::getFromRawEncoding(
2557 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2558 Pieces.push_back(SourceLocation::getFromRawEncoding(
2559 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2560 }
2561
2562 if (WantSinglePiece) {
2563 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2564 Pieces.clear();
2565 Pieces.push_back(R);
2566 }
2567
2568 return Pieces;
2569}
2570}
2571
2572//===----------------------------------------------------------------------===//
2573// Misc. API hooks.
2574//===----------------------------------------------------------------------===//
2575
Zachary Turnerf68823b2014-06-17 19:57:15 +00002576static llvm::sys::Mutex LoggingMutex;
2577static std::once_flag LibclangGlobalInitFlag;
Guy Benyei11169dd2012-12-18 14:30:41 +00002578
Chad Rosier05c71aa2013-03-27 18:28:23 +00002579static void fatal_error_handler(void *user_data, const std::string& reason,
2580 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002581 // Write the result out to stderr avoiding errs() because raw_ostreams can
2582 // call report_fatal_error.
2583 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2584 ::abort();
2585}
2586
Zachary Turnerf68823b2014-06-17 19:57:15 +00002587static void initializeLibClang() {
Zachary Turnerf68823b2014-06-17 19:57:15 +00002588 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2589}
2590
Guy Benyei11169dd2012-12-18 14:30:41 +00002591extern "C" {
2592CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2593 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002594 // We use crash recovery to make some of our APIs more reliable, implicitly
2595 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002596 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2597 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002598
Zachary Turnerf68823b2014-06-17 19:57:15 +00002599 std::call_once(LibclangGlobalInitFlag, initializeLibClang);
Guy Benyei11169dd2012-12-18 14:30:41 +00002600
2601 CIndexer *CIdxr = new CIndexer();
2602 if (excludeDeclarationsFromPCH)
2603 CIdxr->setOnlyLocalDecls();
2604 if (displayDiagnostics)
2605 CIdxr->setDisplayDiagnostics();
2606
2607 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2608 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2609 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2610 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2611 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2612 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2613
2614 return CIdxr;
2615}
2616
2617void clang_disposeIndex(CXIndex CIdx) {
2618 if (CIdx)
2619 delete static_cast<CIndexer *>(CIdx);
2620}
2621
2622void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2623 if (CIdx)
2624 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2625}
2626
2627unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2628 if (CIdx)
2629 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2630 return 0;
2631}
2632
2633void clang_toggleCrashRecovery(unsigned isEnabled) {
2634 if (isEnabled)
2635 llvm::CrashRecoveryContext::Enable();
2636 else
2637 llvm::CrashRecoveryContext::Disable();
2638}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002639
Guy Benyei11169dd2012-12-18 14:30:41 +00002640CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2641 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002642 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002643 enum CXErrorCode Result =
2644 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002645 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002646 assert((TU && Result == CXError_Success) ||
2647 (!TU && Result != CXError_Success));
2648 return TU;
2649}
2650
2651enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2652 const char *ast_filename,
2653 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002654 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002655 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002656
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002657 if (!CIdx || !ast_filename || !out_TU)
2658 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002659
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002660 LOG_FUNC_SECTION {
2661 *Log << ast_filename;
2662 }
2663
Guy Benyei11169dd2012-12-18 14:30:41 +00002664 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2665 FileSystemOptions FileSystemOpts;
2666
2667 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002668 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002669 CXXIdx->getOnlyLocalDecls(), None,
2670 /*CaptureDiagnostics=*/true,
2671 /*AllowPCHWithCompilerErrors=*/true,
2672 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002673 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2674 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002675}
2676
2677unsigned clang_defaultEditingTranslationUnitOptions() {
2678 return CXTranslationUnit_PrecompiledPreamble |
2679 CXTranslationUnit_CacheCompletionResults;
2680}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002681
Guy Benyei11169dd2012-12-18 14:30:41 +00002682CXTranslationUnit
2683clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2684 const char *source_filename,
2685 int num_command_line_args,
2686 const char * const *command_line_args,
2687 unsigned num_unsaved_files,
2688 struct CXUnsavedFile *unsaved_files) {
2689 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2690 return clang_parseTranslationUnit(CIdx, source_filename,
2691 command_line_args, num_command_line_args,
2692 unsaved_files, num_unsaved_files,
2693 Options);
2694}
2695
2696struct ParseTranslationUnitInfo {
2697 CXIndex CIdx;
2698 const char *source_filename;
2699 const char *const *command_line_args;
2700 int num_command_line_args;
2701 struct CXUnsavedFile *unsaved_files;
2702 unsigned num_unsaved_files;
2703 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002704 CXTranslationUnit *out_TU;
2705 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002706};
2707static void clang_parseTranslationUnit_Impl(void *UserData) {
2708 ParseTranslationUnitInfo *PTUI =
2709 static_cast<ParseTranslationUnitInfo*>(UserData);
2710 CXIndex CIdx = PTUI->CIdx;
2711 const char *source_filename = PTUI->source_filename;
2712 const char * const *command_line_args = PTUI->command_line_args;
2713 int num_command_line_args = PTUI->num_command_line_args;
2714 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2715 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2716 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002717 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002718
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002719 // Set up the initial return values.
2720 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002721 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002722 PTUI->result = CXError_Failure;
2723
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002724 // Check arguments.
2725 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002726 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002727 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002728 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002729 }
2730
Guy Benyei11169dd2012-12-18 14:30:41 +00002731 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2732
2733 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2734 setThreadBackgroundPriority();
2735
2736 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2737 // FIXME: Add a flag for modules.
2738 TranslationUnitKind TUKind
2739 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002740 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002741 = options & CXTranslationUnit_CacheCompletionResults;
2742 bool IncludeBriefCommentsInCodeCompletion
2743 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2744 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2745 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2746
2747 // Configure the diagnostics.
2748 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002749 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002750
2751 // Recover resources if we crash before exiting this function.
2752 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2753 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2754 DiagCleanup(Diags.getPtr());
2755
Ahmed Charlesb8984322014-03-07 20:03:18 +00002756 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2757 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002758
2759 // Recover resources if we crash before exiting this function.
2760 llvm::CrashRecoveryContextCleanupRegistrar<
2761 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2762
2763 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2764 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2765 const llvm::MemoryBuffer *Buffer
2766 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2767 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2768 Buffer));
2769 }
2770
Ahmed Charlesb8984322014-03-07 20:03:18 +00002771 std::unique_ptr<std::vector<const char *>> Args(
2772 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002773
2774 // Recover resources if we crash before exiting this method.
2775 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2776 ArgsCleanup(Args.get());
2777
2778 // Since the Clang C library is primarily used by batch tools dealing with
2779 // (often very broken) source code, where spell-checking can have a
2780 // significant negative impact on performance (particularly when
2781 // precompiled headers are involved), we disable it by default.
2782 // Only do this if we haven't found a spell-checking-related argument.
2783 bool FoundSpellCheckingArgument = false;
2784 for (int I = 0; I != num_command_line_args; ++I) {
2785 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2786 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2787 FoundSpellCheckingArgument = true;
2788 break;
2789 }
2790 }
2791 if (!FoundSpellCheckingArgument)
2792 Args->push_back("-fno-spell-checking");
2793
2794 Args->insert(Args->end(), command_line_args,
2795 command_line_args + num_command_line_args);
2796
2797 // The 'source_filename' argument is optional. If the caller does not
2798 // specify it then it is assumed that the source file is specified
2799 // in the actual argument list.
2800 // Put the source file after command_line_args otherwise if '-x' flag is
2801 // present it will be unused.
2802 if (source_filename)
2803 Args->push_back(source_filename);
2804
2805 // Do we need the detailed preprocessing record?
2806 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2807 Args->push_back("-Xclang");
2808 Args->push_back("-detailed-preprocessing-record");
2809 }
2810
2811 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002812 std::unique_ptr<ASTUnit> ErrUnit;
2813 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002814 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002815 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2816 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2817 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2818 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2819 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2820 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002821
2822 if (NumErrors != Diags->getClient()->getNumErrors()) {
2823 // Make sure to check that 'Unit' is non-NULL.
2824 if (CXXIdx->getDisplayDiagnostics())
2825 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2826 }
2827
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002828 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2829 PTUI->result = CXError_ASTReadError;
2830 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002831 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002832 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2833 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002834}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002835
2836CXTranslationUnit
2837clang_parseTranslationUnit(CXIndex CIdx,
2838 const char *source_filename,
2839 const char *const *command_line_args,
2840 int num_command_line_args,
2841 struct CXUnsavedFile *unsaved_files,
2842 unsigned num_unsaved_files,
2843 unsigned options) {
2844 CXTranslationUnit TU;
2845 enum CXErrorCode Result = clang_parseTranslationUnit2(
2846 CIdx, source_filename, command_line_args, num_command_line_args,
2847 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002848 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002849 assert((TU && Result == CXError_Success) ||
2850 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002851 return TU;
2852}
2853
2854enum CXErrorCode clang_parseTranslationUnit2(
2855 CXIndex CIdx,
2856 const char *source_filename,
2857 const char *const *command_line_args,
2858 int num_command_line_args,
2859 struct CXUnsavedFile *unsaved_files,
2860 unsigned num_unsaved_files,
2861 unsigned options,
2862 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002863 LOG_FUNC_SECTION {
2864 *Log << source_filename << ": ";
2865 for (int i = 0; i != num_command_line_args; ++i)
2866 *Log << command_line_args[i] << " ";
2867 }
2868
Guy Benyei11169dd2012-12-18 14:30:41 +00002869 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2870 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002871 num_unsaved_files, options, out_TU,
2872 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002873 llvm::CrashRecoveryContext CRC;
2874
2875 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2876 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2877 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2878 fprintf(stderr, " 'command_line_args' : [");
2879 for (int i = 0; i != num_command_line_args; ++i) {
2880 if (i)
2881 fprintf(stderr, ", ");
2882 fprintf(stderr, "'%s'", command_line_args[i]);
2883 }
2884 fprintf(stderr, "],\n");
2885 fprintf(stderr, " 'unsaved_files' : [");
2886 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2887 if (i)
2888 fprintf(stderr, ", ");
2889 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2890 unsaved_files[i].Length);
2891 }
2892 fprintf(stderr, "],\n");
2893 fprintf(stderr, " 'options' : %d,\n", options);
2894 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002895
2896 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002897 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002898 if (CXTranslationUnit *TU = PTUI.out_TU)
2899 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002900 }
2901
2902 return PTUI.result;
2903}
2904
2905unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2906 return CXSaveTranslationUnit_None;
2907}
2908
2909namespace {
2910
2911struct SaveTranslationUnitInfo {
2912 CXTranslationUnit TU;
2913 const char *FileName;
2914 unsigned options;
2915 CXSaveError result;
2916};
2917
2918}
2919
2920static void clang_saveTranslationUnit_Impl(void *UserData) {
2921 SaveTranslationUnitInfo *STUI =
2922 static_cast<SaveTranslationUnitInfo*>(UserData);
2923
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002924 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002925 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2926 setThreadBackgroundPriority();
2927
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002928 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002929 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2930}
2931
2932int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2933 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002934 LOG_FUNC_SECTION {
2935 *Log << TU << ' ' << FileName;
2936 }
2937
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002938 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002939 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002940 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002941 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002942
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002943 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002944 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2945 if (!CXXUnit->hasSema())
2946 return CXSaveError_InvalidTU;
2947
2948 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2949
2950 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2951 getenv("LIBCLANG_NOTHREADS")) {
2952 clang_saveTranslationUnit_Impl(&STUI);
2953
2954 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2955 PrintLibclangResourceUsage(TU);
2956
2957 return STUI.result;
2958 }
2959
2960 // We have an AST that has invalid nodes due to compiler errors.
2961 // Use a crash recovery thread for protection.
2962
2963 llvm::CrashRecoveryContext CRC;
2964
2965 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2966 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2967 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2968 fprintf(stderr, " 'options' : %d,\n", options);
2969 fprintf(stderr, "}\n");
2970
2971 return CXSaveError_Unknown;
2972
2973 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2974 PrintLibclangResourceUsage(TU);
2975 }
2976
2977 return STUI.result;
2978}
2979
2980void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2981 if (CTUnit) {
2982 // If the translation unit has been marked as unsafe to free, just discard
2983 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002984 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2985 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002986 return;
2987
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002988 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002989 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002990 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2991 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002992 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002993 delete CTUnit;
2994 }
2995}
2996
2997unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2998 return CXReparse_None;
2999}
3000
3001struct ReparseTranslationUnitInfo {
3002 CXTranslationUnit TU;
3003 unsigned num_unsaved_files;
3004 struct CXUnsavedFile *unsaved_files;
3005 unsigned options;
3006 int result;
3007};
3008
3009static void clang_reparseTranslationUnit_Impl(void *UserData) {
3010 ReparseTranslationUnitInfo *RTUI =
3011 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003012 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003013
Guy Benyei11169dd2012-12-18 14:30:41 +00003014 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003015 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3016 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3017 unsigned options = RTUI->options;
3018 (void) options;
3019
3020 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003021 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003022 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003023 RTUI->result = CXError_InvalidArguments;
3024 return;
3025 }
Craig Topper69186e72014-06-08 08:38:04 +00003026 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003027 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003028 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003029 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003030
3031 // Reset the associated diagnostics.
3032 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003033 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003034
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003035 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003036 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3037 setThreadBackgroundPriority();
3038
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003039 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003040 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003041
3042 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3043 new std::vector<ASTUnit::RemappedFile>());
3044
Guy Benyei11169dd2012-12-18 14:30:41 +00003045 // Recover resources if we crash before exiting this function.
3046 llvm::CrashRecoveryContextCleanupRegistrar<
3047 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3048
3049 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3050 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3051 const llvm::MemoryBuffer *Buffer
3052 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3053 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3054 Buffer));
3055 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003056
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003057 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003058 RTUI->result = CXError_Success;
3059 else if (isASTReadError(CXXUnit))
3060 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003061}
3062
3063int clang_reparseTranslationUnit(CXTranslationUnit TU,
3064 unsigned num_unsaved_files,
3065 struct CXUnsavedFile *unsaved_files,
3066 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003067 LOG_FUNC_SECTION {
3068 *Log << TU;
3069 }
3070
Guy Benyei11169dd2012-12-18 14:30:41 +00003071 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003072 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003073
3074 if (getenv("LIBCLANG_NOTHREADS")) {
3075 clang_reparseTranslationUnit_Impl(&RTUI);
3076 return RTUI.result;
3077 }
3078
3079 llvm::CrashRecoveryContext CRC;
3080
3081 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3082 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003083 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003084 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003085 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3086 PrintLibclangResourceUsage(TU);
3087
3088 return RTUI.result;
3089}
3090
3091
3092CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003093 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003094 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003095 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003096 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003097
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003098 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003099 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003100}
3101
3102CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003103 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003104 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003105 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003106 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003107
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003108 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003109 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3110}
3111
3112} // end: extern "C"
3113
3114//===----------------------------------------------------------------------===//
3115// CXFile Operations.
3116//===----------------------------------------------------------------------===//
3117
3118extern "C" {
3119CXString clang_getFileName(CXFile SFile) {
3120 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003121 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003122
3123 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003124 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003125}
3126
3127time_t clang_getFileTime(CXFile SFile) {
3128 if (!SFile)
3129 return 0;
3130
3131 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3132 return FEnt->getModificationTime();
3133}
3134
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003135CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003136 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003137 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003138 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003139 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003140
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003141 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003142
3143 FileManager &FMgr = CXXUnit->getFileManager();
3144 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3145}
3146
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003147unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3148 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003149 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003150 LOG_BAD_TU(TU);
3151 return 0;
3152 }
3153
3154 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003155 return 0;
3156
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003157 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 FileEntry *FEnt = static_cast<FileEntry *>(file);
3159 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3160 .isFileMultipleIncludeGuarded(FEnt);
3161}
3162
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003163int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3164 if (!file || !outID)
3165 return 1;
3166
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003167 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003168 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3169 outID->data[0] = ID.getDevice();
3170 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003171 outID->data[2] = FEnt->getModificationTime();
3172 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003173}
3174
Guy Benyei11169dd2012-12-18 14:30:41 +00003175} // end: extern "C"
3176
3177//===----------------------------------------------------------------------===//
3178// CXCursor Operations.
3179//===----------------------------------------------------------------------===//
3180
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003181static const Decl *getDeclFromExpr(const Stmt *E) {
3182 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 return getDeclFromExpr(CE->getSubExpr());
3184
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003187 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 if (PRE->isExplicitProperty())
3193 return PRE->getExplicitProperty();
3194 // It could be messaging both getter and setter as in:
3195 // ++myobj.myprop;
3196 // in which case prefer to associate the setter since it is less obvious
3197 // from inspecting the source that the setter is going to get called.
3198 if (PRE->isMessagingSetter())
3199 return PRE->getImplicitPropertySetter();
3200 return PRE->getImplicitPropertyGetter();
3201 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003202 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003204 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 if (Expr *Src = OVE->getSourceExpr())
3206 return getDeclFromExpr(Src);
3207
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003208 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003210 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 if (!CE->isElidable())
3212 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003213 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 return OME->getMethodDecl();
3215
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003216 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003218 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3220 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003221 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003222 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3223 isa<ParmVarDecl>(SizeOfPack->getPack()))
3224 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003225
3226 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003227}
3228
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003229static SourceLocation getLocationFromExpr(const Expr *E) {
3230 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003231 return getLocationFromExpr(CE->getSubExpr());
3232
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003233 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003235 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003237 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003239 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003241 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003242 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003243 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003244 return PropRef->getLocation();
3245
3246 return E->getLocStart();
3247}
3248
3249extern "C" {
3250
3251unsigned clang_visitChildren(CXCursor parent,
3252 CXCursorVisitor visitor,
3253 CXClientData client_data) {
3254 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3255 /*VisitPreprocessorLast=*/false);
3256 return CursorVis.VisitChildren(parent);
3257}
3258
3259#ifndef __has_feature
3260#define __has_feature(x) 0
3261#endif
3262#if __has_feature(blocks)
3263typedef enum CXChildVisitResult
3264 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3265
3266static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3267 CXClientData client_data) {
3268 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3269 return block(cursor, parent);
3270}
3271#else
3272// If we are compiled with a compiler that doesn't have native blocks support,
3273// define and call the block manually, so the
3274typedef struct _CXChildVisitResult
3275{
3276 void *isa;
3277 int flags;
3278 int reserved;
3279 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3280 CXCursor);
3281} *CXCursorVisitorBlock;
3282
3283static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3284 CXClientData client_data) {
3285 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3286 return block->invoke(block, cursor, parent);
3287}
3288#endif
3289
3290
3291unsigned clang_visitChildrenWithBlock(CXCursor parent,
3292 CXCursorVisitorBlock block) {
3293 return clang_visitChildren(parent, visitWithBlock, block);
3294}
3295
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003296static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003298 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003299
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003300 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003302 if (const ObjCPropertyImplDecl *PropImpl =
3303 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003305 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003306
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003307 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003309 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003310
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003311 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003312 }
3313
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003314 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003315 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003316
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003317 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3319 // and returns different names. NamedDecl returns the class name and
3320 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003321 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003322
3323 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003324 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003325
3326 SmallString<1024> S;
3327 llvm::raw_svector_ostream os(S);
3328 ND->printName(os);
3329
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003330 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003331}
3332
3333CXString clang_getCursorSpelling(CXCursor C) {
3334 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003335 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003336
3337 if (clang_isReference(C.kind)) {
3338 switch (C.kind) {
3339 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003340 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003341 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 }
3343 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003344 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003345 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 }
3347 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003348 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003350 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 }
3352 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003353 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003354 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 }
3356 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003357 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 assert(Type && "Missing type decl");
3359
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003360 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 getAsString());
3362 }
3363 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003364 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 assert(Template && "Missing template decl");
3366
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003367 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 }
3369
3370 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003371 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 assert(NS && "Missing namespace decl");
3373
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003374 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 }
3376
3377 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003378 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 assert(Field && "Missing member decl");
3380
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003381 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 }
3383
3384 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003385 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 assert(Label && "Missing label");
3387
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003388 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 }
3390
3391 case CXCursor_OverloadedDeclRef: {
3392 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003393 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3394 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003395 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003396 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003398 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003399 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 OverloadedTemplateStorage *Ovl
3401 = Storage.get<OverloadedTemplateStorage*>();
3402 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003403 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003404 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 }
3406
3407 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003408 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003409 assert(Var && "Missing variable decl");
3410
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003411 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 }
3413
3414 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003415 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 }
3417 }
3418
3419 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003420 const Expr *E = getCursorExpr(C);
3421
3422 if (C.kind == CXCursor_ObjCStringLiteral ||
3423 C.kind == CXCursor_StringLiteral) {
3424 const StringLiteral *SLit;
3425 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3426 SLit = OSL->getString();
3427 } else {
3428 SLit = cast<StringLiteral>(E);
3429 }
3430 SmallString<256> Buf;
3431 llvm::raw_svector_ostream OS(Buf);
3432 SLit->outputString(OS);
3433 return cxstring::createDup(OS.str());
3434 }
3435
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003436 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 if (D)
3438 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003439 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 }
3441
3442 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003443 const Stmt *S = getCursorStmt(C);
3444 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003445 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003446
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003447 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 }
3449
3450 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003451 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 ->getNameStart());
3453
3454 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003455 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 ->getNameStart());
3457
3458 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003459 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003460
3461 if (clang_isDeclaration(C.kind))
3462 return getDeclSpelling(getCursorDecl(C));
3463
3464 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003465 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003466 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003467 }
3468
3469 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003470 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003471 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 }
3473
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003474 if (C.kind == CXCursor_PackedAttr) {
3475 return cxstring::createRef("packed");
3476 }
3477
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003478 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003479}
3480
3481CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3482 unsigned pieceIndex,
3483 unsigned options) {
3484 if (clang_Cursor_isNull(C))
3485 return clang_getNullRange();
3486
3487 ASTContext &Ctx = getCursorContext(C);
3488
3489 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003490 const Stmt *S = getCursorStmt(C);
3491 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 if (pieceIndex > 0)
3493 return clang_getNullRange();
3494 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3495 }
3496
3497 return clang_getNullRange();
3498 }
3499
3500 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003501 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3503 if (pieceIndex >= ME->getNumSelectorLocs())
3504 return clang_getNullRange();
3505 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3506 }
3507 }
3508
3509 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3510 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003511 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3513 if (pieceIndex >= MD->getNumSelectorLocs())
3514 return clang_getNullRange();
3515 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3516 }
3517 }
3518
3519 if (C.kind == CXCursor_ObjCCategoryDecl ||
3520 C.kind == CXCursor_ObjCCategoryImplDecl) {
3521 if (pieceIndex > 0)
3522 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003523 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3525 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003526 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3528 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3529 }
3530
3531 if (C.kind == CXCursor_ModuleImportDecl) {
3532 if (pieceIndex > 0)
3533 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003534 if (const ImportDecl *ImportD =
3535 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3537 if (!Locs.empty())
3538 return cxloc::translateSourceRange(Ctx,
3539 SourceRange(Locs.front(), Locs.back()));
3540 }
3541 return clang_getNullRange();
3542 }
3543
3544 // FIXME: A CXCursor_InclusionDirective should give the location of the
3545 // filename, but we don't keep track of this.
3546
3547 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3548 // but we don't keep track of this.
3549
3550 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3551 // but we don't keep track of this.
3552
3553 // Default handling, give the location of the cursor.
3554
3555 if (pieceIndex > 0)
3556 return clang_getNullRange();
3557
3558 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3559 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3560 return cxloc::translateSourceRange(Ctx, Loc);
3561}
3562
3563CXString clang_getCursorDisplayName(CXCursor C) {
3564 if (!clang_isDeclaration(C.kind))
3565 return clang_getCursorSpelling(C);
3566
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003567 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003569 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003570
3571 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003572 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 D = FunTmpl->getTemplatedDecl();
3574
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003575 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 SmallString<64> Str;
3577 llvm::raw_svector_ostream OS(Str);
3578 OS << *Function;
3579 if (Function->getPrimaryTemplate())
3580 OS << "<>";
3581 OS << "(";
3582 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3583 if (I)
3584 OS << ", ";
3585 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3586 }
3587
3588 if (Function->isVariadic()) {
3589 if (Function->getNumParams())
3590 OS << ", ";
3591 OS << "...";
3592 }
3593 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003594 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 }
3596
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003597 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 SmallString<64> Str;
3599 llvm::raw_svector_ostream OS(Str);
3600 OS << *ClassTemplate;
3601 OS << "<";
3602 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3603 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3604 if (I)
3605 OS << ", ";
3606
3607 NamedDecl *Param = Params->getParam(I);
3608 if (Param->getIdentifier()) {
3609 OS << Param->getIdentifier()->getName();
3610 continue;
3611 }
3612
3613 // There is no parameter name, which makes this tricky. Try to come up
3614 // with something useful that isn't too long.
3615 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3616 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3617 else if (NonTypeTemplateParmDecl *NTTP
3618 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3619 OS << NTTP->getType().getAsString(Policy);
3620 else
3621 OS << "template<...> class";
3622 }
3623
3624 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003625 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 }
3627
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003628 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3630 // If the type was explicitly written, use that.
3631 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003632 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003633
Benjamin Kramer9170e912013-02-22 15:46:01 +00003634 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 llvm::raw_svector_ostream OS(Str);
3636 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003637 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 ClassSpec->getTemplateArgs().data(),
3639 ClassSpec->getTemplateArgs().size(),
3640 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003641 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 }
3643
3644 return clang_getCursorSpelling(C);
3645}
3646
3647CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3648 switch (Kind) {
3649 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003777 case CXCursor_ObjCSelfExpr:
3778 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003895 case CXCursor_PackedAttr:
3896 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003897 case CXCursor_PureAttr:
3898 return cxstring::createRef("attribute(pure)");
3899 case CXCursor_ConstAttr:
3900 return cxstring::createRef("attribute(const)");
3901 case CXCursor_NoDuplicateAttr:
3902 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003903 case CXCursor_CUDAConstantAttr:
3904 return cxstring::createRef("attribute(constant)");
3905 case CXCursor_CUDADeviceAttr:
3906 return cxstring::createRef("attribute(device)");
3907 case CXCursor_CUDAGlobalAttr:
3908 return cxstring::createRef("attribute(global)");
3909 case CXCursor_CUDAHostAttr:
3910 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003959 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003960 return cxstring::createRef("OMPParallelDirective");
3961 case CXCursor_OMPSimdDirective:
3962 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003963 case CXCursor_OMPForDirective:
3964 return cxstring::createRef("OMPForDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 }
3966
3967 llvm_unreachable("Unhandled CXCursorKind");
3968}
3969
3970struct GetCursorData {
3971 SourceLocation TokenBeginLoc;
3972 bool PointsAtMacroArgExpansion;
3973 bool VisitedObjCPropertyImplDecl;
3974 SourceLocation VisitedDeclaratorDeclStartLoc;
3975 CXCursor &BestCursor;
3976
3977 GetCursorData(SourceManager &SM,
3978 SourceLocation tokenBegin, CXCursor &outputCursor)
3979 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3980 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3981 VisitedObjCPropertyImplDecl = false;
3982 }
3983};
3984
3985static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3986 CXCursor parent,
3987 CXClientData client_data) {
3988 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3989 CXCursor *BestCursor = &Data->BestCursor;
3990
3991 // If we point inside a macro argument we should provide info of what the
3992 // token is so use the actual cursor, don't replace it with a macro expansion
3993 // cursor.
3994 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3995 return CXChildVisit_Recurse;
3996
3997 if (clang_isDeclaration(cursor.kind)) {
3998 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003999 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4001 if (MD->isImplicit())
4002 return CXChildVisit_Break;
4003
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004004 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4006 // Check that when we have multiple @class references in the same line,
4007 // that later ones do not override the previous ones.
4008 // If we have:
4009 // @class Foo, Bar;
4010 // source ranges for both start at '@', so 'Bar' will end up overriding
4011 // 'Foo' even though the cursor location was at 'Foo'.
4012 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4013 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004014 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4016 if (PrevID != ID &&
4017 !PrevID->isThisDeclarationADefinition() &&
4018 !ID->isThisDeclarationADefinition())
4019 return CXChildVisit_Break;
4020 }
4021
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004022 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4024 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4025 // Check that when we have multiple declarators in the same line,
4026 // that later ones do not override the previous ones.
4027 // If we have:
4028 // int Foo, Bar;
4029 // source ranges for both start at 'int', so 'Bar' will end up overriding
4030 // 'Foo' even though the cursor location was at 'Foo'.
4031 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4032 return CXChildVisit_Break;
4033 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4034
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004035 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4037 (void)PropImp;
4038 // Check that when we have multiple @synthesize in the same line,
4039 // that later ones do not override the previous ones.
4040 // If we have:
4041 // @synthesize Foo, Bar;
4042 // source ranges for both start at '@', so 'Bar' will end up overriding
4043 // 'Foo' even though the cursor location was at 'Foo'.
4044 if (Data->VisitedObjCPropertyImplDecl)
4045 return CXChildVisit_Break;
4046 Data->VisitedObjCPropertyImplDecl = true;
4047 }
4048 }
4049
4050 if (clang_isExpression(cursor.kind) &&
4051 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004052 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 // Avoid having the cursor of an expression replace the declaration cursor
4054 // when the expression source range overlaps the declaration range.
4055 // This can happen for C++ constructor expressions whose range generally
4056 // include the variable declaration, e.g.:
4057 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4058 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4059 D->getLocation() == Data->TokenBeginLoc)
4060 return CXChildVisit_Break;
4061 }
4062 }
4063
4064 // If our current best cursor is the construction of a temporary object,
4065 // don't replace that cursor with a type reference, because we want
4066 // clang_getCursor() to point at the constructor.
4067 if (clang_isExpression(BestCursor->kind) &&
4068 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4069 cursor.kind == CXCursor_TypeRef) {
4070 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4071 // as having the actual point on the type reference.
4072 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4073 return CXChildVisit_Recurse;
4074 }
4075
4076 *BestCursor = cursor;
4077 return CXChildVisit_Recurse;
4078}
4079
4080CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004081 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004082 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004084 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004085
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004086 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4088
4089 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4090 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4091
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004092 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 CXFile SearchFile;
4094 unsigned SearchLine, SearchColumn;
4095 CXFile ResultFile;
4096 unsigned ResultLine, ResultColumn;
4097 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4098 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4099 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004100
4101 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4102 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004103 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004104 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 SearchFileName = clang_getFileName(SearchFile);
4106 ResultFileName = clang_getFileName(ResultFile);
4107 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4108 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004109 *Log << llvm::format("(%s:%d:%d) = %s",
4110 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4111 clang_getCString(KindSpelling))
4112 << llvm::format("(%s:%d:%d):%s%s",
4113 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4114 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 clang_disposeString(SearchFileName);
4116 clang_disposeString(ResultFileName);
4117 clang_disposeString(KindSpelling);
4118 clang_disposeString(USR);
4119
4120 CXCursor Definition = clang_getCursorDefinition(Result);
4121 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4122 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4123 CXString DefinitionKindSpelling
4124 = clang_getCursorKindSpelling(Definition.kind);
4125 CXFile DefinitionFile;
4126 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004127 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004128 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004130 *Log << llvm::format(" -> %s(%s:%d:%d)",
4131 clang_getCString(DefinitionKindSpelling),
4132 clang_getCString(DefinitionFileName),
4133 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 clang_disposeString(DefinitionFileName);
4135 clang_disposeString(DefinitionKindSpelling);
4136 }
4137 }
4138
4139 return Result;
4140}
4141
4142CXCursor clang_getNullCursor(void) {
4143 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4144}
4145
4146unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004147 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4148 // can't set consistently. For example, when visiting a DeclStmt we will set
4149 // it but we don't set it on the result of clang_getCursorDefinition for
4150 // a reference of the same declaration.
4151 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4152 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4153 // to provide that kind of info.
4154 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004155 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004156 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004157 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004158
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 return X == Y;
4160}
4161
4162unsigned clang_hashCursor(CXCursor C) {
4163 unsigned Index = 0;
4164 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4165 Index = 1;
4166
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004167 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 std::make_pair(C.kind, C.data[Index]));
4169}
4170
4171unsigned clang_isInvalid(enum CXCursorKind K) {
4172 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4173}
4174
4175unsigned clang_isDeclaration(enum CXCursorKind K) {
4176 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4177 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4178}
4179
4180unsigned clang_isReference(enum CXCursorKind K) {
4181 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4182}
4183
4184unsigned clang_isExpression(enum CXCursorKind K) {
4185 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4186}
4187
4188unsigned clang_isStatement(enum CXCursorKind K) {
4189 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4190}
4191
4192unsigned clang_isAttribute(enum CXCursorKind K) {
4193 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4194}
4195
4196unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4197 return K == CXCursor_TranslationUnit;
4198}
4199
4200unsigned clang_isPreprocessing(enum CXCursorKind K) {
4201 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4202}
4203
4204unsigned clang_isUnexposed(enum CXCursorKind K) {
4205 switch (K) {
4206 case CXCursor_UnexposedDecl:
4207 case CXCursor_UnexposedExpr:
4208 case CXCursor_UnexposedStmt:
4209 case CXCursor_UnexposedAttr:
4210 return true;
4211 default:
4212 return false;
4213 }
4214}
4215
4216CXCursorKind clang_getCursorKind(CXCursor C) {
4217 return C.kind;
4218}
4219
4220CXSourceLocation clang_getCursorLocation(CXCursor C) {
4221 if (clang_isReference(C.kind)) {
4222 switch (C.kind) {
4223 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004224 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 = getCursorObjCSuperClassRef(C);
4226 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4227 }
4228
4229 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004230 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 = getCursorObjCProtocolRef(C);
4232 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4233 }
4234
4235 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004236 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 = getCursorObjCClassRef(C);
4238 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4239 }
4240
4241 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004242 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4244 }
4245
4246 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004247 std::pair<const TemplateDecl *, SourceLocation> P =
4248 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4250 }
4251
4252 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004253 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4255 }
4256
4257 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004258 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4260 }
4261
4262 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004263 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4265 }
4266
4267 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004268 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 if (!BaseSpec)
4270 return clang_getNullLocation();
4271
4272 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4273 return cxloc::translateSourceLocation(getCursorContext(C),
4274 TSInfo->getTypeLoc().getBeginLoc());
4275
4276 return cxloc::translateSourceLocation(getCursorContext(C),
4277 BaseSpec->getLocStart());
4278 }
4279
4280 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004281 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4283 }
4284
4285 case CXCursor_OverloadedDeclRef:
4286 return cxloc::translateSourceLocation(getCursorContext(C),
4287 getCursorOverloadedDeclRef(C).second);
4288
4289 default:
4290 // FIXME: Need a way to enumerate all non-reference cases.
4291 llvm_unreachable("Missed a reference kind");
4292 }
4293 }
4294
4295 if (clang_isExpression(C.kind))
4296 return cxloc::translateSourceLocation(getCursorContext(C),
4297 getLocationFromExpr(getCursorExpr(C)));
4298
4299 if (clang_isStatement(C.kind))
4300 return cxloc::translateSourceLocation(getCursorContext(C),
4301 getCursorStmt(C)->getLocStart());
4302
4303 if (C.kind == CXCursor_PreprocessingDirective) {
4304 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4305 return cxloc::translateSourceLocation(getCursorContext(C), L);
4306 }
4307
4308 if (C.kind == CXCursor_MacroExpansion) {
4309 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004310 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 return cxloc::translateSourceLocation(getCursorContext(C), L);
4312 }
4313
4314 if (C.kind == CXCursor_MacroDefinition) {
4315 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4316 return cxloc::translateSourceLocation(getCursorContext(C), L);
4317 }
4318
4319 if (C.kind == CXCursor_InclusionDirective) {
4320 SourceLocation L
4321 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4322 return cxloc::translateSourceLocation(getCursorContext(C), L);
4323 }
4324
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004325 if (clang_isAttribute(C.kind)) {
4326 SourceLocation L
4327 = cxcursor::getCursorAttr(C)->getLocation();
4328 return cxloc::translateSourceLocation(getCursorContext(C), L);
4329 }
4330
Guy Benyei11169dd2012-12-18 14:30:41 +00004331 if (!clang_isDeclaration(C.kind))
4332 return clang_getNullLocation();
4333
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004334 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004335 if (!D)
4336 return clang_getNullLocation();
4337
4338 SourceLocation Loc = D->getLocation();
4339 // FIXME: Multiple variables declared in a single declaration
4340 // currently lack the information needed to correctly determine their
4341 // ranges when accounting for the type-specifier. We use context
4342 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4343 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004344 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004345 if (!cxcursor::isFirstInDeclGroup(C))
4346 Loc = VD->getLocation();
4347 }
4348
4349 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004350 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004351 Loc = MD->getSelectorStartLoc();
4352
4353 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4354}
4355
4356} // end extern "C"
4357
4358CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4359 assert(TU);
4360
4361 // Guard against an invalid SourceLocation, or we may assert in one
4362 // of the following calls.
4363 if (SLoc.isInvalid())
4364 return clang_getNullCursor();
4365
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004366 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004367
4368 // Translate the given source location to make it point at the beginning of
4369 // the token under the cursor.
4370 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4371 CXXUnit->getASTContext().getLangOpts());
4372
4373 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4374 if (SLoc.isValid()) {
4375 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4376 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4377 /*VisitPreprocessorLast=*/true,
4378 /*VisitIncludedEntities=*/false,
4379 SourceLocation(SLoc));
4380 CursorVis.visitFileRegion();
4381 }
4382
4383 return Result;
4384}
4385
4386static SourceRange getRawCursorExtent(CXCursor C) {
4387 if (clang_isReference(C.kind)) {
4388 switch (C.kind) {
4389 case CXCursor_ObjCSuperClassRef:
4390 return getCursorObjCSuperClassRef(C).second;
4391
4392 case CXCursor_ObjCProtocolRef:
4393 return getCursorObjCProtocolRef(C).second;
4394
4395 case CXCursor_ObjCClassRef:
4396 return getCursorObjCClassRef(C).second;
4397
4398 case CXCursor_TypeRef:
4399 return getCursorTypeRef(C).second;
4400
4401 case CXCursor_TemplateRef:
4402 return getCursorTemplateRef(C).second;
4403
4404 case CXCursor_NamespaceRef:
4405 return getCursorNamespaceRef(C).second;
4406
4407 case CXCursor_MemberRef:
4408 return getCursorMemberRef(C).second;
4409
4410 case CXCursor_CXXBaseSpecifier:
4411 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4412
4413 case CXCursor_LabelRef:
4414 return getCursorLabelRef(C).second;
4415
4416 case CXCursor_OverloadedDeclRef:
4417 return getCursorOverloadedDeclRef(C).second;
4418
4419 case CXCursor_VariableRef:
4420 return getCursorVariableRef(C).second;
4421
4422 default:
4423 // FIXME: Need a way to enumerate all non-reference cases.
4424 llvm_unreachable("Missed a reference kind");
4425 }
4426 }
4427
4428 if (clang_isExpression(C.kind))
4429 return getCursorExpr(C)->getSourceRange();
4430
4431 if (clang_isStatement(C.kind))
4432 return getCursorStmt(C)->getSourceRange();
4433
4434 if (clang_isAttribute(C.kind))
4435 return getCursorAttr(C)->getRange();
4436
4437 if (C.kind == CXCursor_PreprocessingDirective)
4438 return cxcursor::getCursorPreprocessingDirective(C);
4439
4440 if (C.kind == CXCursor_MacroExpansion) {
4441 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004442 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 return TU->mapRangeFromPreamble(Range);
4444 }
4445
4446 if (C.kind == CXCursor_MacroDefinition) {
4447 ASTUnit *TU = getCursorASTUnit(C);
4448 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4449 return TU->mapRangeFromPreamble(Range);
4450 }
4451
4452 if (C.kind == CXCursor_InclusionDirective) {
4453 ASTUnit *TU = getCursorASTUnit(C);
4454 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4455 return TU->mapRangeFromPreamble(Range);
4456 }
4457
4458 if (C.kind == CXCursor_TranslationUnit) {
4459 ASTUnit *TU = getCursorASTUnit(C);
4460 FileID MainID = TU->getSourceManager().getMainFileID();
4461 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4462 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4463 return SourceRange(Start, End);
4464 }
4465
4466 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004467 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 if (!D)
4469 return SourceRange();
4470
4471 SourceRange R = D->getSourceRange();
4472 // FIXME: Multiple variables declared in a single declaration
4473 // currently lack the information needed to correctly determine their
4474 // ranges when accounting for the type-specifier. We use context
4475 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4476 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004477 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004478 if (!cxcursor::isFirstInDeclGroup(C))
4479 R.setBegin(VD->getLocation());
4480 }
4481 return R;
4482 }
4483 return SourceRange();
4484}
4485
4486/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4487/// the decl-specifier-seq for declarations.
4488static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4489 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004490 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 if (!D)
4492 return SourceRange();
4493
4494 SourceRange R = D->getSourceRange();
4495
4496 // Adjust the start of the location for declarations preceded by
4497 // declaration specifiers.
4498 SourceLocation StartLoc;
4499 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4500 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4501 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004502 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4504 StartLoc = TI->getTypeLoc().getLocStart();
4505 }
4506
4507 if (StartLoc.isValid() && R.getBegin().isValid() &&
4508 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4509 R.setBegin(StartLoc);
4510
4511 // FIXME: Multiple variables declared in a single declaration
4512 // currently lack the information needed to correctly determine their
4513 // ranges when accounting for the type-specifier. We use context
4514 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4515 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004516 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 if (!cxcursor::isFirstInDeclGroup(C))
4518 R.setBegin(VD->getLocation());
4519 }
4520
4521 return R;
4522 }
4523
4524 return getRawCursorExtent(C);
4525}
4526
4527extern "C" {
4528
4529CXSourceRange clang_getCursorExtent(CXCursor C) {
4530 SourceRange R = getRawCursorExtent(C);
4531 if (R.isInvalid())
4532 return clang_getNullRange();
4533
4534 return cxloc::translateSourceRange(getCursorContext(C), R);
4535}
4536
4537CXCursor clang_getCursorReferenced(CXCursor C) {
4538 if (clang_isInvalid(C.kind))
4539 return clang_getNullCursor();
4540
4541 CXTranslationUnit tu = getCursorTU(C);
4542 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004543 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004544 if (!D)
4545 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004546 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004548 if (const ObjCPropertyImplDecl *PropImpl =
4549 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4551 return MakeCXCursor(Property, tu);
4552
4553 return C;
4554 }
4555
4556 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004557 const Expr *E = getCursorExpr(C);
4558 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 if (D) {
4560 CXCursor declCursor = MakeCXCursor(D, tu);
4561 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4562 declCursor);
4563 return declCursor;
4564 }
4565
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004566 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 return MakeCursorOverloadedDeclRef(Ovl, tu);
4568
4569 return clang_getNullCursor();
4570 }
4571
4572 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004573 const Stmt *S = getCursorStmt(C);
4574 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 if (LabelDecl *label = Goto->getLabel())
4576 if (LabelStmt *labelS = label->getStmt())
4577 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4578
4579 return clang_getNullCursor();
4580 }
4581
4582 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004583 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 return MakeMacroDefinitionCursor(Def, tu);
4585 }
4586
4587 if (!clang_isReference(C.kind))
4588 return clang_getNullCursor();
4589
4590 switch (C.kind) {
4591 case CXCursor_ObjCSuperClassRef:
4592 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4593
4594 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004595 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4596 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 return MakeCXCursor(Def, tu);
4598
4599 return MakeCXCursor(Prot, tu);
4600 }
4601
4602 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004603 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4604 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 return MakeCXCursor(Def, tu);
4606
4607 return MakeCXCursor(Class, tu);
4608 }
4609
4610 case CXCursor_TypeRef:
4611 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4612
4613 case CXCursor_TemplateRef:
4614 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4615
4616 case CXCursor_NamespaceRef:
4617 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4618
4619 case CXCursor_MemberRef:
4620 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4621
4622 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004623 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4625 tu ));
4626 }
4627
4628 case CXCursor_LabelRef:
4629 // FIXME: We end up faking the "parent" declaration here because we
4630 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004631 return MakeCXCursor(getCursorLabelRef(C).first,
4632 cxtu::getASTUnit(tu)->getASTContext()
4633 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 tu);
4635
4636 case CXCursor_OverloadedDeclRef:
4637 return C;
4638
4639 case CXCursor_VariableRef:
4640 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4641
4642 default:
4643 // We would prefer to enumerate all non-reference cursor kinds here.
4644 llvm_unreachable("Unhandled reference cursor kind");
4645 }
4646}
4647
4648CXCursor clang_getCursorDefinition(CXCursor C) {
4649 if (clang_isInvalid(C.kind))
4650 return clang_getNullCursor();
4651
4652 CXTranslationUnit TU = getCursorTU(C);
4653
4654 bool WasReference = false;
4655 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4656 C = clang_getCursorReferenced(C);
4657 WasReference = true;
4658 }
4659
4660 if (C.kind == CXCursor_MacroExpansion)
4661 return clang_getCursorReferenced(C);
4662
4663 if (!clang_isDeclaration(C.kind))
4664 return clang_getNullCursor();
4665
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004666 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 if (!D)
4668 return clang_getNullCursor();
4669
4670 switch (D->getKind()) {
4671 // Declaration kinds that don't really separate the notions of
4672 // declaration and definition.
4673 case Decl::Namespace:
4674 case Decl::Typedef:
4675 case Decl::TypeAlias:
4676 case Decl::TypeAliasTemplate:
4677 case Decl::TemplateTypeParm:
4678 case Decl::EnumConstant:
4679 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004680 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case Decl::IndirectField:
4682 case Decl::ObjCIvar:
4683 case Decl::ObjCAtDefsField:
4684 case Decl::ImplicitParam:
4685 case Decl::ParmVar:
4686 case Decl::NonTypeTemplateParm:
4687 case Decl::TemplateTemplateParm:
4688 case Decl::ObjCCategoryImpl:
4689 case Decl::ObjCImplementation:
4690 case Decl::AccessSpec:
4691 case Decl::LinkageSpec:
4692 case Decl::ObjCPropertyImpl:
4693 case Decl::FileScopeAsm:
4694 case Decl::StaticAssert:
4695 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004696 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 case Decl::Label: // FIXME: Is this right??
4698 case Decl::ClassScopeFunctionSpecialization:
4699 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004700 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 return C;
4702
4703 // Declaration kinds that don't make any sense here, but are
4704 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004705 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004706 case Decl::TranslationUnit:
4707 break;
4708
4709 // Declaration kinds for which the definition is not resolvable.
4710 case Decl::UnresolvedUsingTypename:
4711 case Decl::UnresolvedUsingValue:
4712 break;
4713
4714 case Decl::UsingDirective:
4715 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4716 TU);
4717
4718 case Decl::NamespaceAlias:
4719 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4720
4721 case Decl::Enum:
4722 case Decl::Record:
4723 case Decl::CXXRecord:
4724 case Decl::ClassTemplateSpecialization:
4725 case Decl::ClassTemplatePartialSpecialization:
4726 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4727 return MakeCXCursor(Def, TU);
4728 return clang_getNullCursor();
4729
4730 case Decl::Function:
4731 case Decl::CXXMethod:
4732 case Decl::CXXConstructor:
4733 case Decl::CXXDestructor:
4734 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004735 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004737 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 return clang_getNullCursor();
4739 }
4740
Larisse Voufo39a1e502013-08-06 01:03:05 +00004741 case Decl::Var:
4742 case Decl::VarTemplateSpecialization:
4743 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004745 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 return MakeCXCursor(Def, TU);
4747 return clang_getNullCursor();
4748 }
4749
4750 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004751 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004752 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4753 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4754 return clang_getNullCursor();
4755 }
4756
4757 case Decl::ClassTemplate: {
4758 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4759 ->getDefinition())
4760 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4761 TU);
4762 return clang_getNullCursor();
4763 }
4764
Larisse Voufo39a1e502013-08-06 01:03:05 +00004765 case Decl::VarTemplate: {
4766 if (VarDecl *Def =
4767 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4768 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4769 return clang_getNullCursor();
4770 }
4771
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 case Decl::Using:
4773 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4774 D->getLocation(), TU);
4775
4776 case Decl::UsingShadow:
4777 return clang_getCursorDefinition(
4778 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4779 TU));
4780
4781 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004782 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 if (Method->isThisDeclarationADefinition())
4784 return C;
4785
4786 // Dig out the method definition in the associated
4787 // @implementation, if we have it.
4788 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004789 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004790 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4791 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4792 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4793 Method->isInstanceMethod()))
4794 if (Def->isThisDeclarationADefinition())
4795 return MakeCXCursor(Def, TU);
4796
4797 return clang_getNullCursor();
4798 }
4799
4800 case Decl::ObjCCategory:
4801 if (ObjCCategoryImplDecl *Impl
4802 = cast<ObjCCategoryDecl>(D)->getImplementation())
4803 return MakeCXCursor(Impl, TU);
4804 return clang_getNullCursor();
4805
4806 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004807 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004808 return MakeCXCursor(Def, TU);
4809 return clang_getNullCursor();
4810
4811 case Decl::ObjCInterface: {
4812 // There are two notions of a "definition" for an Objective-C
4813 // class: the interface and its implementation. When we resolved a
4814 // reference to an Objective-C class, produce the @interface as
4815 // the definition; when we were provided with the interface,
4816 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004817 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004819 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004820 return MakeCXCursor(Def, TU);
4821 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4822 return MakeCXCursor(Impl, TU);
4823 return clang_getNullCursor();
4824 }
4825
4826 case Decl::ObjCProperty:
4827 // FIXME: We don't really know where to find the
4828 // ObjCPropertyImplDecls that implement this property.
4829 return clang_getNullCursor();
4830
4831 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004832 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004833 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004834 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 return MakeCXCursor(Def, TU);
4836
4837 return clang_getNullCursor();
4838
4839 case Decl::Friend:
4840 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4841 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4842 return clang_getNullCursor();
4843
4844 case Decl::FriendTemplate:
4845 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4846 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4847 return clang_getNullCursor();
4848 }
4849
4850 return clang_getNullCursor();
4851}
4852
4853unsigned clang_isCursorDefinition(CXCursor C) {
4854 if (!clang_isDeclaration(C.kind))
4855 return 0;
4856
4857 return clang_getCursorDefinition(C) == C;
4858}
4859
4860CXCursor clang_getCanonicalCursor(CXCursor C) {
4861 if (!clang_isDeclaration(C.kind))
4862 return C;
4863
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004864 if (const Decl *D = getCursorDecl(C)) {
4865 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004866 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4867 return MakeCXCursor(CatD, getCursorTU(C));
4868
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004869 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4870 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004871 return MakeCXCursor(IFD, getCursorTU(C));
4872
4873 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4874 }
4875
4876 return C;
4877}
4878
4879int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4880 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4881}
4882
4883unsigned clang_getNumOverloadedDecls(CXCursor C) {
4884 if (C.kind != CXCursor_OverloadedDeclRef)
4885 return 0;
4886
4887 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004888 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004889 return E->getNumDecls();
4890
4891 if (OverloadedTemplateStorage *S
4892 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4893 return S->size();
4894
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004895 const Decl *D = Storage.get<const Decl *>();
4896 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004897 return Using->shadow_size();
4898
4899 return 0;
4900}
4901
4902CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4903 if (cursor.kind != CXCursor_OverloadedDeclRef)
4904 return clang_getNullCursor();
4905
4906 if (index >= clang_getNumOverloadedDecls(cursor))
4907 return clang_getNullCursor();
4908
4909 CXTranslationUnit TU = getCursorTU(cursor);
4910 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004911 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004912 return MakeCXCursor(E->decls_begin()[index], TU);
4913
4914 if (OverloadedTemplateStorage *S
4915 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4916 return MakeCXCursor(S->begin()[index], TU);
4917
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004918 const Decl *D = Storage.get<const Decl *>();
4919 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 // FIXME: This is, unfortunately, linear time.
4921 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4922 std::advance(Pos, index);
4923 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4924 }
4925
4926 return clang_getNullCursor();
4927}
4928
4929void clang_getDefinitionSpellingAndExtent(CXCursor C,
4930 const char **startBuf,
4931 const char **endBuf,
4932 unsigned *startLine,
4933 unsigned *startColumn,
4934 unsigned *endLine,
4935 unsigned *endColumn) {
4936 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004937 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004938 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4939
4940 SourceManager &SM = FD->getASTContext().getSourceManager();
4941 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4942 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4943 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4944 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4945 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4946 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4947}
4948
4949
4950CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4951 unsigned PieceIndex) {
4952 RefNamePieces Pieces;
4953
4954 switch (C.kind) {
4955 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004956 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004957 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4958 E->getQualifierLoc().getSourceRange());
4959 break;
4960
4961 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004962 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004963 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4964 E->getQualifierLoc().getSourceRange(),
4965 E->getOptionalExplicitTemplateArgs());
4966 break;
4967
4968 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004969 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004970 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004971 const Expr *Callee = OCE->getCallee();
4972 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004973 Callee = ICE->getSubExpr();
4974
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004975 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004976 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4977 DRE->getQualifierLoc().getSourceRange());
4978 }
4979 break;
4980
4981 default:
4982 break;
4983 }
4984
4985 if (Pieces.empty()) {
4986 if (PieceIndex == 0)
4987 return clang_getCursorExtent(C);
4988 } else if (PieceIndex < Pieces.size()) {
4989 SourceRange R = Pieces[PieceIndex];
4990 if (R.isValid())
4991 return cxloc::translateSourceRange(getCursorContext(C), R);
4992 }
4993
4994 return clang_getNullRange();
4995}
4996
4997void clang_enableStackTraces(void) {
4998 llvm::sys::PrintStackTraceOnErrorSignal();
4999}
5000
5001void clang_executeOnThread(void (*fn)(void*), void *user_data,
5002 unsigned stack_size) {
5003 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5004}
5005
5006} // end: extern "C"
5007
5008//===----------------------------------------------------------------------===//
5009// Token-based Operations.
5010//===----------------------------------------------------------------------===//
5011
5012/* CXToken layout:
5013 * int_data[0]: a CXTokenKind
5014 * int_data[1]: starting token location
5015 * int_data[2]: token length
5016 * int_data[3]: reserved
5017 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5018 * otherwise unused.
5019 */
5020extern "C" {
5021
5022CXTokenKind clang_getTokenKind(CXToken CXTok) {
5023 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5024}
5025
5026CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5027 switch (clang_getTokenKind(CXTok)) {
5028 case CXToken_Identifier:
5029 case CXToken_Keyword:
5030 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005031 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005032 ->getNameStart());
5033
5034 case CXToken_Literal: {
5035 // We have stashed the starting pointer in the ptr_data field. Use it.
5036 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005037 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005038 }
5039
5040 case CXToken_Punctuation:
5041 case CXToken_Comment:
5042 break;
5043 }
5044
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005045 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005046 LOG_BAD_TU(TU);
5047 return cxstring::createEmpty();
5048 }
5049
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 // We have to find the starting buffer pointer the hard way, by
5051 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005052 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005054 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005055
5056 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5057 std::pair<FileID, unsigned> LocInfo
5058 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5059 bool Invalid = false;
5060 StringRef Buffer
5061 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5062 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005063 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005064
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005065 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005066}
5067
5068CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005069 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005070 LOG_BAD_TU(TU);
5071 return clang_getNullLocation();
5072 }
5073
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005074 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005075 if (!CXXUnit)
5076 return clang_getNullLocation();
5077
5078 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5079 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5080}
5081
5082CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005083 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005084 LOG_BAD_TU(TU);
5085 return clang_getNullRange();
5086 }
5087
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005088 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005089 if (!CXXUnit)
5090 return clang_getNullRange();
5091
5092 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5093 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5094}
5095
5096static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5097 SmallVectorImpl<CXToken> &CXTokens) {
5098 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5099 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005100 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005101 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005102 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005103
5104 // Cannot tokenize across files.
5105 if (BeginLocInfo.first != EndLocInfo.first)
5106 return;
5107
5108 // Create a lexer
5109 bool Invalid = false;
5110 StringRef Buffer
5111 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5112 if (Invalid)
5113 return;
5114
5115 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5116 CXXUnit->getASTContext().getLangOpts(),
5117 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5118 Lex.SetCommentRetentionState(true);
5119
5120 // Lex tokens until we hit the end of the range.
5121 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5122 Token Tok;
5123 bool previousWasAt = false;
5124 do {
5125 // Lex the next token
5126 Lex.LexFromRawLexer(Tok);
5127 if (Tok.is(tok::eof))
5128 break;
5129
5130 // Initialize the CXToken.
5131 CXToken CXTok;
5132
5133 // - Common fields
5134 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5135 CXTok.int_data[2] = Tok.getLength();
5136 CXTok.int_data[3] = 0;
5137
5138 // - Kind-specific fields
5139 if (Tok.isLiteral()) {
5140 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005141 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 } else if (Tok.is(tok::raw_identifier)) {
5143 // Lookup the identifier to determine whether we have a keyword.
5144 IdentifierInfo *II
5145 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5146
5147 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5148 CXTok.int_data[0] = CXToken_Keyword;
5149 }
5150 else {
5151 CXTok.int_data[0] = Tok.is(tok::identifier)
5152 ? CXToken_Identifier
5153 : CXToken_Keyword;
5154 }
5155 CXTok.ptr_data = II;
5156 } else if (Tok.is(tok::comment)) {
5157 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005158 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 } else {
5160 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005161 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 }
5163 CXTokens.push_back(CXTok);
5164 previousWasAt = Tok.is(tok::at);
5165 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5166}
5167
5168void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5169 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005170 LOG_FUNC_SECTION {
5171 *Log << TU << ' ' << Range;
5172 }
5173
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005175 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 if (NumTokens)
5177 *NumTokens = 0;
5178
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005179 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005180 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005181 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005182 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005183
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005184 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005185 if (!CXXUnit || !Tokens || !NumTokens)
5186 return;
5187
5188 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5189
5190 SourceRange R = cxloc::translateCXSourceRange(Range);
5191 if (R.isInvalid())
5192 return;
5193
5194 SmallVector<CXToken, 32> CXTokens;
5195 getTokens(CXXUnit, R, CXTokens);
5196
5197 if (CXTokens.empty())
5198 return;
5199
5200 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5201 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5202 *NumTokens = CXTokens.size();
5203}
5204
5205void clang_disposeTokens(CXTranslationUnit TU,
5206 CXToken *Tokens, unsigned NumTokens) {
5207 free(Tokens);
5208}
5209
5210} // end: extern "C"
5211
5212//===----------------------------------------------------------------------===//
5213// Token annotation APIs.
5214//===----------------------------------------------------------------------===//
5215
Guy Benyei11169dd2012-12-18 14:30:41 +00005216static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5217 CXCursor parent,
5218 CXClientData client_data);
5219static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5220 CXClientData client_data);
5221
5222namespace {
5223class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 CXToken *Tokens;
5225 CXCursor *Cursors;
5226 unsigned NumTokens;
5227 unsigned TokIdx;
5228 unsigned PreprocessingTokIdx;
5229 CursorVisitor AnnotateVis;
5230 SourceManager &SrcMgr;
5231 bool HasContextSensitiveKeywords;
5232
5233 struct PostChildrenInfo {
5234 CXCursor Cursor;
5235 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005236 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005237 unsigned BeforeChildrenTokenIdx;
5238 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005239 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005240
5241 CXToken &getTok(unsigned Idx) {
5242 assert(Idx < NumTokens);
5243 return Tokens[Idx];
5244 }
5245 const CXToken &getTok(unsigned Idx) const {
5246 assert(Idx < NumTokens);
5247 return Tokens[Idx];
5248 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005249 bool MoreTokens() const { return TokIdx < NumTokens; }
5250 unsigned NextToken() const { return TokIdx; }
5251 void AdvanceToken() { ++TokIdx; }
5252 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005253 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 }
5255 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005256 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005257 }
5258 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005259 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 }
5261
5262 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005263 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 SourceRange);
5265
5266public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005267 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005268 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005269 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005271 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 AnnotateTokensVisitor, this,
5273 /*VisitPreprocessorLast=*/true,
5274 /*VisitIncludedEntities=*/false,
5275 RegionOfInterest,
5276 /*VisitDeclsOnly=*/false,
5277 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005278 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005279 HasContextSensitiveKeywords(false) { }
5280
5281 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5282 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5283 bool postVisitChildren(CXCursor cursor);
5284 void AnnotateTokens();
5285
5286 /// \brief Determine whether the annotator saw any cursors that have
5287 /// context-sensitive keywords.
5288 bool hasContextSensitiveKeywords() const {
5289 return HasContextSensitiveKeywords;
5290 }
5291
5292 ~AnnotateTokensWorker() {
5293 assert(PostChildrenInfos.empty());
5294 }
5295};
5296}
5297
5298void AnnotateTokensWorker::AnnotateTokens() {
5299 // Walk the AST within the region of interest, annotating tokens
5300 // along the way.
5301 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005302}
Guy Benyei11169dd2012-12-18 14:30:41 +00005303
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005304static inline void updateCursorAnnotation(CXCursor &Cursor,
5305 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005306 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005307 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005308 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005309}
5310
5311/// \brief It annotates and advances tokens with a cursor until the comparison
5312//// between the cursor location and the source range is the same as
5313/// \arg compResult.
5314///
5315/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5316/// Pass RangeOverlap to annotate tokens inside a range.
5317void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5318 RangeComparisonResult compResult,
5319 SourceRange range) {
5320 while (MoreTokens()) {
5321 const unsigned I = NextToken();
5322 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005323 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5324 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005325
5326 SourceLocation TokLoc = GetTokenLoc(I);
5327 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005328 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005329 AdvanceToken();
5330 continue;
5331 }
5332 break;
5333 }
5334}
5335
5336/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005337/// \returns true if it advanced beyond all macro tokens, false otherwise.
5338bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 CXCursor updateC,
5340 RangeComparisonResult compResult,
5341 SourceRange range) {
5342 assert(MoreTokens());
5343 assert(isFunctionMacroToken(NextToken()) &&
5344 "Should be called only for macro arg tokens");
5345
5346 // This works differently than annotateAndAdvanceTokens; because expanded
5347 // macro arguments can have arbitrary translation-unit source order, we do not
5348 // advance the token index one by one until a token fails the range test.
5349 // We only advance once past all of the macro arg tokens if all of them
5350 // pass the range test. If one of them fails we keep the token index pointing
5351 // at the start of the macro arg tokens so that the failing token will be
5352 // annotated by a subsequent annotation try.
5353
5354 bool atLeastOneCompFail = false;
5355
5356 unsigned I = NextToken();
5357 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5358 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5359 if (TokLoc.isFileID())
5360 continue; // not macro arg token, it's parens or comma.
5361 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5362 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5363 Cursors[I] = updateC;
5364 } else
5365 atLeastOneCompFail = true;
5366 }
5367
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005368 if (atLeastOneCompFail)
5369 return false;
5370
5371 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5372 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005373}
5374
5375enum CXChildVisitResult
5376AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005377 SourceRange cursorRange = getRawCursorExtent(cursor);
5378 if (cursorRange.isInvalid())
5379 return CXChildVisit_Recurse;
5380
5381 if (!HasContextSensitiveKeywords) {
5382 // Objective-C properties can have context-sensitive keywords.
5383 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005384 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005385 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5386 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5387 }
5388 // Objective-C methods can have context-sensitive keywords.
5389 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5390 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005391 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005392 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5393 if (Method->getObjCDeclQualifier())
5394 HasContextSensitiveKeywords = true;
5395 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005396 for (const auto *P : Method->params()) {
5397 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005398 HasContextSensitiveKeywords = true;
5399 break;
5400 }
5401 }
5402 }
5403 }
5404 }
5405 // C++ methods can have context-sensitive keywords.
5406 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005407 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5409 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5410 HasContextSensitiveKeywords = true;
5411 }
5412 }
5413 // C++ classes can have context-sensitive keywords.
5414 else if (cursor.kind == CXCursor_StructDecl ||
5415 cursor.kind == CXCursor_ClassDecl ||
5416 cursor.kind == CXCursor_ClassTemplate ||
5417 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005418 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005419 if (D->hasAttr<FinalAttr>())
5420 HasContextSensitiveKeywords = true;
5421 }
5422 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005423
5424 // Don't override a property annotation with its getter/setter method.
5425 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5426 parent.kind == CXCursor_ObjCPropertyDecl)
5427 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005428
5429 if (clang_isPreprocessing(cursor.kind)) {
5430 // Items in the preprocessing record are kept separate from items in
5431 // declarations, so we keep a separate token index.
5432 unsigned SavedTokIdx = TokIdx;
5433 TokIdx = PreprocessingTokIdx;
5434
5435 // Skip tokens up until we catch up to the beginning of the preprocessing
5436 // entry.
5437 while (MoreTokens()) {
5438 const unsigned I = NextToken();
5439 SourceLocation TokLoc = GetTokenLoc(I);
5440 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5441 case RangeBefore:
5442 AdvanceToken();
5443 continue;
5444 case RangeAfter:
5445 case RangeOverlap:
5446 break;
5447 }
5448 break;
5449 }
5450
5451 // Look at all of the tokens within this range.
5452 while (MoreTokens()) {
5453 const unsigned I = NextToken();
5454 SourceLocation TokLoc = GetTokenLoc(I);
5455 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5456 case RangeBefore:
5457 llvm_unreachable("Infeasible");
5458 case RangeAfter:
5459 break;
5460 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005461 // For macro expansions, just note where the beginning of the macro
5462 // expansion occurs.
5463 if (cursor.kind == CXCursor_MacroExpansion) {
5464 if (TokLoc == cursorRange.getBegin())
5465 Cursors[I] = cursor;
5466 AdvanceToken();
5467 break;
5468 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005469 // We may have already annotated macro names inside macro definitions.
5470 if (Cursors[I].kind != CXCursor_MacroExpansion)
5471 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005472 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 continue;
5474 }
5475 break;
5476 }
5477
5478 // Save the preprocessing token index; restore the non-preprocessing
5479 // token index.
5480 PreprocessingTokIdx = TokIdx;
5481 TokIdx = SavedTokIdx;
5482 return CXChildVisit_Recurse;
5483 }
5484
5485 if (cursorRange.isInvalid())
5486 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005487
5488 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005490 const enum CXCursorKind K = clang_getCursorKind(parent);
5491 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005492 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5493 // Attributes are annotated out-of-order, skip tokens until we reach it.
5494 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005495 ? clang_getNullCursor() : parent;
5496
5497 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5498
5499 // Avoid having the cursor of an expression "overwrite" the annotation of the
5500 // variable declaration that it belongs to.
5501 // This can happen for C++ constructor expressions whose range generally
5502 // include the variable declaration, e.g.:
5503 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005504 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005505 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005506 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005507 const unsigned I = NextToken();
5508 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5509 E->getLocStart() == D->getLocation() &&
5510 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005511 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 AdvanceToken();
5513 }
5514 }
5515 }
5516
5517 // Before recursing into the children keep some state that we are going
5518 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5519 // extra work after the child nodes are visited.
5520 // Note that we don't call VisitChildren here to avoid traversing statements
5521 // code-recursively which can blow the stack.
5522
5523 PostChildrenInfo Info;
5524 Info.Cursor = cursor;
5525 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005526 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005527 Info.BeforeChildrenTokenIdx = NextToken();
5528 PostChildrenInfos.push_back(Info);
5529
5530 return CXChildVisit_Recurse;
5531}
5532
5533bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5534 if (PostChildrenInfos.empty())
5535 return false;
5536 const PostChildrenInfo &Info = PostChildrenInfos.back();
5537 if (!clang_equalCursors(Info.Cursor, cursor))
5538 return false;
5539
5540 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5541 const unsigned AfterChildren = NextToken();
5542 SourceRange cursorRange = Info.CursorRange;
5543
5544 // Scan the tokens that are at the end of the cursor, but are not captured
5545 // but the child cursors.
5546 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5547
5548 // Scan the tokens that are at the beginning of the cursor, but are not
5549 // capture by the child cursors.
5550 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5551 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5552 break;
5553
5554 Cursors[I] = cursor;
5555 }
5556
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005557 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5558 // encountered the attribute cursor.
5559 if (clang_isAttribute(cursor.kind))
5560 TokIdx = Info.BeforeReachingCursorIdx;
5561
Guy Benyei11169dd2012-12-18 14:30:41 +00005562 PostChildrenInfos.pop_back();
5563 return false;
5564}
5565
5566static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5567 CXCursor parent,
5568 CXClientData client_data) {
5569 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5570}
5571
5572static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5573 CXClientData client_data) {
5574 return static_cast<AnnotateTokensWorker*>(client_data)->
5575 postVisitChildren(cursor);
5576}
5577
5578namespace {
5579
5580/// \brief Uses the macro expansions in the preprocessing record to find
5581/// and mark tokens that are macro arguments. This info is used by the
5582/// AnnotateTokensWorker.
5583class MarkMacroArgTokensVisitor {
5584 SourceManager &SM;
5585 CXToken *Tokens;
5586 unsigned NumTokens;
5587 unsigned CurIdx;
5588
5589public:
5590 MarkMacroArgTokensVisitor(SourceManager &SM,
5591 CXToken *tokens, unsigned numTokens)
5592 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5593
5594 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5595 if (cursor.kind != CXCursor_MacroExpansion)
5596 return CXChildVisit_Continue;
5597
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005598 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 if (macroRange.getBegin() == macroRange.getEnd())
5600 return CXChildVisit_Continue; // it's not a function macro.
5601
5602 for (; CurIdx < NumTokens; ++CurIdx) {
5603 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5604 macroRange.getBegin()))
5605 break;
5606 }
5607
5608 if (CurIdx == NumTokens)
5609 return CXChildVisit_Break;
5610
5611 for (; CurIdx < NumTokens; ++CurIdx) {
5612 SourceLocation tokLoc = getTokenLoc(CurIdx);
5613 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5614 break;
5615
5616 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5617 }
5618
5619 if (CurIdx == NumTokens)
5620 return CXChildVisit_Break;
5621
5622 return CXChildVisit_Continue;
5623 }
5624
5625private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005626 CXToken &getTok(unsigned Idx) {
5627 assert(Idx < NumTokens);
5628 return Tokens[Idx];
5629 }
5630 const CXToken &getTok(unsigned Idx) const {
5631 assert(Idx < NumTokens);
5632 return Tokens[Idx];
5633 }
5634
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005636 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 }
5638
5639 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5640 // The third field is reserved and currently not used. Use it here
5641 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005642 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 }
5644};
5645
5646} // end anonymous namespace
5647
5648static CXChildVisitResult
5649MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5650 CXClientData client_data) {
5651 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5652 parent);
5653}
5654
5655namespace {
5656 struct clang_annotateTokens_Data {
5657 CXTranslationUnit TU;
5658 ASTUnit *CXXUnit;
5659 CXToken *Tokens;
5660 unsigned NumTokens;
5661 CXCursor *Cursors;
5662 };
5663}
5664
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005665/// \brief Used by \c annotatePreprocessorTokens.
5666/// \returns true if lexing was finished, false otherwise.
5667static bool lexNext(Lexer &Lex, Token &Tok,
5668 unsigned &NextIdx, unsigned NumTokens) {
5669 if (NextIdx >= NumTokens)
5670 return true;
5671
5672 ++NextIdx;
5673 Lex.LexFromRawLexer(Tok);
5674 if (Tok.is(tok::eof))
5675 return true;
5676
5677 return false;
5678}
5679
Guy Benyei11169dd2012-12-18 14:30:41 +00005680static void annotatePreprocessorTokens(CXTranslationUnit TU,
5681 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005682 CXCursor *Cursors,
5683 CXToken *Tokens,
5684 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005685 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005686
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005687 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5689 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005690 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005692 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005693
5694 if (BeginLocInfo.first != EndLocInfo.first)
5695 return;
5696
5697 StringRef Buffer;
5698 bool Invalid = false;
5699 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5700 if (Buffer.empty() || Invalid)
5701 return;
5702
5703 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5704 CXXUnit->getASTContext().getLangOpts(),
5705 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5706 Buffer.end());
5707 Lex.SetCommentRetentionState(true);
5708
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005709 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005710 // Lex tokens in raw mode until we hit the end of the range, to avoid
5711 // entering #includes or expanding macros.
5712 while (true) {
5713 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005714 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5715 break;
5716 unsigned TokIdx = NextIdx-1;
5717 assert(Tok.getLocation() ==
5718 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005719
5720 reprocess:
5721 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005722 // We have found a preprocessing directive. Annotate the tokens
5723 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 //
5725 // FIXME: Some simple tests here could identify macro definitions and
5726 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005727
5728 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005729 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5730 break;
5731
Craig Topper69186e72014-06-08 08:38:04 +00005732 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005733 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005734 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5735 break;
5736
5737 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005738 IdentifierInfo &II =
5739 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005740 SourceLocation MappedTokLoc =
5741 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5742 MI = getMacroInfo(II, MappedTokLoc, TU);
5743 }
5744 }
5745
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005746 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005748 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5749 finished = true;
5750 break;
5751 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005752 // If we are in a macro definition, check if the token was ever a
5753 // macro name and annotate it if that's the case.
5754 if (MI) {
5755 SourceLocation SaveLoc = Tok.getLocation();
5756 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5757 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5758 Tok.setLocation(SaveLoc);
5759 if (MacroDef)
5760 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5761 Tok.getLocation(), TU);
5762 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005763 } while (!Tok.isAtStartOfLine());
5764
5765 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5766 assert(TokIdx <= LastIdx);
5767 SourceLocation EndLoc =
5768 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5769 CXCursor Cursor =
5770 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5771
5772 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005773 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005774
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005775 if (finished)
5776 break;
5777 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005779 }
5780}
5781
5782// This gets run a separate thread to avoid stack blowout.
5783static void clang_annotateTokensImpl(void *UserData) {
5784 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5785 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5786 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5787 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5788 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5789
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005790 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005791 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5792 setThreadBackgroundPriority();
5793
5794 // Determine the region of interest, which contains all of the tokens.
5795 SourceRange RegionOfInterest;
5796 RegionOfInterest.setBegin(
5797 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5798 RegionOfInterest.setEnd(
5799 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5800 Tokens[NumTokens-1])));
5801
Guy Benyei11169dd2012-12-18 14:30:41 +00005802 // Relex the tokens within the source range to look for preprocessing
5803 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005804 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005805
5806 // If begin location points inside a macro argument, set it to the expansion
5807 // location so we can have the full context when annotating semantically.
5808 {
5809 SourceManager &SM = CXXUnit->getSourceManager();
5810 SourceLocation Loc =
5811 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5812 if (Loc.isMacroID())
5813 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5814 }
5815
Guy Benyei11169dd2012-12-18 14:30:41 +00005816 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5817 // Search and mark tokens that are macro argument expansions.
5818 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5819 Tokens, NumTokens);
5820 CursorVisitor MacroArgMarker(TU,
5821 MarkMacroArgTokensVisitorDelegate, &Visitor,
5822 /*VisitPreprocessorLast=*/true,
5823 /*VisitIncludedEntities=*/false,
5824 RegionOfInterest);
5825 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5826 }
5827
5828 // Annotate all of the source locations in the region of interest that map to
5829 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005830 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005831
5832 // FIXME: We use a ridiculous stack size here because the data-recursion
5833 // algorithm uses a large stack frame than the non-data recursive version,
5834 // and AnnotationTokensWorker currently transforms the data-recursion
5835 // algorithm back into a traditional recursion by explicitly calling
5836 // VisitChildren(). We will need to remove this explicit recursive call.
5837 W.AnnotateTokens();
5838
5839 // If we ran into any entities that involve context-sensitive keywords,
5840 // take another pass through the tokens to mark them as such.
5841 if (W.hasContextSensitiveKeywords()) {
5842 for (unsigned I = 0; I != NumTokens; ++I) {
5843 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5844 continue;
5845
5846 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5847 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005848 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005849 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5850 if (Property->getPropertyAttributesAsWritten() != 0 &&
5851 llvm::StringSwitch<bool>(II->getName())
5852 .Case("readonly", true)
5853 .Case("assign", true)
5854 .Case("unsafe_unretained", true)
5855 .Case("readwrite", true)
5856 .Case("retain", true)
5857 .Case("copy", true)
5858 .Case("nonatomic", true)
5859 .Case("atomic", true)
5860 .Case("getter", true)
5861 .Case("setter", true)
5862 .Case("strong", true)
5863 .Case("weak", true)
5864 .Default(false))
5865 Tokens[I].int_data[0] = CXToken_Keyword;
5866 }
5867 continue;
5868 }
5869
5870 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5871 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5872 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5873 if (llvm::StringSwitch<bool>(II->getName())
5874 .Case("in", true)
5875 .Case("out", true)
5876 .Case("inout", true)
5877 .Case("oneway", true)
5878 .Case("bycopy", true)
5879 .Case("byref", true)
5880 .Default(false))
5881 Tokens[I].int_data[0] = CXToken_Keyword;
5882 continue;
5883 }
5884
5885 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5886 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5887 Tokens[I].int_data[0] = CXToken_Keyword;
5888 continue;
5889 }
5890 }
5891 }
5892}
5893
5894extern "C" {
5895
5896void clang_annotateTokens(CXTranslationUnit TU,
5897 CXToken *Tokens, unsigned NumTokens,
5898 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005899 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005900 LOG_BAD_TU(TU);
5901 return;
5902 }
5903 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005904 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005905 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005906 }
5907
5908 LOG_FUNC_SECTION {
5909 *Log << TU << ' ';
5910 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5911 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5912 *Log << clang_getRange(bloc, eloc);
5913 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005914
5915 // Any token we don't specifically annotate will have a NULL cursor.
5916 CXCursor C = clang_getNullCursor();
5917 for (unsigned I = 0; I != NumTokens; ++I)
5918 Cursors[I] = C;
5919
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005920 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005921 if (!CXXUnit)
5922 return;
5923
5924 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5925
5926 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5927 llvm::CrashRecoveryContext CRC;
5928 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5929 GetSafetyThreadStackSize() * 2)) {
5930 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5931 }
5932}
5933
5934} // end: extern "C"
5935
5936//===----------------------------------------------------------------------===//
5937// Operations for querying linkage of a cursor.
5938//===----------------------------------------------------------------------===//
5939
5940extern "C" {
5941CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5942 if (!clang_isDeclaration(cursor.kind))
5943 return CXLinkage_Invalid;
5944
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005945 const Decl *D = cxcursor::getCursorDecl(cursor);
5946 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005947 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005948 case NoLinkage:
5949 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005950 case InternalLinkage: return CXLinkage_Internal;
5951 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5952 case ExternalLinkage: return CXLinkage_External;
5953 };
5954
5955 return CXLinkage_Invalid;
5956}
5957} // end: extern "C"
5958
5959//===----------------------------------------------------------------------===//
5960// Operations for querying language of a cursor.
5961//===----------------------------------------------------------------------===//
5962
5963static CXLanguageKind getDeclLanguage(const Decl *D) {
5964 if (!D)
5965 return CXLanguage_C;
5966
5967 switch (D->getKind()) {
5968 default:
5969 break;
5970 case Decl::ImplicitParam:
5971 case Decl::ObjCAtDefsField:
5972 case Decl::ObjCCategory:
5973 case Decl::ObjCCategoryImpl:
5974 case Decl::ObjCCompatibleAlias:
5975 case Decl::ObjCImplementation:
5976 case Decl::ObjCInterface:
5977 case Decl::ObjCIvar:
5978 case Decl::ObjCMethod:
5979 case Decl::ObjCProperty:
5980 case Decl::ObjCPropertyImpl:
5981 case Decl::ObjCProtocol:
5982 return CXLanguage_ObjC;
5983 case Decl::CXXConstructor:
5984 case Decl::CXXConversion:
5985 case Decl::CXXDestructor:
5986 case Decl::CXXMethod:
5987 case Decl::CXXRecord:
5988 case Decl::ClassTemplate:
5989 case Decl::ClassTemplatePartialSpecialization:
5990 case Decl::ClassTemplateSpecialization:
5991 case Decl::Friend:
5992 case Decl::FriendTemplate:
5993 case Decl::FunctionTemplate:
5994 case Decl::LinkageSpec:
5995 case Decl::Namespace:
5996 case Decl::NamespaceAlias:
5997 case Decl::NonTypeTemplateParm:
5998 case Decl::StaticAssert:
5999 case Decl::TemplateTemplateParm:
6000 case Decl::TemplateTypeParm:
6001 case Decl::UnresolvedUsingTypename:
6002 case Decl::UnresolvedUsingValue:
6003 case Decl::Using:
6004 case Decl::UsingDirective:
6005 case Decl::UsingShadow:
6006 return CXLanguage_CPlusPlus;
6007 }
6008
6009 return CXLanguage_C;
6010}
6011
6012extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006013
6014static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6015 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6016 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006017
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006018 switch (D->getAvailability()) {
6019 case AR_Available:
6020 case AR_NotYetIntroduced:
6021 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006022 return getCursorAvailabilityForDecl(
6023 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006024 return CXAvailability_Available;
6025
6026 case AR_Deprecated:
6027 return CXAvailability_Deprecated;
6028
6029 case AR_Unavailable:
6030 return CXAvailability_NotAvailable;
6031 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006032
6033 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006034}
6035
Guy Benyei11169dd2012-12-18 14:30:41 +00006036enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6037 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006038 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6039 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006040
6041 return CXAvailability_Available;
6042}
6043
6044static CXVersion convertVersion(VersionTuple In) {
6045 CXVersion Out = { -1, -1, -1 };
6046 if (In.empty())
6047 return Out;
6048
6049 Out.Major = In.getMajor();
6050
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006051 Optional<unsigned> Minor = In.getMinor();
6052 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006053 Out.Minor = *Minor;
6054 else
6055 return Out;
6056
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006057 Optional<unsigned> Subminor = In.getSubminor();
6058 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006059 Out.Subminor = *Subminor;
6060
6061 return Out;
6062}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006063
6064static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6065 int *always_deprecated,
6066 CXString *deprecated_message,
6067 int *always_unavailable,
6068 CXString *unavailable_message,
6069 CXPlatformAvailability *availability,
6070 int availability_size) {
6071 bool HadAvailAttr = false;
6072 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006073 for (auto A : D->attrs()) {
6074 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006075 HadAvailAttr = true;
6076 if (always_deprecated)
6077 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006078 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006079 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006080 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006081 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006082 continue;
6083 }
6084
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006085 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006086 HadAvailAttr = true;
6087 if (always_unavailable)
6088 *always_unavailable = 1;
6089 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006090 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006091 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6092 }
6093 continue;
6094 }
6095
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006096 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006097 HadAvailAttr = true;
6098 if (N < availability_size) {
6099 availability[N].Platform
6100 = cxstring::createDup(Avail->getPlatform()->getName());
6101 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6102 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6103 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6104 availability[N].Unavailable = Avail->getUnavailable();
6105 availability[N].Message = cxstring::createDup(Avail->getMessage());
6106 }
6107 ++N;
6108 }
6109 }
6110
6111 if (!HadAvailAttr)
6112 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6113 return getCursorPlatformAvailabilityForDecl(
6114 cast<Decl>(EnumConst->getDeclContext()),
6115 always_deprecated,
6116 deprecated_message,
6117 always_unavailable,
6118 unavailable_message,
6119 availability,
6120 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006121
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006122 return N;
6123}
6124
Guy Benyei11169dd2012-12-18 14:30:41 +00006125int clang_getCursorPlatformAvailability(CXCursor cursor,
6126 int *always_deprecated,
6127 CXString *deprecated_message,
6128 int *always_unavailable,
6129 CXString *unavailable_message,
6130 CXPlatformAvailability *availability,
6131 int availability_size) {
6132 if (always_deprecated)
6133 *always_deprecated = 0;
6134 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006135 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006136 if (always_unavailable)
6137 *always_unavailable = 0;
6138 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006139 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006140
Guy Benyei11169dd2012-12-18 14:30:41 +00006141 if (!clang_isDeclaration(cursor.kind))
6142 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006143
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006144 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 if (!D)
6146 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006147
6148 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6149 deprecated_message,
6150 always_unavailable,
6151 unavailable_message,
6152 availability,
6153 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006154}
6155
6156void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6157 clang_disposeString(availability->Platform);
6158 clang_disposeString(availability->Message);
6159}
6160
6161CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6162 if (clang_isDeclaration(cursor.kind))
6163 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6164
6165 return CXLanguage_Invalid;
6166}
6167
6168 /// \brief If the given cursor is the "templated" declaration
6169 /// descibing a class or function template, return the class or
6170 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006171static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006172 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006173 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006174
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006175 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6177 return FunTmpl;
6178
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006179 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006180 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6181 return ClassTmpl;
6182
6183 return D;
6184}
6185
6186CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6187 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006188 if (const Decl *D = getCursorDecl(cursor)) {
6189 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 if (!DC)
6191 return clang_getNullCursor();
6192
6193 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6194 getCursorTU(cursor));
6195 }
6196 }
6197
6198 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006199 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006200 return MakeCXCursor(D, getCursorTU(cursor));
6201 }
6202
6203 return clang_getNullCursor();
6204}
6205
6206CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6207 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006208 if (const Decl *D = getCursorDecl(cursor)) {
6209 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006210 if (!DC)
6211 return clang_getNullCursor();
6212
6213 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6214 getCursorTU(cursor));
6215 }
6216 }
6217
6218 // FIXME: Note that we can't easily compute the lexical context of a
6219 // statement or expression, so we return nothing.
6220 return clang_getNullCursor();
6221}
6222
6223CXFile clang_getIncludedFile(CXCursor cursor) {
6224 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006225 return nullptr;
6226
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006227 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006228 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006229}
6230
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006231unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6232 if (C.kind != CXCursor_ObjCPropertyDecl)
6233 return CXObjCPropertyAttr_noattr;
6234
6235 unsigned Result = CXObjCPropertyAttr_noattr;
6236 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6237 ObjCPropertyDecl::PropertyAttributeKind Attr =
6238 PD->getPropertyAttributesAsWritten();
6239
6240#define SET_CXOBJCPROP_ATTR(A) \
6241 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6242 Result |= CXObjCPropertyAttr_##A
6243 SET_CXOBJCPROP_ATTR(readonly);
6244 SET_CXOBJCPROP_ATTR(getter);
6245 SET_CXOBJCPROP_ATTR(assign);
6246 SET_CXOBJCPROP_ATTR(readwrite);
6247 SET_CXOBJCPROP_ATTR(retain);
6248 SET_CXOBJCPROP_ATTR(copy);
6249 SET_CXOBJCPROP_ATTR(nonatomic);
6250 SET_CXOBJCPROP_ATTR(setter);
6251 SET_CXOBJCPROP_ATTR(atomic);
6252 SET_CXOBJCPROP_ATTR(weak);
6253 SET_CXOBJCPROP_ATTR(strong);
6254 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6255#undef SET_CXOBJCPROP_ATTR
6256
6257 return Result;
6258}
6259
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006260unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6261 if (!clang_isDeclaration(C.kind))
6262 return CXObjCDeclQualifier_None;
6263
6264 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6265 const Decl *D = getCursorDecl(C);
6266 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6267 QT = MD->getObjCDeclQualifier();
6268 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6269 QT = PD->getObjCDeclQualifier();
6270 if (QT == Decl::OBJC_TQ_None)
6271 return CXObjCDeclQualifier_None;
6272
6273 unsigned Result = CXObjCDeclQualifier_None;
6274 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6275 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6276 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6277 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6278 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6279 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6280
6281 return Result;
6282}
6283
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006284unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6285 if (!clang_isDeclaration(C.kind))
6286 return 0;
6287
6288 const Decl *D = getCursorDecl(C);
6289 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6290 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6291 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6292 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6293
6294 return 0;
6295}
6296
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006297unsigned clang_Cursor_isVariadic(CXCursor C) {
6298 if (!clang_isDeclaration(C.kind))
6299 return 0;
6300
6301 const Decl *D = getCursorDecl(C);
6302 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6303 return FD->isVariadic();
6304 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6305 return MD->isVariadic();
6306
6307 return 0;
6308}
6309
Guy Benyei11169dd2012-12-18 14:30:41 +00006310CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6311 if (!clang_isDeclaration(C.kind))
6312 return clang_getNullRange();
6313
6314 const Decl *D = getCursorDecl(C);
6315 ASTContext &Context = getCursorContext(C);
6316 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6317 if (!RC)
6318 return clang_getNullRange();
6319
6320 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6321}
6322
6323CXString clang_Cursor_getRawCommentText(CXCursor C) {
6324 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006325 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006326
6327 const Decl *D = getCursorDecl(C);
6328 ASTContext &Context = getCursorContext(C);
6329 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6330 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6331 StringRef();
6332
6333 // Don't duplicate the string because RawText points directly into source
6334 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006335 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006336}
6337
6338CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6339 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006340 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006341
6342 const Decl *D = getCursorDecl(C);
6343 const ASTContext &Context = getCursorContext(C);
6344 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6345
6346 if (RC) {
6347 StringRef BriefText = RC->getBriefText(Context);
6348
6349 // Don't duplicate the string because RawComment ensures that this memory
6350 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006351 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006352 }
6353
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006354 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006355}
6356
Guy Benyei11169dd2012-12-18 14:30:41 +00006357CXModule clang_Cursor_getModule(CXCursor C) {
6358 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006359 if (const ImportDecl *ImportD =
6360 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006361 return ImportD->getImportedModule();
6362 }
6363
Craig Topper69186e72014-06-08 08:38:04 +00006364 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006365}
6366
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006367CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6368 if (isNotUsableTU(TU)) {
6369 LOG_BAD_TU(TU);
6370 return nullptr;
6371 }
6372 if (!File)
6373 return nullptr;
6374 FileEntry *FE = static_cast<FileEntry *>(File);
6375
6376 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6377 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6378 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6379
6380 if (Module *Mod = Header.getModule()) {
6381 if (Header.getRole() != ModuleMap::ExcludedHeader)
6382 return Mod;
6383 }
6384 return nullptr;
6385}
6386
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006387CXFile clang_Module_getASTFile(CXModule CXMod) {
6388 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006389 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006390 Module *Mod = static_cast<Module*>(CXMod);
6391 return const_cast<FileEntry *>(Mod->getASTFile());
6392}
6393
Guy Benyei11169dd2012-12-18 14:30:41 +00006394CXModule clang_Module_getParent(CXModule CXMod) {
6395 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006396 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006397 Module *Mod = static_cast<Module*>(CXMod);
6398 return Mod->Parent;
6399}
6400
6401CXString clang_Module_getName(CXModule CXMod) {
6402 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006403 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006404 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006405 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006406}
6407
6408CXString clang_Module_getFullName(CXModule CXMod) {
6409 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006410 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006411 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006412 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006413}
6414
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006415int clang_Module_isSystem(CXModule CXMod) {
6416 if (!CXMod)
6417 return 0;
6418 Module *Mod = static_cast<Module*>(CXMod);
6419 return Mod->IsSystem;
6420}
6421
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006422unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6423 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006424 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006425 LOG_BAD_TU(TU);
6426 return 0;
6427 }
6428 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006429 return 0;
6430 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006431 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6432 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6433 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006434}
6435
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006436CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6437 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006438 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006439 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006440 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006441 }
6442 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006443 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006444 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006445 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006446
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006447 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6448 if (Index < TopHeaders.size())
6449 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006450
Craig Topper69186e72014-06-08 08:38:04 +00006451 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006452}
6453
6454} // end: extern "C"
6455
6456//===----------------------------------------------------------------------===//
6457// C++ AST instrospection.
6458//===----------------------------------------------------------------------===//
6459
6460extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006461unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6462 if (!clang_isDeclaration(C.kind))
6463 return 0;
6464
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006465 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006466 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006467 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006468 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6469}
6470
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006471unsigned clang_CXXMethod_isConst(CXCursor C) {
6472 if (!clang_isDeclaration(C.kind))
6473 return 0;
6474
6475 const Decl *D = cxcursor::getCursorDecl(C);
6476 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006477 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006478 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6479}
6480
Guy Benyei11169dd2012-12-18 14:30:41 +00006481unsigned clang_CXXMethod_isStatic(CXCursor C) {
6482 if (!clang_isDeclaration(C.kind))
6483 return 0;
6484
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006485 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006486 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006487 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006488 return (Method && Method->isStatic()) ? 1 : 0;
6489}
6490
6491unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6492 if (!clang_isDeclaration(C.kind))
6493 return 0;
6494
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006495 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006496 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006497 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006498 return (Method && Method->isVirtual()) ? 1 : 0;
6499}
6500} // end: extern "C"
6501
6502//===----------------------------------------------------------------------===//
6503// Attribute introspection.
6504//===----------------------------------------------------------------------===//
6505
6506extern "C" {
6507CXType clang_getIBOutletCollectionType(CXCursor C) {
6508 if (C.kind != CXCursor_IBOutletCollectionAttr)
6509 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6510
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006511 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006512 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6513
6514 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6515}
6516} // end: extern "C"
6517
6518//===----------------------------------------------------------------------===//
6519// Inspecting memory usage.
6520//===----------------------------------------------------------------------===//
6521
6522typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6523
6524static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6525 enum CXTUResourceUsageKind k,
6526 unsigned long amount) {
6527 CXTUResourceUsageEntry entry = { k, amount };
6528 entries.push_back(entry);
6529}
6530
6531extern "C" {
6532
6533const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6534 const char *str = "";
6535 switch (kind) {
6536 case CXTUResourceUsage_AST:
6537 str = "ASTContext: expressions, declarations, and types";
6538 break;
6539 case CXTUResourceUsage_Identifiers:
6540 str = "ASTContext: identifiers";
6541 break;
6542 case CXTUResourceUsage_Selectors:
6543 str = "ASTContext: selectors";
6544 break;
6545 case CXTUResourceUsage_GlobalCompletionResults:
6546 str = "Code completion: cached global results";
6547 break;
6548 case CXTUResourceUsage_SourceManagerContentCache:
6549 str = "SourceManager: content cache allocator";
6550 break;
6551 case CXTUResourceUsage_AST_SideTables:
6552 str = "ASTContext: side tables";
6553 break;
6554 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6555 str = "SourceManager: malloc'ed memory buffers";
6556 break;
6557 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6558 str = "SourceManager: mmap'ed memory buffers";
6559 break;
6560 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6561 str = "ExternalASTSource: malloc'ed memory buffers";
6562 break;
6563 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6564 str = "ExternalASTSource: mmap'ed memory buffers";
6565 break;
6566 case CXTUResourceUsage_Preprocessor:
6567 str = "Preprocessor: malloc'ed memory";
6568 break;
6569 case CXTUResourceUsage_PreprocessingRecord:
6570 str = "Preprocessor: PreprocessingRecord";
6571 break;
6572 case CXTUResourceUsage_SourceManager_DataStructures:
6573 str = "SourceManager: data structures and tables";
6574 break;
6575 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6576 str = "Preprocessor: header search tables";
6577 break;
6578 }
6579 return str;
6580}
6581
6582CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006583 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006584 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006585 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006586 return usage;
6587 }
6588
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006589 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006590 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006591 ASTContext &astContext = astUnit->getASTContext();
6592
6593 // How much memory is used by AST nodes and types?
6594 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6595 (unsigned long) astContext.getASTAllocatedMemory());
6596
6597 // How much memory is used by identifiers?
6598 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6599 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6600
6601 // How much memory is used for selectors?
6602 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6603 (unsigned long) astContext.Selectors.getTotalMemory());
6604
6605 // How much memory is used by ASTContext's side tables?
6606 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6607 (unsigned long) astContext.getSideTableAllocatedMemory());
6608
6609 // How much memory is used for caching global code completion results?
6610 unsigned long completionBytes = 0;
6611 if (GlobalCodeCompletionAllocator *completionAllocator =
6612 astUnit->getCachedCompletionAllocator().getPtr()) {
6613 completionBytes = completionAllocator->getTotalMemory();
6614 }
6615 createCXTUResourceUsageEntry(*entries,
6616 CXTUResourceUsage_GlobalCompletionResults,
6617 completionBytes);
6618
6619 // How much memory is being used by SourceManager's content cache?
6620 createCXTUResourceUsageEntry(*entries,
6621 CXTUResourceUsage_SourceManagerContentCache,
6622 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6623
6624 // How much memory is being used by the MemoryBuffer's in SourceManager?
6625 const SourceManager::MemoryBufferSizes &srcBufs =
6626 astUnit->getSourceManager().getMemoryBufferSizes();
6627
6628 createCXTUResourceUsageEntry(*entries,
6629 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6630 (unsigned long) srcBufs.malloc_bytes);
6631 createCXTUResourceUsageEntry(*entries,
6632 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6633 (unsigned long) srcBufs.mmap_bytes);
6634 createCXTUResourceUsageEntry(*entries,
6635 CXTUResourceUsage_SourceManager_DataStructures,
6636 (unsigned long) astContext.getSourceManager()
6637 .getDataStructureSizes());
6638
6639 // How much memory is being used by the ExternalASTSource?
6640 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6641 const ExternalASTSource::MemoryBufferSizes &sizes =
6642 esrc->getMemoryBufferSizes();
6643
6644 createCXTUResourceUsageEntry(*entries,
6645 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6646 (unsigned long) sizes.malloc_bytes);
6647 createCXTUResourceUsageEntry(*entries,
6648 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6649 (unsigned long) sizes.mmap_bytes);
6650 }
6651
6652 // How much memory is being used by the Preprocessor?
6653 Preprocessor &pp = astUnit->getPreprocessor();
6654 createCXTUResourceUsageEntry(*entries,
6655 CXTUResourceUsage_Preprocessor,
6656 pp.getTotalMemory());
6657
6658 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6659 createCXTUResourceUsageEntry(*entries,
6660 CXTUResourceUsage_PreprocessingRecord,
6661 pRec->getTotalMemory());
6662 }
6663
6664 createCXTUResourceUsageEntry(*entries,
6665 CXTUResourceUsage_Preprocessor_HeaderSearch,
6666 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006667
Guy Benyei11169dd2012-12-18 14:30:41 +00006668 CXTUResourceUsage usage = { (void*) entries.get(),
6669 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006670 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006671 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006672 return usage;
6673}
6674
6675void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6676 if (usage.data)
6677 delete (MemUsageEntries*) usage.data;
6678}
6679
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006680CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6681 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006682 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006683 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006684
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006685 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006686 LOG_BAD_TU(TU);
6687 return skipped;
6688 }
6689
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006690 if (!file)
6691 return skipped;
6692
6693 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6694 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6695 if (!ppRec)
6696 return skipped;
6697
6698 ASTContext &Ctx = astUnit->getASTContext();
6699 SourceManager &sm = Ctx.getSourceManager();
6700 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6701 FileID wantedFileID = sm.translateFile(fileEntry);
6702
6703 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6704 std::vector<SourceRange> wantedRanges;
6705 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6706 i != ei; ++i) {
6707 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6708 wantedRanges.push_back(*i);
6709 }
6710
6711 skipped->count = wantedRanges.size();
6712 skipped->ranges = new CXSourceRange[skipped->count];
6713 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6714 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6715
6716 return skipped;
6717}
6718
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006719void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6720 if (ranges) {
6721 delete[] ranges->ranges;
6722 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006723 }
6724}
6725
Guy Benyei11169dd2012-12-18 14:30:41 +00006726} // end extern "C"
6727
6728void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6729 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6730 for (unsigned I = 0; I != Usage.numEntries; ++I)
6731 fprintf(stderr, " %s: %lu\n",
6732 clang_getTUResourceUsageName(Usage.entries[I].kind),
6733 Usage.entries[I].amount);
6734
6735 clang_disposeCXTUResourceUsage(Usage);
6736}
6737
6738//===----------------------------------------------------------------------===//
6739// Misc. utility functions.
6740//===----------------------------------------------------------------------===//
6741
6742/// Default to using an 8 MB stack size on "safety" threads.
6743static unsigned SafetyStackThreadSize = 8 << 20;
6744
6745namespace clang {
6746
6747bool RunSafely(llvm::CrashRecoveryContext &CRC,
6748 void (*Fn)(void*), void *UserData,
6749 unsigned Size) {
6750 if (!Size)
6751 Size = GetSafetyThreadStackSize();
6752 if (Size)
6753 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6754 return CRC.RunSafely(Fn, UserData);
6755}
6756
6757unsigned GetSafetyThreadStackSize() {
6758 return SafetyStackThreadSize;
6759}
6760
6761void SetSafetyThreadStackSize(unsigned Value) {
6762 SafetyStackThreadSize = Value;
6763}
6764
6765}
6766
6767void clang::setThreadBackgroundPriority() {
6768 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6769 return;
6770
6771 // FIXME: Move to llvm/Support and make it cross-platform.
6772#ifdef __APPLE__
6773 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6774#endif
6775}
6776
6777void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6778 if (!Unit)
6779 return;
6780
6781 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6782 DEnd = Unit->stored_diag_end();
6783 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006784 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006785 CXString Msg = clang_formatDiagnostic(&Diag,
6786 clang_defaultDiagnosticDisplayOptions());
6787 fprintf(stderr, "%s\n", clang_getCString(Msg));
6788 clang_disposeString(Msg);
6789 }
6790#ifdef LLVM_ON_WIN32
6791 // On Windows, force a flush, since there may be multiple copies of
6792 // stderr and stdout in the file system, all with different buffers
6793 // but writing to the same device.
6794 fflush(stderr);
6795#endif
6796}
6797
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006798MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6799 SourceLocation MacroDefLoc,
6800 CXTranslationUnit TU){
6801 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006802 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006803 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006804 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006805
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006806 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006807 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006808 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006809 if (MD) {
6810 for (MacroDirective::DefInfo
6811 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6812 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6813 return Def.getMacroInfo();
6814 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006815 }
6816
Craig Topper69186e72014-06-08 08:38:04 +00006817 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006818}
6819
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006820const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6821 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006822 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006823 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006824 const IdentifierInfo *II = MacroDef->getName();
6825 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006826 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006827
6828 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6829}
6830
6831MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6832 const Token &Tok,
6833 CXTranslationUnit TU) {
6834 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006835 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006836 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006837 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006838
6839 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006840 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006841 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6842 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006843 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006844
6845 // Check that the token is inside the definition and not its argument list.
6846 SourceManager &SM = Unit->getSourceManager();
6847 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006848 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006849 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006850 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006851
6852 Preprocessor &PP = Unit->getPreprocessor();
6853 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6854 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006855 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006856
Alp Toker2d57cea2014-05-17 04:53:25 +00006857 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006858 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006859 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006860
6861 // Check that the identifier is not one of the macro arguments.
6862 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006863 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006864
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006865 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6866 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006867 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006868
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006869 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006870}
6871
6872MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6873 SourceLocation Loc,
6874 CXTranslationUnit TU) {
6875 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006876 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006877
6878 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006879 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006880 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006881 Preprocessor &PP = Unit->getPreprocessor();
6882 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006883 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006884 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6885 Token Tok;
6886 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006887 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006888
6889 return checkForMacroInMacroDefinition(MI, Tok, TU);
6890}
6891
Guy Benyei11169dd2012-12-18 14:30:41 +00006892extern "C" {
6893
6894CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006895 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006896}
6897
6898} // end: extern "C"
6899
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006900Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6901 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006902 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006903 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006904 if (Unit->isMainFileAST())
6905 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006906 return *this;
6907 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006908 } else {
6909 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006910 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006911 return *this;
6912}
6913
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006914Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6915 *this << FE->getName();
6916 return *this;
6917}
6918
6919Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6920 CXString cursorName = clang_getCursorDisplayName(cursor);
6921 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6922 clang_disposeString(cursorName);
6923 return *this;
6924}
6925
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006926Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6927 CXFile File;
6928 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006929 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006930 CXString FileName = clang_getFileName(File);
6931 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6932 clang_disposeString(FileName);
6933 return *this;
6934}
6935
6936Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6937 CXSourceLocation BLoc = clang_getRangeStart(range);
6938 CXSourceLocation ELoc = clang_getRangeEnd(range);
6939
6940 CXFile BFile;
6941 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006942 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006943
6944 CXFile EFile;
6945 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006946 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006947
6948 CXString BFileName = clang_getFileName(BFile);
6949 if (BFile == EFile) {
6950 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6951 BLine, BColumn, ELine, EColumn);
6952 } else {
6953 CXString EFileName = clang_getFileName(EFile);
6954 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6955 BLine, BColumn)
6956 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6957 ELine, EColumn);
6958 clang_disposeString(EFileName);
6959 }
6960 clang_disposeString(BFileName);
6961 return *this;
6962}
6963
6964Logger &cxindex::Logger::operator<<(CXString Str) {
6965 *this << clang_getCString(Str);
6966 return *this;
6967}
6968
6969Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6970 LogOS << Fmt;
6971 return *this;
6972}
6973
6974cxindex::Logger::~Logger() {
6975 LogOS.flush();
6976
Zachary Turnerf68823b2014-06-17 19:57:15 +00006977 llvm::sys::ScopedLock L(LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006978
6979 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6980
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006981 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006982 OS << "[libclang:" << Name << ':';
6983
6984 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00006985#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006986 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6987 OS << tid << ':';
6988#endif
6989
6990 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6991 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6992 OS << Msg.str() << '\n';
6993
6994 if (Trace) {
6995 llvm::sys::PrintStackTrace(stderr);
6996 OS << "--------------------------------------------------\n";
6997 }
6998}