blob: 0958634a2845fcf4461bb5c04c1435015a6b6d88 [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 Bataev756c1962013-09-24 03:17:45 +00001952template<typename T>
1953void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001954 for (const auto *I : Node->varlists())
1955 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001956}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001957
1958void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001959 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001960}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001961void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1962 const OMPFirstprivateClause *C) {
1963 VisitOMPClauseList(C);
1964}
Alexander Musman1bb328c2014-06-04 13:06:39 +00001965void OMPClauseEnqueue::VisitOMPLastprivateClause(
1966 const OMPLastprivateClause *C) {
1967 VisitOMPClauseList(C);
1968}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001969void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001970 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001971}
Alexey Bataevc5e02582014-06-16 07:08:35 +00001972void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
1973 VisitOMPClauseList(C);
1974}
Alexander Musman8dba6642014-04-22 13:09:42 +00001975void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1976 VisitOMPClauseList(C);
1977 Visitor->AddStmt(C->getStep());
1978}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001979void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1980 VisitOMPClauseList(C);
1981 Visitor->AddStmt(C->getAlignment());
1982}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001983void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1984 VisitOMPClauseList(C);
1985}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001986}
Alexey Bataev756c1962013-09-24 03:17:45 +00001987
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001988void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1989 unsigned size = WL.size();
1990 OMPClauseEnqueue Visitor(this);
1991 Visitor.Visit(S);
1992 if (size == WL.size())
1993 return;
1994 // Now reverse the entries we just added. This will match the DFS
1995 // ordering performed by the worklist.
1996 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1997 std::reverse(I, E);
1998}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001999void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002000 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2001}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002002void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002003 AddDecl(B->getBlockDecl());
2004}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002005void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002006 EnqueueChildren(E);
2007 AddTypeLoc(E->getTypeSourceInfo());
2008}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002009void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2010 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002011 E = S->body_rend(); I != E; ++I) {
2012 AddStmt(*I);
2013 }
2014}
2015void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002016VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002017 AddStmt(S->getSubStmt());
2018 AddDeclarationNameInfo(S);
2019 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2020 AddNestedNameSpecifierLoc(QualifierLoc);
2021}
2022
2023void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002024VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002025 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2026 AddDeclarationNameInfo(E);
2027 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2028 AddNestedNameSpecifierLoc(QualifierLoc);
2029 if (!E->isImplicitAccess())
2030 AddStmt(E->getBase());
2031}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002032void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002033 // Enqueue the initializer , if any.
2034 AddStmt(E->getInitializer());
2035 // Enqueue the array size, if any.
2036 AddStmt(E->getArraySize());
2037 // Enqueue the allocated type.
2038 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2039 // Enqueue the placement arguments.
2040 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2041 AddStmt(E->getPlacementArg(I-1));
2042}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002043void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002044 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2045 AddStmt(CE->getArg(I-1));
2046 AddStmt(CE->getCallee());
2047 AddStmt(CE->getArg(0));
2048}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2050 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002051 // Visit the name of the type being destroyed.
2052 AddTypeLoc(E->getDestroyedTypeInfo());
2053 // Visit the scope type that looks disturbingly like the nested-name-specifier
2054 // but isn't.
2055 AddTypeLoc(E->getScopeTypeInfo());
2056 // Visit the nested-name-specifier.
2057 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2058 AddNestedNameSpecifierLoc(QualifierLoc);
2059 // Visit base expression.
2060 AddStmt(E->getBase());
2061}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2063 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002064 AddTypeLoc(E->getTypeSourceInfo());
2065}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2067 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 EnqueueChildren(E);
2069 AddTypeLoc(E->getTypeSourceInfo());
2070}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002071void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002072 EnqueueChildren(E);
2073 if (E->isTypeOperand())
2074 AddTypeLoc(E->getTypeOperandSourceInfo());
2075}
2076
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2078 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002079 EnqueueChildren(E);
2080 AddTypeLoc(E->getTypeSourceInfo());
2081}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 EnqueueChildren(E);
2084 if (E->isTypeOperand())
2085 AddTypeLoc(E->getTypeOperandSourceInfo());
2086}
2087
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 EnqueueChildren(S);
2090 AddDecl(S->getExceptionDecl());
2091}
2092
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 if (DR->hasExplicitTemplateArgs()) {
2095 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2096 }
2097 WL.push_back(DeclRefExprParts(DR, Parent));
2098}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2100 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2102 AddDeclarationNameInfo(E);
2103 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2104}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002105void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002106 unsigned size = WL.size();
2107 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002108 for (const auto *D : S->decls()) {
2109 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002110 isFirst = false;
2111 }
2112 if (size == WL.size())
2113 return;
2114 // Now reverse the entries we just added. This will match the DFS
2115 // ordering performed by the worklist.
2116 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2117 std::reverse(I, E);
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002121 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002122 D = E->designators_rbegin(), DEnd = E->designators_rend();
2123 D != DEnd; ++D) {
2124 if (D->isFieldDesignator()) {
2125 if (FieldDecl *Field = D->getField())
2126 AddMemberRef(Field, D->getFieldLoc());
2127 continue;
2128 }
2129 if (D->isArrayDesignator()) {
2130 AddStmt(E->getArrayIndex(*D));
2131 continue;
2132 }
2133 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2134 AddStmt(E->getArrayRangeEnd(*D));
2135 AddStmt(E->getArrayRangeStart(*D));
2136 }
2137}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 EnqueueChildren(E);
2140 AddTypeLoc(E->getTypeInfoAsWritten());
2141}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 AddStmt(FS->getBody());
2144 AddStmt(FS->getInc());
2145 AddStmt(FS->getCond());
2146 AddDecl(FS->getConditionVariable());
2147 AddStmt(FS->getInit());
2148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2151}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 AddStmt(If->getElse());
2154 AddStmt(If->getThen());
2155 AddStmt(If->getCond());
2156 AddDecl(If->getConditionVariable());
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 // We care about the syntactic form of the initializer list, only.
2160 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2161 IE = Syntactic;
2162 EnqueueChildren(IE);
2163}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 WL.push_back(MemberExprParts(M, Parent));
2166
2167 // If the base of the member access expression is an implicit 'this', don't
2168 // visit it.
2169 // FIXME: If we ever want to show these implicit accesses, this will be
2170 // unfortunate. However, clang_getCursor() relies on this behavior.
2171 if (!M->isImplicitAccess())
2172 AddStmt(M->getBase());
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 AddTypeLoc(E->getEncodedTypeSourceInfo());
2176}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002177void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002178 EnqueueChildren(M);
2179 AddTypeLoc(M->getClassReceiverTypeInfo());
2180}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 // Visit the components of the offsetof expression.
2183 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2184 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2185 const OffsetOfNode &Node = E->getComponent(I-1);
2186 switch (Node.getKind()) {
2187 case OffsetOfNode::Array:
2188 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2189 break;
2190 case OffsetOfNode::Field:
2191 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2192 break;
2193 case OffsetOfNode::Identifier:
2194 case OffsetOfNode::Base:
2195 continue;
2196 }
2197 }
2198 // Visit the type into which we're computing the offset.
2199 AddTypeLoc(E->getTypeSourceInfo());
2200}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002201void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002202 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2203 WL.push_back(OverloadExprParts(E, Parent));
2204}
2205void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 EnqueueChildren(E);
2208 if (E->isArgumentType())
2209 AddTypeLoc(E->getArgumentTypeInfo());
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 EnqueueChildren(S);
2213}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 AddStmt(S->getBody());
2216 AddStmt(S->getCond());
2217 AddDecl(S->getConditionVariable());
2218}
2219
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 AddStmt(W->getBody());
2222 AddStmt(W->getCond());
2223 AddDecl(W->getConditionVariable());
2224}
2225
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 for (unsigned I = E->getNumArgs(); I > 0; --I)
2228 AddTypeLoc(E->getArg(I-1));
2229}
2230
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddTypeLoc(E->getQueriedTypeSourceInfo());
2233}
2234
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 EnqueueChildren(E);
2237}
2238
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 VisitOverloadExpr(U);
2241 if (!U->isImplicitAccess())
2242 AddStmt(U->getBase());
2243}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 AddStmt(E->getSubExpr());
2246 AddTypeLoc(E->getWrittenTypeInfo());
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 WL.push_back(SizeOfPackExprParts(E, Parent));
2250}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 // If the opaque value has a source expression, just transparently
2253 // visit that. This is useful for (e.g.) pseudo-object expressions.
2254 if (Expr *SourceExpr = E->getSourceExpr())
2255 return Visit(SourceExpr);
2256}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 AddStmt(E->getBody());
2259 WL.push_back(LambdaExprParts(E, Parent));
2260}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 // Treat the expression like its syntactic form.
2263 Visit(E->getSyntacticForm());
2264}
2265
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002266void EnqueueVisitor::VisitOMPExecutableDirective(
2267 const OMPExecutableDirective *D) {
2268 EnqueueChildren(D);
2269 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2270 E = D->clauses().end();
2271 I != E; ++I)
2272 EnqueueChildren(*I);
2273}
2274
2275void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2276 VisitOMPExecutableDirective(D);
2277}
2278
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002279void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2280 VisitOMPExecutableDirective(D);
2281}
2282
Alexey Bataevf29276e2014-06-18 04:14:57 +00002283void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2284 VisitOMPExecutableDirective(D);
2285}
2286
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002287void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002288 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2289}
2290
2291bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2292 if (RegionOfInterest.isValid()) {
2293 SourceRange Range = getRawCursorExtent(C);
2294 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2295 return false;
2296 }
2297 return true;
2298}
2299
2300bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2301 while (!WL.empty()) {
2302 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002303 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002304
2305 // Set the Parent field, then back to its old value once we're done.
2306 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2307
2308 switch (LI.getKind()) {
2309 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 if (!D)
2312 continue;
2313
2314 // For now, perform default visitation for Decls.
2315 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2316 cast<DeclVisit>(&LI)->isFirst())))
2317 return true;
2318
2319 continue;
2320 }
2321 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2322 const ASTTemplateArgumentListInfo *ArgList =
2323 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2324 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2325 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2326 Arg != ArgEnd; ++Arg) {
2327 if (VisitTemplateArgumentLoc(*Arg))
2328 return true;
2329 }
2330 continue;
2331 }
2332 case VisitorJob::TypeLocVisitKind: {
2333 // Perform default visitation for TypeLocs.
2334 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2335 return true;
2336 continue;
2337 }
2338 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002339 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002340 if (LabelStmt *stmt = LS->getStmt()) {
2341 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2342 TU))) {
2343 return true;
2344 }
2345 }
2346 continue;
2347 }
2348
2349 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2350 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2351 if (VisitNestedNameSpecifierLoc(V->get()))
2352 return true;
2353 continue;
2354 }
2355
2356 case VisitorJob::DeclarationNameInfoVisitKind: {
2357 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2358 ->get()))
2359 return true;
2360 continue;
2361 }
2362 case VisitorJob::MemberRefVisitKind: {
2363 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2364 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2365 return true;
2366 continue;
2367 }
2368 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002369 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002370 if (!S)
2371 continue;
2372
2373 // Update the current cursor.
2374 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2375 if (!IsInRegionOfInterest(Cursor))
2376 continue;
2377 switch (Visitor(Cursor, Parent, ClientData)) {
2378 case CXChildVisit_Break: return true;
2379 case CXChildVisit_Continue: break;
2380 case CXChildVisit_Recurse:
2381 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002382 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002383 EnqueueWorkList(WL, S);
2384 break;
2385 }
2386 continue;
2387 }
2388 case VisitorJob::MemberExprPartsKind: {
2389 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002390 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002391
2392 // Visit the nested-name-specifier
2393 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2394 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2395 return true;
2396
2397 // Visit the declaration name.
2398 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2399 return true;
2400
2401 // Visit the explicitly-specified template arguments, if any.
2402 if (M->hasExplicitTemplateArgs()) {
2403 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2404 *ArgEnd = Arg + M->getNumTemplateArgs();
2405 Arg != ArgEnd; ++Arg) {
2406 if (VisitTemplateArgumentLoc(*Arg))
2407 return true;
2408 }
2409 }
2410 continue;
2411 }
2412 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002414 // Visit nested-name-specifier, if present.
2415 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2416 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2417 return true;
2418 // Visit declaration name.
2419 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2420 return true;
2421 continue;
2422 }
2423 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002424 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002425 // Visit the nested-name-specifier.
2426 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2427 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2428 return true;
2429 // Visit the declaration name.
2430 if (VisitDeclarationNameInfo(O->getNameInfo()))
2431 return true;
2432 // Visit the overloaded declaration reference.
2433 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2434 return true;
2435 continue;
2436 }
2437 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 NamedDecl *Pack = E->getPack();
2440 if (isa<TemplateTypeParmDecl>(Pack)) {
2441 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2442 E->getPackLoc(), TU)))
2443 return true;
2444
2445 continue;
2446 }
2447
2448 if (isa<TemplateTemplateParmDecl>(Pack)) {
2449 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2450 E->getPackLoc(), TU)))
2451 return true;
2452
2453 continue;
2454 }
2455
2456 // Non-type template parameter packs and function parameter packs are
2457 // treated like DeclRefExpr cursors.
2458 continue;
2459 }
2460
2461 case VisitorJob::LambdaExprPartsKind: {
2462 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2465 CEnd = E->explicit_capture_end();
2466 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002467 // FIXME: Lambda init-captures.
2468 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002469 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002470
Guy Benyei11169dd2012-12-18 14:30:41 +00002471 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2472 C->getLocation(),
2473 TU)))
2474 return true;
2475 }
2476
2477 // Visit parameters and return type, if present.
2478 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2479 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2480 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2481 // Visit the whole type.
2482 if (Visit(TL))
2483 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002484 } else if (FunctionProtoTypeLoc Proto =
2485 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002486 if (E->hasExplicitParameters()) {
2487 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002488 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2489 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002490 return true;
2491 } else {
2492 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002493 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002494 return true;
2495 }
2496 }
2497 }
2498 break;
2499 }
2500
2501 case VisitorJob::PostChildrenVisitKind:
2502 if (PostChildrenVisitor(Parent, ClientData))
2503 return true;
2504 break;
2505 }
2506 }
2507 return false;
2508}
2509
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002510bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002511 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002512 if (!WorkListFreeList.empty()) {
2513 WL = WorkListFreeList.back();
2514 WL->clear();
2515 WorkListFreeList.pop_back();
2516 }
2517 else {
2518 WL = new VisitorWorkList();
2519 WorkListCache.push_back(WL);
2520 }
2521 EnqueueWorkList(*WL, S);
2522 bool result = RunVisitorWorkList(*WL);
2523 WorkListFreeList.push_back(WL);
2524 return result;
2525}
2526
2527namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002528typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002529RefNamePieces
2530buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2531 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2532 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002533 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2534 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2535 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2536
2537 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2538
2539 RefNamePieces Pieces;
2540
2541 if (WantQualifier && QLoc.isValid())
2542 Pieces.push_back(QLoc);
2543
2544 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2545 Pieces.push_back(NI.getLoc());
2546
2547 if (WantTemplateArgs && TemplateArgs)
2548 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2549 TemplateArgs->RAngleLoc));
2550
2551 if (Kind == DeclarationName::CXXOperatorName) {
2552 Pieces.push_back(SourceLocation::getFromRawEncoding(
2553 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2554 Pieces.push_back(SourceLocation::getFromRawEncoding(
2555 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2556 }
2557
2558 if (WantSinglePiece) {
2559 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2560 Pieces.clear();
2561 Pieces.push_back(R);
2562 }
2563
2564 return Pieces;
2565}
2566}
2567
2568//===----------------------------------------------------------------------===//
2569// Misc. API hooks.
2570//===----------------------------------------------------------------------===//
2571
Zachary Turnerf68823b2014-06-17 19:57:15 +00002572static llvm::sys::Mutex LoggingMutex;
2573static std::once_flag LibclangGlobalInitFlag;
Guy Benyei11169dd2012-12-18 14:30:41 +00002574
Chad Rosier05c71aa2013-03-27 18:28:23 +00002575static void fatal_error_handler(void *user_data, const std::string& reason,
2576 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002577 // Write the result out to stderr avoiding errs() because raw_ostreams can
2578 // call report_fatal_error.
2579 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2580 ::abort();
2581}
2582
Zachary Turnerf68823b2014-06-17 19:57:15 +00002583static void initializeLibClang() {
Zachary Turnerf68823b2014-06-17 19:57:15 +00002584 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2585}
2586
Guy Benyei11169dd2012-12-18 14:30:41 +00002587extern "C" {
2588CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2589 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002590 // We use crash recovery to make some of our APIs more reliable, implicitly
2591 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002592 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2593 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002594
Zachary Turnerf68823b2014-06-17 19:57:15 +00002595 std::call_once(LibclangGlobalInitFlag, initializeLibClang);
Guy Benyei11169dd2012-12-18 14:30:41 +00002596
2597 CIndexer *CIdxr = new CIndexer();
2598 if (excludeDeclarationsFromPCH)
2599 CIdxr->setOnlyLocalDecls();
2600 if (displayDiagnostics)
2601 CIdxr->setDisplayDiagnostics();
2602
2603 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2604 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2605 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2606 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2607 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2608 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2609
2610 return CIdxr;
2611}
2612
2613void clang_disposeIndex(CXIndex CIdx) {
2614 if (CIdx)
2615 delete static_cast<CIndexer *>(CIdx);
2616}
2617
2618void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2619 if (CIdx)
2620 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2621}
2622
2623unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2624 if (CIdx)
2625 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2626 return 0;
2627}
2628
2629void clang_toggleCrashRecovery(unsigned isEnabled) {
2630 if (isEnabled)
2631 llvm::CrashRecoveryContext::Enable();
2632 else
2633 llvm::CrashRecoveryContext::Disable();
2634}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002635
Guy Benyei11169dd2012-12-18 14:30:41 +00002636CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2637 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002638 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002639 enum CXErrorCode Result =
2640 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002641 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002642 assert((TU && Result == CXError_Success) ||
2643 (!TU && Result != CXError_Success));
2644 return TU;
2645}
2646
2647enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2648 const char *ast_filename,
2649 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002650 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002651 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002652
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002653 if (!CIdx || !ast_filename || !out_TU)
2654 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002655
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002656 LOG_FUNC_SECTION {
2657 *Log << ast_filename;
2658 }
2659
Guy Benyei11169dd2012-12-18 14:30:41 +00002660 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2661 FileSystemOptions FileSystemOpts;
2662
2663 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002664 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002665 CXXIdx->getOnlyLocalDecls(), None,
2666 /*CaptureDiagnostics=*/true,
2667 /*AllowPCHWithCompilerErrors=*/true,
2668 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002669 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2670 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002671}
2672
2673unsigned clang_defaultEditingTranslationUnitOptions() {
2674 return CXTranslationUnit_PrecompiledPreamble |
2675 CXTranslationUnit_CacheCompletionResults;
2676}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002677
Guy Benyei11169dd2012-12-18 14:30:41 +00002678CXTranslationUnit
2679clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2680 const char *source_filename,
2681 int num_command_line_args,
2682 const char * const *command_line_args,
2683 unsigned num_unsaved_files,
2684 struct CXUnsavedFile *unsaved_files) {
2685 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2686 return clang_parseTranslationUnit(CIdx, source_filename,
2687 command_line_args, num_command_line_args,
2688 unsaved_files, num_unsaved_files,
2689 Options);
2690}
2691
2692struct ParseTranslationUnitInfo {
2693 CXIndex CIdx;
2694 const char *source_filename;
2695 const char *const *command_line_args;
2696 int num_command_line_args;
2697 struct CXUnsavedFile *unsaved_files;
2698 unsigned num_unsaved_files;
2699 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002700 CXTranslationUnit *out_TU;
2701 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002702};
2703static void clang_parseTranslationUnit_Impl(void *UserData) {
2704 ParseTranslationUnitInfo *PTUI =
2705 static_cast<ParseTranslationUnitInfo*>(UserData);
2706 CXIndex CIdx = PTUI->CIdx;
2707 const char *source_filename = PTUI->source_filename;
2708 const char * const *command_line_args = PTUI->command_line_args;
2709 int num_command_line_args = PTUI->num_command_line_args;
2710 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2711 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2712 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002713 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002714
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002715 // Set up the initial return values.
2716 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002717 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002718 PTUI->result = CXError_Failure;
2719
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002720 // Check arguments.
2721 if (!CIdx || !out_TU ||
Craig Topper69186e72014-06-08 08:38:04 +00002722 (unsaved_files == nullptr && num_unsaved_files != 0)) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002723 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002724 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002725 }
2726
Guy Benyei11169dd2012-12-18 14:30:41 +00002727 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2728
2729 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2730 setThreadBackgroundPriority();
2731
2732 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2733 // FIXME: Add a flag for modules.
2734 TranslationUnitKind TUKind
2735 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002736 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002737 = options & CXTranslationUnit_CacheCompletionResults;
2738 bool IncludeBriefCommentsInCodeCompletion
2739 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2740 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2741 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2742
2743 // Configure the diagnostics.
2744 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002745 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002746
2747 // Recover resources if we crash before exiting this function.
2748 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2749 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2750 DiagCleanup(Diags.getPtr());
2751
Ahmed Charlesb8984322014-03-07 20:03:18 +00002752 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2753 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002754
2755 // Recover resources if we crash before exiting this function.
2756 llvm::CrashRecoveryContextCleanupRegistrar<
2757 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2758
2759 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2760 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2761 const llvm::MemoryBuffer *Buffer
2762 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2763 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2764 Buffer));
2765 }
2766
Ahmed Charlesb8984322014-03-07 20:03:18 +00002767 std::unique_ptr<std::vector<const char *>> Args(
2768 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002769
2770 // Recover resources if we crash before exiting this method.
2771 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2772 ArgsCleanup(Args.get());
2773
2774 // Since the Clang C library is primarily used by batch tools dealing with
2775 // (often very broken) source code, where spell-checking can have a
2776 // significant negative impact on performance (particularly when
2777 // precompiled headers are involved), we disable it by default.
2778 // Only do this if we haven't found a spell-checking-related argument.
2779 bool FoundSpellCheckingArgument = false;
2780 for (int I = 0; I != num_command_line_args; ++I) {
2781 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2782 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2783 FoundSpellCheckingArgument = true;
2784 break;
2785 }
2786 }
2787 if (!FoundSpellCheckingArgument)
2788 Args->push_back("-fno-spell-checking");
2789
2790 Args->insert(Args->end(), command_line_args,
2791 command_line_args + num_command_line_args);
2792
2793 // The 'source_filename' argument is optional. If the caller does not
2794 // specify it then it is assumed that the source file is specified
2795 // in the actual argument list.
2796 // Put the source file after command_line_args otherwise if '-x' flag is
2797 // present it will be unused.
2798 if (source_filename)
2799 Args->push_back(source_filename);
2800
2801 // Do we need the detailed preprocessing record?
2802 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2803 Args->push_back("-Xclang");
2804 Args->push_back("-detailed-preprocessing-record");
2805 }
2806
2807 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002808 std::unique_ptr<ASTUnit> ErrUnit;
2809 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002810 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002811 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2812 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2813 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2814 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2815 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2816 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002817
2818 if (NumErrors != Diags->getClient()->getNumErrors()) {
2819 // Make sure to check that 'Unit' is non-NULL.
2820 if (CXXIdx->getDisplayDiagnostics())
2821 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2822 }
2823
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002824 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2825 PTUI->result = CXError_ASTReadError;
2826 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002827 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002828 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2829 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002830}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002831
2832CXTranslationUnit
2833clang_parseTranslationUnit(CXIndex CIdx,
2834 const char *source_filename,
2835 const char *const *command_line_args,
2836 int num_command_line_args,
2837 struct CXUnsavedFile *unsaved_files,
2838 unsigned num_unsaved_files,
2839 unsigned options) {
2840 CXTranslationUnit TU;
2841 enum CXErrorCode Result = clang_parseTranslationUnit2(
2842 CIdx, source_filename, command_line_args, num_command_line_args,
2843 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002844 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002845 assert((TU && Result == CXError_Success) ||
2846 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002847 return TU;
2848}
2849
2850enum CXErrorCode clang_parseTranslationUnit2(
2851 CXIndex CIdx,
2852 const char *source_filename,
2853 const char *const *command_line_args,
2854 int num_command_line_args,
2855 struct CXUnsavedFile *unsaved_files,
2856 unsigned num_unsaved_files,
2857 unsigned options,
2858 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002859 LOG_FUNC_SECTION {
2860 *Log << source_filename << ": ";
2861 for (int i = 0; i != num_command_line_args; ++i)
2862 *Log << command_line_args[i] << " ";
2863 }
2864
Guy Benyei11169dd2012-12-18 14:30:41 +00002865 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2866 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002867 num_unsaved_files, options, out_TU,
2868 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002869 llvm::CrashRecoveryContext CRC;
2870
2871 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2872 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2873 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2874 fprintf(stderr, " 'command_line_args' : [");
2875 for (int i = 0; i != num_command_line_args; ++i) {
2876 if (i)
2877 fprintf(stderr, ", ");
2878 fprintf(stderr, "'%s'", command_line_args[i]);
2879 }
2880 fprintf(stderr, "],\n");
2881 fprintf(stderr, " 'unsaved_files' : [");
2882 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2883 if (i)
2884 fprintf(stderr, ", ");
2885 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2886 unsaved_files[i].Length);
2887 }
2888 fprintf(stderr, "],\n");
2889 fprintf(stderr, " 'options' : %d,\n", options);
2890 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002891
2892 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002893 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002894 if (CXTranslationUnit *TU = PTUI.out_TU)
2895 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002896 }
2897
2898 return PTUI.result;
2899}
2900
2901unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2902 return CXSaveTranslationUnit_None;
2903}
2904
2905namespace {
2906
2907struct SaveTranslationUnitInfo {
2908 CXTranslationUnit TU;
2909 const char *FileName;
2910 unsigned options;
2911 CXSaveError result;
2912};
2913
2914}
2915
2916static void clang_saveTranslationUnit_Impl(void *UserData) {
2917 SaveTranslationUnitInfo *STUI =
2918 static_cast<SaveTranslationUnitInfo*>(UserData);
2919
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002920 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002921 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2922 setThreadBackgroundPriority();
2923
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002924 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002925 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2926}
2927
2928int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2929 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002930 LOG_FUNC_SECTION {
2931 *Log << TU << ' ' << FileName;
2932 }
2933
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002934 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002935 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002936 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002937 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002938
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002939 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002940 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2941 if (!CXXUnit->hasSema())
2942 return CXSaveError_InvalidTU;
2943
2944 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2945
2946 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2947 getenv("LIBCLANG_NOTHREADS")) {
2948 clang_saveTranslationUnit_Impl(&STUI);
2949
2950 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2951 PrintLibclangResourceUsage(TU);
2952
2953 return STUI.result;
2954 }
2955
2956 // We have an AST that has invalid nodes due to compiler errors.
2957 // Use a crash recovery thread for protection.
2958
2959 llvm::CrashRecoveryContext CRC;
2960
2961 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2962 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2963 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2964 fprintf(stderr, " 'options' : %d,\n", options);
2965 fprintf(stderr, "}\n");
2966
2967 return CXSaveError_Unknown;
2968
2969 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2970 PrintLibclangResourceUsage(TU);
2971 }
2972
2973 return STUI.result;
2974}
2975
2976void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2977 if (CTUnit) {
2978 // If the translation unit has been marked as unsafe to free, just discard
2979 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002980 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2981 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002982 return;
2983
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002984 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002985 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002986 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2987 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002988 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002989 delete CTUnit;
2990 }
2991}
2992
2993unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2994 return CXReparse_None;
2995}
2996
2997struct ReparseTranslationUnitInfo {
2998 CXTranslationUnit TU;
2999 unsigned num_unsaved_files;
3000 struct CXUnsavedFile *unsaved_files;
3001 unsigned options;
3002 int result;
3003};
3004
3005static void clang_reparseTranslationUnit_Impl(void *UserData) {
3006 ReparseTranslationUnitInfo *RTUI =
3007 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003008 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003009
Guy Benyei11169dd2012-12-18 14:30:41 +00003010 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003011 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3012 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3013 unsigned options = RTUI->options;
3014 (void) options;
3015
3016 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003017 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003018 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003019 RTUI->result = CXError_InvalidArguments;
3020 return;
3021 }
Craig Topper69186e72014-06-08 08:38:04 +00003022 if (unsaved_files == nullptr && num_unsaved_files != 0) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003023 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003024 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003025 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003026
3027 // Reset the associated diagnostics.
3028 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003029 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003030
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003031 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003032 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3033 setThreadBackgroundPriority();
3034
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003035 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003036 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003037
3038 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3039 new std::vector<ASTUnit::RemappedFile>());
3040
Guy Benyei11169dd2012-12-18 14:30:41 +00003041 // Recover resources if we crash before exiting this function.
3042 llvm::CrashRecoveryContextCleanupRegistrar<
3043 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3044
3045 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3046 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3047 const llvm::MemoryBuffer *Buffer
3048 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3049 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3050 Buffer));
3051 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003052
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003053 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003054 RTUI->result = CXError_Success;
3055 else if (isASTReadError(CXXUnit))
3056 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003057}
3058
3059int clang_reparseTranslationUnit(CXTranslationUnit TU,
3060 unsigned num_unsaved_files,
3061 struct CXUnsavedFile *unsaved_files,
3062 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003063 LOG_FUNC_SECTION {
3064 *Log << TU;
3065 }
3066
Guy Benyei11169dd2012-12-18 14:30:41 +00003067 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003068 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003069
3070 if (getenv("LIBCLANG_NOTHREADS")) {
3071 clang_reparseTranslationUnit_Impl(&RTUI);
3072 return RTUI.result;
3073 }
3074
3075 llvm::CrashRecoveryContext CRC;
3076
3077 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3078 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003079 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003080 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003081 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3082 PrintLibclangResourceUsage(TU);
3083
3084 return RTUI.result;
3085}
3086
3087
3088CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003089 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003090 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003091 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003092 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003093
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003094 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003095 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003096}
3097
3098CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003099 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003100 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003101 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003102 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003103
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003104 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003105 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3106}
3107
3108} // end: extern "C"
3109
3110//===----------------------------------------------------------------------===//
3111// CXFile Operations.
3112//===----------------------------------------------------------------------===//
3113
3114extern "C" {
3115CXString clang_getFileName(CXFile SFile) {
3116 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003117 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003118
3119 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003120 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003121}
3122
3123time_t clang_getFileTime(CXFile SFile) {
3124 if (!SFile)
3125 return 0;
3126
3127 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3128 return FEnt->getModificationTime();
3129}
3130
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003131CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003132 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003133 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003134 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003135 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003136
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003137 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003138
3139 FileManager &FMgr = CXXUnit->getFileManager();
3140 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3141}
3142
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003143unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3144 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003145 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003146 LOG_BAD_TU(TU);
3147 return 0;
3148 }
3149
3150 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003151 return 0;
3152
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003153 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003154 FileEntry *FEnt = static_cast<FileEntry *>(file);
3155 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3156 .isFileMultipleIncludeGuarded(FEnt);
3157}
3158
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003159int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3160 if (!file || !outID)
3161 return 1;
3162
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003163 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003164 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3165 outID->data[0] = ID.getDevice();
3166 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003167 outID->data[2] = FEnt->getModificationTime();
3168 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003169}
3170
Guy Benyei11169dd2012-12-18 14:30:41 +00003171} // end: extern "C"
3172
3173//===----------------------------------------------------------------------===//
3174// CXCursor Operations.
3175//===----------------------------------------------------------------------===//
3176
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003177static const Decl *getDeclFromExpr(const Stmt *E) {
3178 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 return getDeclFromExpr(CE->getSubExpr());
3180
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003181 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003183 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003187 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 if (PRE->isExplicitProperty())
3189 return PRE->getExplicitProperty();
3190 // It could be messaging both getter and setter as in:
3191 // ++myobj.myprop;
3192 // in which case prefer to associate the setter since it is less obvious
3193 // from inspecting the source that the setter is going to get called.
3194 if (PRE->isMessagingSetter())
3195 return PRE->getImplicitPropertySetter();
3196 return PRE->getImplicitPropertyGetter();
3197 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003198 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003199 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003200 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 if (Expr *Src = OVE->getSourceExpr())
3202 return getDeclFromExpr(Src);
3203
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003204 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003206 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003207 if (!CE->isElidable())
3208 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003209 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 return OME->getMethodDecl();
3211
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003212 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003214 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3216 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003217 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3219 isa<ParmVarDecl>(SizeOfPack->getPack()))
3220 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003221
3222 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003223}
3224
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003225static SourceLocation getLocationFromExpr(const Expr *E) {
3226 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 return getLocationFromExpr(CE->getSubExpr());
3228
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003229 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003230 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003231 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003233 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003235 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003237 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003239 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 return PropRef->getLocation();
3241
3242 return E->getLocStart();
3243}
3244
3245extern "C" {
3246
3247unsigned clang_visitChildren(CXCursor parent,
3248 CXCursorVisitor visitor,
3249 CXClientData client_data) {
3250 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3251 /*VisitPreprocessorLast=*/false);
3252 return CursorVis.VisitChildren(parent);
3253}
3254
3255#ifndef __has_feature
3256#define __has_feature(x) 0
3257#endif
3258#if __has_feature(blocks)
3259typedef enum CXChildVisitResult
3260 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3261
3262static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3263 CXClientData client_data) {
3264 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3265 return block(cursor, parent);
3266}
3267#else
3268// If we are compiled with a compiler that doesn't have native blocks support,
3269// define and call the block manually, so the
3270typedef struct _CXChildVisitResult
3271{
3272 void *isa;
3273 int flags;
3274 int reserved;
3275 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3276 CXCursor);
3277} *CXCursorVisitorBlock;
3278
3279static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3280 CXClientData client_data) {
3281 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3282 return block->invoke(block, cursor, parent);
3283}
3284#endif
3285
3286
3287unsigned clang_visitChildrenWithBlock(CXCursor parent,
3288 CXCursorVisitorBlock block) {
3289 return clang_visitChildren(parent, visitWithBlock, block);
3290}
3291
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003292static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003294 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003295
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003296 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003298 if (const ObjCPropertyImplDecl *PropImpl =
3299 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003300 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003301 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003302
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003303 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003305 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003306
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003307 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 }
3309
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003310 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003311 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003312
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003313 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3315 // and returns different names. NamedDecl returns the class name and
3316 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003317 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003318
3319 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003320 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003321
3322 SmallString<1024> S;
3323 llvm::raw_svector_ostream os(S);
3324 ND->printName(os);
3325
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003326 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003327}
3328
3329CXString clang_getCursorSpelling(CXCursor C) {
3330 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003331 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003332
3333 if (clang_isReference(C.kind)) {
3334 switch (C.kind) {
3335 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003336 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003337 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 }
3339 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003340 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003341 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 }
3343 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003344 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003346 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 }
3348 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003349 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003350 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 }
3352 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003353 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 assert(Type && "Missing type decl");
3355
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003356 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 getAsString());
3358 }
3359 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003360 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 assert(Template && "Missing template decl");
3362
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003363 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 }
3365
3366 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003367 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 assert(NS && "Missing namespace decl");
3369
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003370 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 }
3372
3373 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003374 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 assert(Field && "Missing member decl");
3376
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003377 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 }
3379
3380 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003381 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 assert(Label && "Missing label");
3383
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003384 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003385 }
3386
3387 case CXCursor_OverloadedDeclRef: {
3388 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003389 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3390 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003391 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003392 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003394 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003395 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 OverloadedTemplateStorage *Ovl
3397 = Storage.get<OverloadedTemplateStorage*>();
3398 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003399 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003400 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 }
3402
3403 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003404 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 assert(Var && "Missing variable decl");
3406
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003407 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 }
3409
3410 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003411 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 }
3413 }
3414
3415 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003416 const Expr *E = getCursorExpr(C);
3417
3418 if (C.kind == CXCursor_ObjCStringLiteral ||
3419 C.kind == CXCursor_StringLiteral) {
3420 const StringLiteral *SLit;
3421 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3422 SLit = OSL->getString();
3423 } else {
3424 SLit = cast<StringLiteral>(E);
3425 }
3426 SmallString<256> Buf;
3427 llvm::raw_svector_ostream OS(Buf);
3428 SLit->outputString(OS);
3429 return cxstring::createDup(OS.str());
3430 }
3431
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003432 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003433 if (D)
3434 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003435 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 }
3437
3438 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003439 const Stmt *S = getCursorStmt(C);
3440 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003441 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003442
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003443 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003444 }
3445
3446 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003447 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 ->getNameStart());
3449
3450 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003451 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 ->getNameStart());
3453
3454 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003455 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003456
3457 if (clang_isDeclaration(C.kind))
3458 return getDeclSpelling(getCursorDecl(C));
3459
3460 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003461 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003462 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 }
3464
3465 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003466 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003467 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 }
3469
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003470 if (C.kind == CXCursor_PackedAttr) {
3471 return cxstring::createRef("packed");
3472 }
3473
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003474 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003475}
3476
3477CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3478 unsigned pieceIndex,
3479 unsigned options) {
3480 if (clang_Cursor_isNull(C))
3481 return clang_getNullRange();
3482
3483 ASTContext &Ctx = getCursorContext(C);
3484
3485 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003486 const Stmt *S = getCursorStmt(C);
3487 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 if (pieceIndex > 0)
3489 return clang_getNullRange();
3490 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3491 }
3492
3493 return clang_getNullRange();
3494 }
3495
3496 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003497 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3499 if (pieceIndex >= ME->getNumSelectorLocs())
3500 return clang_getNullRange();
3501 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3502 }
3503 }
3504
3505 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3506 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3509 if (pieceIndex >= MD->getNumSelectorLocs())
3510 return clang_getNullRange();
3511 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3512 }
3513 }
3514
3515 if (C.kind == CXCursor_ObjCCategoryDecl ||
3516 C.kind == CXCursor_ObjCCategoryImplDecl) {
3517 if (pieceIndex > 0)
3518 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003519 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3521 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003522 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3524 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3525 }
3526
3527 if (C.kind == CXCursor_ModuleImportDecl) {
3528 if (pieceIndex > 0)
3529 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003530 if (const ImportDecl *ImportD =
3531 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3533 if (!Locs.empty())
3534 return cxloc::translateSourceRange(Ctx,
3535 SourceRange(Locs.front(), Locs.back()));
3536 }
3537 return clang_getNullRange();
3538 }
3539
3540 // FIXME: A CXCursor_InclusionDirective should give the location of the
3541 // filename, but we don't keep track of this.
3542
3543 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3544 // but we don't keep track of this.
3545
3546 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3547 // but we don't keep track of this.
3548
3549 // Default handling, give the location of the cursor.
3550
3551 if (pieceIndex > 0)
3552 return clang_getNullRange();
3553
3554 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3555 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3556 return cxloc::translateSourceRange(Ctx, Loc);
3557}
3558
3559CXString clang_getCursorDisplayName(CXCursor C) {
3560 if (!clang_isDeclaration(C.kind))
3561 return clang_getCursorSpelling(C);
3562
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003563 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003565 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003566
3567 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003568 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 D = FunTmpl->getTemplatedDecl();
3570
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003571 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003572 SmallString<64> Str;
3573 llvm::raw_svector_ostream OS(Str);
3574 OS << *Function;
3575 if (Function->getPrimaryTemplate())
3576 OS << "<>";
3577 OS << "(";
3578 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3579 if (I)
3580 OS << ", ";
3581 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3582 }
3583
3584 if (Function->isVariadic()) {
3585 if (Function->getNumParams())
3586 OS << ", ";
3587 OS << "...";
3588 }
3589 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003590 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 }
3592
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003593 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 SmallString<64> Str;
3595 llvm::raw_svector_ostream OS(Str);
3596 OS << *ClassTemplate;
3597 OS << "<";
3598 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3599 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3600 if (I)
3601 OS << ", ";
3602
3603 NamedDecl *Param = Params->getParam(I);
3604 if (Param->getIdentifier()) {
3605 OS << Param->getIdentifier()->getName();
3606 continue;
3607 }
3608
3609 // There is no parameter name, which makes this tricky. Try to come up
3610 // with something useful that isn't too long.
3611 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3612 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3613 else if (NonTypeTemplateParmDecl *NTTP
3614 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3615 OS << NTTP->getType().getAsString(Policy);
3616 else
3617 OS << "template<...> class";
3618 }
3619
3620 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003621 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 }
3623
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003624 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3626 // If the type was explicitly written, use that.
3627 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003628 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003629
Benjamin Kramer9170e912013-02-22 15:46:01 +00003630 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 llvm::raw_svector_ostream OS(Str);
3632 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003633 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 ClassSpec->getTemplateArgs().data(),
3635 ClassSpec->getTemplateArgs().size(),
3636 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003637 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 }
3639
3640 return clang_getCursorSpelling(C);
3641}
3642
3643CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3644 switch (Kind) {
3645 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003773 case CXCursor_ObjCSelfExpr:
3774 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003891 case CXCursor_PackedAttr:
3892 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003893 case CXCursor_PureAttr:
3894 return cxstring::createRef("attribute(pure)");
3895 case CXCursor_ConstAttr:
3896 return cxstring::createRef("attribute(const)");
3897 case CXCursor_NoDuplicateAttr:
3898 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003899 case CXCursor_CUDAConstantAttr:
3900 return cxstring::createRef("attribute(constant)");
3901 case CXCursor_CUDADeviceAttr:
3902 return cxstring::createRef("attribute(device)");
3903 case CXCursor_CUDAGlobalAttr:
3904 return cxstring::createRef("attribute(global)");
3905 case CXCursor_CUDAHostAttr:
3906 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003955 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003956 return cxstring::createRef("OMPParallelDirective");
3957 case CXCursor_OMPSimdDirective:
3958 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00003959 case CXCursor_OMPForDirective:
3960 return cxstring::createRef("OMPForDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 }
3962
3963 llvm_unreachable("Unhandled CXCursorKind");
3964}
3965
3966struct GetCursorData {
3967 SourceLocation TokenBeginLoc;
3968 bool PointsAtMacroArgExpansion;
3969 bool VisitedObjCPropertyImplDecl;
3970 SourceLocation VisitedDeclaratorDeclStartLoc;
3971 CXCursor &BestCursor;
3972
3973 GetCursorData(SourceManager &SM,
3974 SourceLocation tokenBegin, CXCursor &outputCursor)
3975 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3976 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3977 VisitedObjCPropertyImplDecl = false;
3978 }
3979};
3980
3981static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3982 CXCursor parent,
3983 CXClientData client_data) {
3984 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3985 CXCursor *BestCursor = &Data->BestCursor;
3986
3987 // If we point inside a macro argument we should provide info of what the
3988 // token is so use the actual cursor, don't replace it with a macro expansion
3989 // cursor.
3990 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3991 return CXChildVisit_Recurse;
3992
3993 if (clang_isDeclaration(cursor.kind)) {
3994 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003995 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3997 if (MD->isImplicit())
3998 return CXChildVisit_Break;
3999
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004000 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4002 // Check that when we have multiple @class references in the same line,
4003 // that later ones do not override the previous ones.
4004 // If we have:
4005 // @class Foo, Bar;
4006 // source ranges for both start at '@', so 'Bar' will end up overriding
4007 // 'Foo' even though the cursor location was at 'Foo'.
4008 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4009 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004010 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4012 if (PrevID != ID &&
4013 !PrevID->isThisDeclarationADefinition() &&
4014 !ID->isThisDeclarationADefinition())
4015 return CXChildVisit_Break;
4016 }
4017
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004018 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4020 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4021 // Check that when we have multiple declarators in the same line,
4022 // that later ones do not override the previous ones.
4023 // If we have:
4024 // int Foo, Bar;
4025 // source ranges for both start at 'int', so 'Bar' will end up overriding
4026 // 'Foo' even though the cursor location was at 'Foo'.
4027 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4028 return CXChildVisit_Break;
4029 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4030
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004031 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4033 (void)PropImp;
4034 // Check that when we have multiple @synthesize in the same line,
4035 // that later ones do not override the previous ones.
4036 // If we have:
4037 // @synthesize Foo, Bar;
4038 // source ranges for both start at '@', so 'Bar' will end up overriding
4039 // 'Foo' even though the cursor location was at 'Foo'.
4040 if (Data->VisitedObjCPropertyImplDecl)
4041 return CXChildVisit_Break;
4042 Data->VisitedObjCPropertyImplDecl = true;
4043 }
4044 }
4045
4046 if (clang_isExpression(cursor.kind) &&
4047 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004048 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 // Avoid having the cursor of an expression replace the declaration cursor
4050 // when the expression source range overlaps the declaration range.
4051 // This can happen for C++ constructor expressions whose range generally
4052 // include the variable declaration, e.g.:
4053 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4054 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4055 D->getLocation() == Data->TokenBeginLoc)
4056 return CXChildVisit_Break;
4057 }
4058 }
4059
4060 // If our current best cursor is the construction of a temporary object,
4061 // don't replace that cursor with a type reference, because we want
4062 // clang_getCursor() to point at the constructor.
4063 if (clang_isExpression(BestCursor->kind) &&
4064 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4065 cursor.kind == CXCursor_TypeRef) {
4066 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4067 // as having the actual point on the type reference.
4068 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4069 return CXChildVisit_Recurse;
4070 }
4071
4072 *BestCursor = cursor;
4073 return CXChildVisit_Recurse;
4074}
4075
4076CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004077 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004078 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004080 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004081
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004082 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4084
4085 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4086 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4087
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004088 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 CXFile SearchFile;
4090 unsigned SearchLine, SearchColumn;
4091 CXFile ResultFile;
4092 unsigned ResultLine, ResultColumn;
4093 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4094 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4095 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004096
4097 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4098 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004099 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004100 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 SearchFileName = clang_getFileName(SearchFile);
4102 ResultFileName = clang_getFileName(ResultFile);
4103 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4104 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004105 *Log << llvm::format("(%s:%d:%d) = %s",
4106 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4107 clang_getCString(KindSpelling))
4108 << llvm::format("(%s:%d:%d):%s%s",
4109 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4110 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 clang_disposeString(SearchFileName);
4112 clang_disposeString(ResultFileName);
4113 clang_disposeString(KindSpelling);
4114 clang_disposeString(USR);
4115
4116 CXCursor Definition = clang_getCursorDefinition(Result);
4117 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4118 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4119 CXString DefinitionKindSpelling
4120 = clang_getCursorKindSpelling(Definition.kind);
4121 CXFile DefinitionFile;
4122 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004123 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004124 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004126 *Log << llvm::format(" -> %s(%s:%d:%d)",
4127 clang_getCString(DefinitionKindSpelling),
4128 clang_getCString(DefinitionFileName),
4129 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 clang_disposeString(DefinitionFileName);
4131 clang_disposeString(DefinitionKindSpelling);
4132 }
4133 }
4134
4135 return Result;
4136}
4137
4138CXCursor clang_getNullCursor(void) {
4139 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4140}
4141
4142unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004143 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4144 // can't set consistently. For example, when visiting a DeclStmt we will set
4145 // it but we don't set it on the result of clang_getCursorDefinition for
4146 // a reference of the same declaration.
4147 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4148 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4149 // to provide that kind of info.
4150 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004151 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004152 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004153 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004154
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 return X == Y;
4156}
4157
4158unsigned clang_hashCursor(CXCursor C) {
4159 unsigned Index = 0;
4160 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4161 Index = 1;
4162
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004163 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 std::make_pair(C.kind, C.data[Index]));
4165}
4166
4167unsigned clang_isInvalid(enum CXCursorKind K) {
4168 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4169}
4170
4171unsigned clang_isDeclaration(enum CXCursorKind K) {
4172 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4173 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4174}
4175
4176unsigned clang_isReference(enum CXCursorKind K) {
4177 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4178}
4179
4180unsigned clang_isExpression(enum CXCursorKind K) {
4181 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4182}
4183
4184unsigned clang_isStatement(enum CXCursorKind K) {
4185 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4186}
4187
4188unsigned clang_isAttribute(enum CXCursorKind K) {
4189 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4190}
4191
4192unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4193 return K == CXCursor_TranslationUnit;
4194}
4195
4196unsigned clang_isPreprocessing(enum CXCursorKind K) {
4197 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4198}
4199
4200unsigned clang_isUnexposed(enum CXCursorKind K) {
4201 switch (K) {
4202 case CXCursor_UnexposedDecl:
4203 case CXCursor_UnexposedExpr:
4204 case CXCursor_UnexposedStmt:
4205 case CXCursor_UnexposedAttr:
4206 return true;
4207 default:
4208 return false;
4209 }
4210}
4211
4212CXCursorKind clang_getCursorKind(CXCursor C) {
4213 return C.kind;
4214}
4215
4216CXSourceLocation clang_getCursorLocation(CXCursor C) {
4217 if (clang_isReference(C.kind)) {
4218 switch (C.kind) {
4219 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004220 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 = getCursorObjCSuperClassRef(C);
4222 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4223 }
4224
4225 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004226 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 = getCursorObjCProtocolRef(C);
4228 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4229 }
4230
4231 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004232 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 = getCursorObjCClassRef(C);
4234 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4235 }
4236
4237 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004238 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4240 }
4241
4242 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004243 std::pair<const TemplateDecl *, SourceLocation> P =
4244 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4246 }
4247
4248 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004249 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4251 }
4252
4253 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004254 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4256 }
4257
4258 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004259 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4261 }
4262
4263 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004264 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 if (!BaseSpec)
4266 return clang_getNullLocation();
4267
4268 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4269 return cxloc::translateSourceLocation(getCursorContext(C),
4270 TSInfo->getTypeLoc().getBeginLoc());
4271
4272 return cxloc::translateSourceLocation(getCursorContext(C),
4273 BaseSpec->getLocStart());
4274 }
4275
4276 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004277 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4279 }
4280
4281 case CXCursor_OverloadedDeclRef:
4282 return cxloc::translateSourceLocation(getCursorContext(C),
4283 getCursorOverloadedDeclRef(C).second);
4284
4285 default:
4286 // FIXME: Need a way to enumerate all non-reference cases.
4287 llvm_unreachable("Missed a reference kind");
4288 }
4289 }
4290
4291 if (clang_isExpression(C.kind))
4292 return cxloc::translateSourceLocation(getCursorContext(C),
4293 getLocationFromExpr(getCursorExpr(C)));
4294
4295 if (clang_isStatement(C.kind))
4296 return cxloc::translateSourceLocation(getCursorContext(C),
4297 getCursorStmt(C)->getLocStart());
4298
4299 if (C.kind == CXCursor_PreprocessingDirective) {
4300 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4301 return cxloc::translateSourceLocation(getCursorContext(C), L);
4302 }
4303
4304 if (C.kind == CXCursor_MacroExpansion) {
4305 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004306 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004307 return cxloc::translateSourceLocation(getCursorContext(C), L);
4308 }
4309
4310 if (C.kind == CXCursor_MacroDefinition) {
4311 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4312 return cxloc::translateSourceLocation(getCursorContext(C), L);
4313 }
4314
4315 if (C.kind == CXCursor_InclusionDirective) {
4316 SourceLocation L
4317 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4318 return cxloc::translateSourceLocation(getCursorContext(C), L);
4319 }
4320
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004321 if (clang_isAttribute(C.kind)) {
4322 SourceLocation L
4323 = cxcursor::getCursorAttr(C)->getLocation();
4324 return cxloc::translateSourceLocation(getCursorContext(C), L);
4325 }
4326
Guy Benyei11169dd2012-12-18 14:30:41 +00004327 if (!clang_isDeclaration(C.kind))
4328 return clang_getNullLocation();
4329
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004330 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004331 if (!D)
4332 return clang_getNullLocation();
4333
4334 SourceLocation Loc = D->getLocation();
4335 // FIXME: Multiple variables declared in a single declaration
4336 // currently lack the information needed to correctly determine their
4337 // ranges when accounting for the type-specifier. We use context
4338 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4339 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004340 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004341 if (!cxcursor::isFirstInDeclGroup(C))
4342 Loc = VD->getLocation();
4343 }
4344
4345 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004346 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004347 Loc = MD->getSelectorStartLoc();
4348
4349 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4350}
4351
4352} // end extern "C"
4353
4354CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4355 assert(TU);
4356
4357 // Guard against an invalid SourceLocation, or we may assert in one
4358 // of the following calls.
4359 if (SLoc.isInvalid())
4360 return clang_getNullCursor();
4361
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004362 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004363
4364 // Translate the given source location to make it point at the beginning of
4365 // the token under the cursor.
4366 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4367 CXXUnit->getASTContext().getLangOpts());
4368
4369 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4370 if (SLoc.isValid()) {
4371 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4372 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4373 /*VisitPreprocessorLast=*/true,
4374 /*VisitIncludedEntities=*/false,
4375 SourceLocation(SLoc));
4376 CursorVis.visitFileRegion();
4377 }
4378
4379 return Result;
4380}
4381
4382static SourceRange getRawCursorExtent(CXCursor C) {
4383 if (clang_isReference(C.kind)) {
4384 switch (C.kind) {
4385 case CXCursor_ObjCSuperClassRef:
4386 return getCursorObjCSuperClassRef(C).second;
4387
4388 case CXCursor_ObjCProtocolRef:
4389 return getCursorObjCProtocolRef(C).second;
4390
4391 case CXCursor_ObjCClassRef:
4392 return getCursorObjCClassRef(C).second;
4393
4394 case CXCursor_TypeRef:
4395 return getCursorTypeRef(C).second;
4396
4397 case CXCursor_TemplateRef:
4398 return getCursorTemplateRef(C).second;
4399
4400 case CXCursor_NamespaceRef:
4401 return getCursorNamespaceRef(C).second;
4402
4403 case CXCursor_MemberRef:
4404 return getCursorMemberRef(C).second;
4405
4406 case CXCursor_CXXBaseSpecifier:
4407 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4408
4409 case CXCursor_LabelRef:
4410 return getCursorLabelRef(C).second;
4411
4412 case CXCursor_OverloadedDeclRef:
4413 return getCursorOverloadedDeclRef(C).second;
4414
4415 case CXCursor_VariableRef:
4416 return getCursorVariableRef(C).second;
4417
4418 default:
4419 // FIXME: Need a way to enumerate all non-reference cases.
4420 llvm_unreachable("Missed a reference kind");
4421 }
4422 }
4423
4424 if (clang_isExpression(C.kind))
4425 return getCursorExpr(C)->getSourceRange();
4426
4427 if (clang_isStatement(C.kind))
4428 return getCursorStmt(C)->getSourceRange();
4429
4430 if (clang_isAttribute(C.kind))
4431 return getCursorAttr(C)->getRange();
4432
4433 if (C.kind == CXCursor_PreprocessingDirective)
4434 return cxcursor::getCursorPreprocessingDirective(C);
4435
4436 if (C.kind == CXCursor_MacroExpansion) {
4437 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004438 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 return TU->mapRangeFromPreamble(Range);
4440 }
4441
4442 if (C.kind == CXCursor_MacroDefinition) {
4443 ASTUnit *TU = getCursorASTUnit(C);
4444 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4445 return TU->mapRangeFromPreamble(Range);
4446 }
4447
4448 if (C.kind == CXCursor_InclusionDirective) {
4449 ASTUnit *TU = getCursorASTUnit(C);
4450 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4451 return TU->mapRangeFromPreamble(Range);
4452 }
4453
4454 if (C.kind == CXCursor_TranslationUnit) {
4455 ASTUnit *TU = getCursorASTUnit(C);
4456 FileID MainID = TU->getSourceManager().getMainFileID();
4457 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4458 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4459 return SourceRange(Start, End);
4460 }
4461
4462 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004463 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 if (!D)
4465 return SourceRange();
4466
4467 SourceRange R = D->getSourceRange();
4468 // FIXME: Multiple variables declared in a single declaration
4469 // currently lack the information needed to correctly determine their
4470 // ranges when accounting for the type-specifier. We use context
4471 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4472 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004473 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 if (!cxcursor::isFirstInDeclGroup(C))
4475 R.setBegin(VD->getLocation());
4476 }
4477 return R;
4478 }
4479 return SourceRange();
4480}
4481
4482/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4483/// the decl-specifier-seq for declarations.
4484static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4485 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004486 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 if (!D)
4488 return SourceRange();
4489
4490 SourceRange R = D->getSourceRange();
4491
4492 // Adjust the start of the location for declarations preceded by
4493 // declaration specifiers.
4494 SourceLocation StartLoc;
4495 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4496 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4497 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004498 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4500 StartLoc = TI->getTypeLoc().getLocStart();
4501 }
4502
4503 if (StartLoc.isValid() && R.getBegin().isValid() &&
4504 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4505 R.setBegin(StartLoc);
4506
4507 // FIXME: Multiple variables declared in a single declaration
4508 // currently lack the information needed to correctly determine their
4509 // ranges when accounting for the type-specifier. We use context
4510 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4511 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004512 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 if (!cxcursor::isFirstInDeclGroup(C))
4514 R.setBegin(VD->getLocation());
4515 }
4516
4517 return R;
4518 }
4519
4520 return getRawCursorExtent(C);
4521}
4522
4523extern "C" {
4524
4525CXSourceRange clang_getCursorExtent(CXCursor C) {
4526 SourceRange R = getRawCursorExtent(C);
4527 if (R.isInvalid())
4528 return clang_getNullRange();
4529
4530 return cxloc::translateSourceRange(getCursorContext(C), R);
4531}
4532
4533CXCursor clang_getCursorReferenced(CXCursor C) {
4534 if (clang_isInvalid(C.kind))
4535 return clang_getNullCursor();
4536
4537 CXTranslationUnit tu = getCursorTU(C);
4538 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004539 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004540 if (!D)
4541 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004542 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004544 if (const ObjCPropertyImplDecl *PropImpl =
4545 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4547 return MakeCXCursor(Property, tu);
4548
4549 return C;
4550 }
4551
4552 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004553 const Expr *E = getCursorExpr(C);
4554 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 if (D) {
4556 CXCursor declCursor = MakeCXCursor(D, tu);
4557 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4558 declCursor);
4559 return declCursor;
4560 }
4561
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004562 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 return MakeCursorOverloadedDeclRef(Ovl, tu);
4564
4565 return clang_getNullCursor();
4566 }
4567
4568 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004569 const Stmt *S = getCursorStmt(C);
4570 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 if (LabelDecl *label = Goto->getLabel())
4572 if (LabelStmt *labelS = label->getStmt())
4573 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4574
4575 return clang_getNullCursor();
4576 }
4577
4578 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004579 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 return MakeMacroDefinitionCursor(Def, tu);
4581 }
4582
4583 if (!clang_isReference(C.kind))
4584 return clang_getNullCursor();
4585
4586 switch (C.kind) {
4587 case CXCursor_ObjCSuperClassRef:
4588 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4589
4590 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004591 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4592 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 return MakeCXCursor(Def, tu);
4594
4595 return MakeCXCursor(Prot, tu);
4596 }
4597
4598 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004599 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4600 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 return MakeCXCursor(Def, tu);
4602
4603 return MakeCXCursor(Class, tu);
4604 }
4605
4606 case CXCursor_TypeRef:
4607 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4608
4609 case CXCursor_TemplateRef:
4610 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4611
4612 case CXCursor_NamespaceRef:
4613 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4614
4615 case CXCursor_MemberRef:
4616 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4617
4618 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004619 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4621 tu ));
4622 }
4623
4624 case CXCursor_LabelRef:
4625 // FIXME: We end up faking the "parent" declaration here because we
4626 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004627 return MakeCXCursor(getCursorLabelRef(C).first,
4628 cxtu::getASTUnit(tu)->getASTContext()
4629 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 tu);
4631
4632 case CXCursor_OverloadedDeclRef:
4633 return C;
4634
4635 case CXCursor_VariableRef:
4636 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4637
4638 default:
4639 // We would prefer to enumerate all non-reference cursor kinds here.
4640 llvm_unreachable("Unhandled reference cursor kind");
4641 }
4642}
4643
4644CXCursor clang_getCursorDefinition(CXCursor C) {
4645 if (clang_isInvalid(C.kind))
4646 return clang_getNullCursor();
4647
4648 CXTranslationUnit TU = getCursorTU(C);
4649
4650 bool WasReference = false;
4651 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4652 C = clang_getCursorReferenced(C);
4653 WasReference = true;
4654 }
4655
4656 if (C.kind == CXCursor_MacroExpansion)
4657 return clang_getCursorReferenced(C);
4658
4659 if (!clang_isDeclaration(C.kind))
4660 return clang_getNullCursor();
4661
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004662 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 if (!D)
4664 return clang_getNullCursor();
4665
4666 switch (D->getKind()) {
4667 // Declaration kinds that don't really separate the notions of
4668 // declaration and definition.
4669 case Decl::Namespace:
4670 case Decl::Typedef:
4671 case Decl::TypeAlias:
4672 case Decl::TypeAliasTemplate:
4673 case Decl::TemplateTypeParm:
4674 case Decl::EnumConstant:
4675 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004676 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case Decl::IndirectField:
4678 case Decl::ObjCIvar:
4679 case Decl::ObjCAtDefsField:
4680 case Decl::ImplicitParam:
4681 case Decl::ParmVar:
4682 case Decl::NonTypeTemplateParm:
4683 case Decl::TemplateTemplateParm:
4684 case Decl::ObjCCategoryImpl:
4685 case Decl::ObjCImplementation:
4686 case Decl::AccessSpec:
4687 case Decl::LinkageSpec:
4688 case Decl::ObjCPropertyImpl:
4689 case Decl::FileScopeAsm:
4690 case Decl::StaticAssert:
4691 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004692 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 case Decl::Label: // FIXME: Is this right??
4694 case Decl::ClassScopeFunctionSpecialization:
4695 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004696 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 return C;
4698
4699 // Declaration kinds that don't make any sense here, but are
4700 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004701 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 case Decl::TranslationUnit:
4703 break;
4704
4705 // Declaration kinds for which the definition is not resolvable.
4706 case Decl::UnresolvedUsingTypename:
4707 case Decl::UnresolvedUsingValue:
4708 break;
4709
4710 case Decl::UsingDirective:
4711 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4712 TU);
4713
4714 case Decl::NamespaceAlias:
4715 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4716
4717 case Decl::Enum:
4718 case Decl::Record:
4719 case Decl::CXXRecord:
4720 case Decl::ClassTemplateSpecialization:
4721 case Decl::ClassTemplatePartialSpecialization:
4722 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4723 return MakeCXCursor(Def, TU);
4724 return clang_getNullCursor();
4725
4726 case Decl::Function:
4727 case Decl::CXXMethod:
4728 case Decl::CXXConstructor:
4729 case Decl::CXXDestructor:
4730 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004731 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004733 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 return clang_getNullCursor();
4735 }
4736
Larisse Voufo39a1e502013-08-06 01:03:05 +00004737 case Decl::Var:
4738 case Decl::VarTemplateSpecialization:
4739 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004740 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004741 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 return MakeCXCursor(Def, TU);
4743 return clang_getNullCursor();
4744 }
4745
4746 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004747 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4749 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4750 return clang_getNullCursor();
4751 }
4752
4753 case Decl::ClassTemplate: {
4754 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4755 ->getDefinition())
4756 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4757 TU);
4758 return clang_getNullCursor();
4759 }
4760
Larisse Voufo39a1e502013-08-06 01:03:05 +00004761 case Decl::VarTemplate: {
4762 if (VarDecl *Def =
4763 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4764 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4765 return clang_getNullCursor();
4766 }
4767
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 case Decl::Using:
4769 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4770 D->getLocation(), TU);
4771
4772 case Decl::UsingShadow:
4773 return clang_getCursorDefinition(
4774 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4775 TU));
4776
4777 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004778 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 if (Method->isThisDeclarationADefinition())
4780 return C;
4781
4782 // Dig out the method definition in the associated
4783 // @implementation, if we have it.
4784 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004785 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4787 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4788 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4789 Method->isInstanceMethod()))
4790 if (Def->isThisDeclarationADefinition())
4791 return MakeCXCursor(Def, TU);
4792
4793 return clang_getNullCursor();
4794 }
4795
4796 case Decl::ObjCCategory:
4797 if (ObjCCategoryImplDecl *Impl
4798 = cast<ObjCCategoryDecl>(D)->getImplementation())
4799 return MakeCXCursor(Impl, TU);
4800 return clang_getNullCursor();
4801
4802 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004803 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004804 return MakeCXCursor(Def, TU);
4805 return clang_getNullCursor();
4806
4807 case Decl::ObjCInterface: {
4808 // There are two notions of a "definition" for an Objective-C
4809 // class: the interface and its implementation. When we resolved a
4810 // reference to an Objective-C class, produce the @interface as
4811 // the definition; when we were provided with the interface,
4812 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004813 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004815 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004816 return MakeCXCursor(Def, TU);
4817 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4818 return MakeCXCursor(Impl, TU);
4819 return clang_getNullCursor();
4820 }
4821
4822 case Decl::ObjCProperty:
4823 // FIXME: We don't really know where to find the
4824 // ObjCPropertyImplDecls that implement this property.
4825 return clang_getNullCursor();
4826
4827 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004828 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004829 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004830 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004831 return MakeCXCursor(Def, TU);
4832
4833 return clang_getNullCursor();
4834
4835 case Decl::Friend:
4836 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4837 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4838 return clang_getNullCursor();
4839
4840 case Decl::FriendTemplate:
4841 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4842 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4843 return clang_getNullCursor();
4844 }
4845
4846 return clang_getNullCursor();
4847}
4848
4849unsigned clang_isCursorDefinition(CXCursor C) {
4850 if (!clang_isDeclaration(C.kind))
4851 return 0;
4852
4853 return clang_getCursorDefinition(C) == C;
4854}
4855
4856CXCursor clang_getCanonicalCursor(CXCursor C) {
4857 if (!clang_isDeclaration(C.kind))
4858 return C;
4859
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004860 if (const Decl *D = getCursorDecl(C)) {
4861 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004862 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4863 return MakeCXCursor(CatD, getCursorTU(C));
4864
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004865 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4866 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004867 return MakeCXCursor(IFD, getCursorTU(C));
4868
4869 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4870 }
4871
4872 return C;
4873}
4874
4875int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4876 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4877}
4878
4879unsigned clang_getNumOverloadedDecls(CXCursor C) {
4880 if (C.kind != CXCursor_OverloadedDeclRef)
4881 return 0;
4882
4883 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004884 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 return E->getNumDecls();
4886
4887 if (OverloadedTemplateStorage *S
4888 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4889 return S->size();
4890
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004891 const Decl *D = Storage.get<const Decl *>();
4892 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004893 return Using->shadow_size();
4894
4895 return 0;
4896}
4897
4898CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4899 if (cursor.kind != CXCursor_OverloadedDeclRef)
4900 return clang_getNullCursor();
4901
4902 if (index >= clang_getNumOverloadedDecls(cursor))
4903 return clang_getNullCursor();
4904
4905 CXTranslationUnit TU = getCursorTU(cursor);
4906 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004907 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004908 return MakeCXCursor(E->decls_begin()[index], TU);
4909
4910 if (OverloadedTemplateStorage *S
4911 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4912 return MakeCXCursor(S->begin()[index], TU);
4913
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004914 const Decl *D = Storage.get<const Decl *>();
4915 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004916 // FIXME: This is, unfortunately, linear time.
4917 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4918 std::advance(Pos, index);
4919 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4920 }
4921
4922 return clang_getNullCursor();
4923}
4924
4925void clang_getDefinitionSpellingAndExtent(CXCursor C,
4926 const char **startBuf,
4927 const char **endBuf,
4928 unsigned *startLine,
4929 unsigned *startColumn,
4930 unsigned *endLine,
4931 unsigned *endColumn) {
4932 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004933 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004934 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4935
4936 SourceManager &SM = FD->getASTContext().getSourceManager();
4937 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4938 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4939 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4940 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4941 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4942 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4943}
4944
4945
4946CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4947 unsigned PieceIndex) {
4948 RefNamePieces Pieces;
4949
4950 switch (C.kind) {
4951 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004952 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4954 E->getQualifierLoc().getSourceRange());
4955 break;
4956
4957 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004958 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004959 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4960 E->getQualifierLoc().getSourceRange(),
4961 E->getOptionalExplicitTemplateArgs());
4962 break;
4963
4964 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004965 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004966 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004967 const Expr *Callee = OCE->getCallee();
4968 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004969 Callee = ICE->getSubExpr();
4970
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004971 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004972 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4973 DRE->getQualifierLoc().getSourceRange());
4974 }
4975 break;
4976
4977 default:
4978 break;
4979 }
4980
4981 if (Pieces.empty()) {
4982 if (PieceIndex == 0)
4983 return clang_getCursorExtent(C);
4984 } else if (PieceIndex < Pieces.size()) {
4985 SourceRange R = Pieces[PieceIndex];
4986 if (R.isValid())
4987 return cxloc::translateSourceRange(getCursorContext(C), R);
4988 }
4989
4990 return clang_getNullRange();
4991}
4992
4993void clang_enableStackTraces(void) {
4994 llvm::sys::PrintStackTraceOnErrorSignal();
4995}
4996
4997void clang_executeOnThread(void (*fn)(void*), void *user_data,
4998 unsigned stack_size) {
4999 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5000}
5001
5002} // end: extern "C"
5003
5004//===----------------------------------------------------------------------===//
5005// Token-based Operations.
5006//===----------------------------------------------------------------------===//
5007
5008/* CXToken layout:
5009 * int_data[0]: a CXTokenKind
5010 * int_data[1]: starting token location
5011 * int_data[2]: token length
5012 * int_data[3]: reserved
5013 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5014 * otherwise unused.
5015 */
5016extern "C" {
5017
5018CXTokenKind clang_getTokenKind(CXToken CXTok) {
5019 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5020}
5021
5022CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5023 switch (clang_getTokenKind(CXTok)) {
5024 case CXToken_Identifier:
5025 case CXToken_Keyword:
5026 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005027 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 ->getNameStart());
5029
5030 case CXToken_Literal: {
5031 // We have stashed the starting pointer in the ptr_data field. Use it.
5032 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005033 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005034 }
5035
5036 case CXToken_Punctuation:
5037 case CXToken_Comment:
5038 break;
5039 }
5040
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005041 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005042 LOG_BAD_TU(TU);
5043 return cxstring::createEmpty();
5044 }
5045
Guy Benyei11169dd2012-12-18 14:30:41 +00005046 // We have to find the starting buffer pointer the hard way, by
5047 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005048 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005050 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005051
5052 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5053 std::pair<FileID, unsigned> LocInfo
5054 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5055 bool Invalid = false;
5056 StringRef Buffer
5057 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5058 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005059 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005060
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005061 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005062}
5063
5064CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005065 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005066 LOG_BAD_TU(TU);
5067 return clang_getNullLocation();
5068 }
5069
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005070 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005071 if (!CXXUnit)
5072 return clang_getNullLocation();
5073
5074 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5075 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5076}
5077
5078CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005079 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005080 LOG_BAD_TU(TU);
5081 return clang_getNullRange();
5082 }
5083
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005084 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005085 if (!CXXUnit)
5086 return clang_getNullRange();
5087
5088 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5089 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5090}
5091
5092static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5093 SmallVectorImpl<CXToken> &CXTokens) {
5094 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5095 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005096 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005097 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005098 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005099
5100 // Cannot tokenize across files.
5101 if (BeginLocInfo.first != EndLocInfo.first)
5102 return;
5103
5104 // Create a lexer
5105 bool Invalid = false;
5106 StringRef Buffer
5107 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5108 if (Invalid)
5109 return;
5110
5111 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5112 CXXUnit->getASTContext().getLangOpts(),
5113 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5114 Lex.SetCommentRetentionState(true);
5115
5116 // Lex tokens until we hit the end of the range.
5117 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5118 Token Tok;
5119 bool previousWasAt = false;
5120 do {
5121 // Lex the next token
5122 Lex.LexFromRawLexer(Tok);
5123 if (Tok.is(tok::eof))
5124 break;
5125
5126 // Initialize the CXToken.
5127 CXToken CXTok;
5128
5129 // - Common fields
5130 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5131 CXTok.int_data[2] = Tok.getLength();
5132 CXTok.int_data[3] = 0;
5133
5134 // - Kind-specific fields
5135 if (Tok.isLiteral()) {
5136 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005137 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 } else if (Tok.is(tok::raw_identifier)) {
5139 // Lookup the identifier to determine whether we have a keyword.
5140 IdentifierInfo *II
5141 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5142
5143 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5144 CXTok.int_data[0] = CXToken_Keyword;
5145 }
5146 else {
5147 CXTok.int_data[0] = Tok.is(tok::identifier)
5148 ? CXToken_Identifier
5149 : CXToken_Keyword;
5150 }
5151 CXTok.ptr_data = II;
5152 } else if (Tok.is(tok::comment)) {
5153 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005154 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005155 } else {
5156 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005157 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 }
5159 CXTokens.push_back(CXTok);
5160 previousWasAt = Tok.is(tok::at);
5161 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5162}
5163
5164void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5165 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005166 LOG_FUNC_SECTION {
5167 *Log << TU << ' ' << Range;
5168 }
5169
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005171 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 if (NumTokens)
5173 *NumTokens = 0;
5174
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005175 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005176 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005177 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005178 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005179
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005180 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005181 if (!CXXUnit || !Tokens || !NumTokens)
5182 return;
5183
5184 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5185
5186 SourceRange R = cxloc::translateCXSourceRange(Range);
5187 if (R.isInvalid())
5188 return;
5189
5190 SmallVector<CXToken, 32> CXTokens;
5191 getTokens(CXXUnit, R, CXTokens);
5192
5193 if (CXTokens.empty())
5194 return;
5195
5196 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5197 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5198 *NumTokens = CXTokens.size();
5199}
5200
5201void clang_disposeTokens(CXTranslationUnit TU,
5202 CXToken *Tokens, unsigned NumTokens) {
5203 free(Tokens);
5204}
5205
5206} // end: extern "C"
5207
5208//===----------------------------------------------------------------------===//
5209// Token annotation APIs.
5210//===----------------------------------------------------------------------===//
5211
Guy Benyei11169dd2012-12-18 14:30:41 +00005212static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5213 CXCursor parent,
5214 CXClientData client_data);
5215static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5216 CXClientData client_data);
5217
5218namespace {
5219class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 CXToken *Tokens;
5221 CXCursor *Cursors;
5222 unsigned NumTokens;
5223 unsigned TokIdx;
5224 unsigned PreprocessingTokIdx;
5225 CursorVisitor AnnotateVis;
5226 SourceManager &SrcMgr;
5227 bool HasContextSensitiveKeywords;
5228
5229 struct PostChildrenInfo {
5230 CXCursor Cursor;
5231 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005232 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005233 unsigned BeforeChildrenTokenIdx;
5234 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005235 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005236
5237 CXToken &getTok(unsigned Idx) {
5238 assert(Idx < NumTokens);
5239 return Tokens[Idx];
5240 }
5241 const CXToken &getTok(unsigned Idx) const {
5242 assert(Idx < NumTokens);
5243 return Tokens[Idx];
5244 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005245 bool MoreTokens() const { return TokIdx < NumTokens; }
5246 unsigned NextToken() const { return TokIdx; }
5247 void AdvanceToken() { ++TokIdx; }
5248 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005249 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 }
5251 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005252 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005253 }
5254 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005255 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 }
5257
5258 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005259 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 SourceRange);
5261
5262public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005263 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005264 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005265 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005267 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 AnnotateTokensVisitor, this,
5269 /*VisitPreprocessorLast=*/true,
5270 /*VisitIncludedEntities=*/false,
5271 RegionOfInterest,
5272 /*VisitDeclsOnly=*/false,
5273 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005274 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 HasContextSensitiveKeywords(false) { }
5276
5277 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5278 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5279 bool postVisitChildren(CXCursor cursor);
5280 void AnnotateTokens();
5281
5282 /// \brief Determine whether the annotator saw any cursors that have
5283 /// context-sensitive keywords.
5284 bool hasContextSensitiveKeywords() const {
5285 return HasContextSensitiveKeywords;
5286 }
5287
5288 ~AnnotateTokensWorker() {
5289 assert(PostChildrenInfos.empty());
5290 }
5291};
5292}
5293
5294void AnnotateTokensWorker::AnnotateTokens() {
5295 // Walk the AST within the region of interest, annotating tokens
5296 // along the way.
5297 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005298}
Guy Benyei11169dd2012-12-18 14:30:41 +00005299
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005300static inline void updateCursorAnnotation(CXCursor &Cursor,
5301 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005302 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005304 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005305}
5306
5307/// \brief It annotates and advances tokens with a cursor until the comparison
5308//// between the cursor location and the source range is the same as
5309/// \arg compResult.
5310///
5311/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5312/// Pass RangeOverlap to annotate tokens inside a range.
5313void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5314 RangeComparisonResult compResult,
5315 SourceRange range) {
5316 while (MoreTokens()) {
5317 const unsigned I = NextToken();
5318 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005319 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5320 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005321
5322 SourceLocation TokLoc = GetTokenLoc(I);
5323 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005324 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005325 AdvanceToken();
5326 continue;
5327 }
5328 break;
5329 }
5330}
5331
5332/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005333/// \returns true if it advanced beyond all macro tokens, false otherwise.
5334bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005335 CXCursor updateC,
5336 RangeComparisonResult compResult,
5337 SourceRange range) {
5338 assert(MoreTokens());
5339 assert(isFunctionMacroToken(NextToken()) &&
5340 "Should be called only for macro arg tokens");
5341
5342 // This works differently than annotateAndAdvanceTokens; because expanded
5343 // macro arguments can have arbitrary translation-unit source order, we do not
5344 // advance the token index one by one until a token fails the range test.
5345 // We only advance once past all of the macro arg tokens if all of them
5346 // pass the range test. If one of them fails we keep the token index pointing
5347 // at the start of the macro arg tokens so that the failing token will be
5348 // annotated by a subsequent annotation try.
5349
5350 bool atLeastOneCompFail = false;
5351
5352 unsigned I = NextToken();
5353 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5354 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5355 if (TokLoc.isFileID())
5356 continue; // not macro arg token, it's parens or comma.
5357 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5358 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5359 Cursors[I] = updateC;
5360 } else
5361 atLeastOneCompFail = true;
5362 }
5363
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005364 if (atLeastOneCompFail)
5365 return false;
5366
5367 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5368 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005369}
5370
5371enum CXChildVisitResult
5372AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 SourceRange cursorRange = getRawCursorExtent(cursor);
5374 if (cursorRange.isInvalid())
5375 return CXChildVisit_Recurse;
5376
5377 if (!HasContextSensitiveKeywords) {
5378 // Objective-C properties can have context-sensitive keywords.
5379 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005380 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005381 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5382 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5383 }
5384 // Objective-C methods can have context-sensitive keywords.
5385 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5386 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005387 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005388 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5389 if (Method->getObjCDeclQualifier())
5390 HasContextSensitiveKeywords = true;
5391 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005392 for (const auto *P : Method->params()) {
5393 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005394 HasContextSensitiveKeywords = true;
5395 break;
5396 }
5397 }
5398 }
5399 }
5400 }
5401 // C++ methods can have context-sensitive keywords.
5402 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005403 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005404 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5405 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5406 HasContextSensitiveKeywords = true;
5407 }
5408 }
5409 // C++ classes can have context-sensitive keywords.
5410 else if (cursor.kind == CXCursor_StructDecl ||
5411 cursor.kind == CXCursor_ClassDecl ||
5412 cursor.kind == CXCursor_ClassTemplate ||
5413 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005414 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005415 if (D->hasAttr<FinalAttr>())
5416 HasContextSensitiveKeywords = true;
5417 }
5418 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005419
5420 // Don't override a property annotation with its getter/setter method.
5421 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5422 parent.kind == CXCursor_ObjCPropertyDecl)
5423 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005424
5425 if (clang_isPreprocessing(cursor.kind)) {
5426 // Items in the preprocessing record are kept separate from items in
5427 // declarations, so we keep a separate token index.
5428 unsigned SavedTokIdx = TokIdx;
5429 TokIdx = PreprocessingTokIdx;
5430
5431 // Skip tokens up until we catch up to the beginning of the preprocessing
5432 // entry.
5433 while (MoreTokens()) {
5434 const unsigned I = NextToken();
5435 SourceLocation TokLoc = GetTokenLoc(I);
5436 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5437 case RangeBefore:
5438 AdvanceToken();
5439 continue;
5440 case RangeAfter:
5441 case RangeOverlap:
5442 break;
5443 }
5444 break;
5445 }
5446
5447 // Look at all of the tokens within this range.
5448 while (MoreTokens()) {
5449 const unsigned I = NextToken();
5450 SourceLocation TokLoc = GetTokenLoc(I);
5451 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5452 case RangeBefore:
5453 llvm_unreachable("Infeasible");
5454 case RangeAfter:
5455 break;
5456 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005457 // For macro expansions, just note where the beginning of the macro
5458 // expansion occurs.
5459 if (cursor.kind == CXCursor_MacroExpansion) {
5460 if (TokLoc == cursorRange.getBegin())
5461 Cursors[I] = cursor;
5462 AdvanceToken();
5463 break;
5464 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005465 // We may have already annotated macro names inside macro definitions.
5466 if (Cursors[I].kind != CXCursor_MacroExpansion)
5467 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005468 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 continue;
5470 }
5471 break;
5472 }
5473
5474 // Save the preprocessing token index; restore the non-preprocessing
5475 // token index.
5476 PreprocessingTokIdx = TokIdx;
5477 TokIdx = SavedTokIdx;
5478 return CXChildVisit_Recurse;
5479 }
5480
5481 if (cursorRange.isInvalid())
5482 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005483
5484 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005486 const enum CXCursorKind K = clang_getCursorKind(parent);
5487 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005488 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5489 // Attributes are annotated out-of-order, skip tokens until we reach it.
5490 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 ? clang_getNullCursor() : parent;
5492
5493 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5494
5495 // Avoid having the cursor of an expression "overwrite" the annotation of the
5496 // variable declaration that it belongs to.
5497 // This can happen for C++ constructor expressions whose range generally
5498 // include the variable declaration, e.g.:
5499 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005500 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005501 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005502 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005503 const unsigned I = NextToken();
5504 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5505 E->getLocStart() == D->getLocation() &&
5506 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005507 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005508 AdvanceToken();
5509 }
5510 }
5511 }
5512
5513 // Before recursing into the children keep some state that we are going
5514 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5515 // extra work after the child nodes are visited.
5516 // Note that we don't call VisitChildren here to avoid traversing statements
5517 // code-recursively which can blow the stack.
5518
5519 PostChildrenInfo Info;
5520 Info.Cursor = cursor;
5521 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005522 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005523 Info.BeforeChildrenTokenIdx = NextToken();
5524 PostChildrenInfos.push_back(Info);
5525
5526 return CXChildVisit_Recurse;
5527}
5528
5529bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5530 if (PostChildrenInfos.empty())
5531 return false;
5532 const PostChildrenInfo &Info = PostChildrenInfos.back();
5533 if (!clang_equalCursors(Info.Cursor, cursor))
5534 return false;
5535
5536 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5537 const unsigned AfterChildren = NextToken();
5538 SourceRange cursorRange = Info.CursorRange;
5539
5540 // Scan the tokens that are at the end of the cursor, but are not captured
5541 // but the child cursors.
5542 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5543
5544 // Scan the tokens that are at the beginning of the cursor, but are not
5545 // capture by the child cursors.
5546 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5547 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5548 break;
5549
5550 Cursors[I] = cursor;
5551 }
5552
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005553 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5554 // encountered the attribute cursor.
5555 if (clang_isAttribute(cursor.kind))
5556 TokIdx = Info.BeforeReachingCursorIdx;
5557
Guy Benyei11169dd2012-12-18 14:30:41 +00005558 PostChildrenInfos.pop_back();
5559 return false;
5560}
5561
5562static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5563 CXCursor parent,
5564 CXClientData client_data) {
5565 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5566}
5567
5568static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5569 CXClientData client_data) {
5570 return static_cast<AnnotateTokensWorker*>(client_data)->
5571 postVisitChildren(cursor);
5572}
5573
5574namespace {
5575
5576/// \brief Uses the macro expansions in the preprocessing record to find
5577/// and mark tokens that are macro arguments. This info is used by the
5578/// AnnotateTokensWorker.
5579class MarkMacroArgTokensVisitor {
5580 SourceManager &SM;
5581 CXToken *Tokens;
5582 unsigned NumTokens;
5583 unsigned CurIdx;
5584
5585public:
5586 MarkMacroArgTokensVisitor(SourceManager &SM,
5587 CXToken *tokens, unsigned numTokens)
5588 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5589
5590 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5591 if (cursor.kind != CXCursor_MacroExpansion)
5592 return CXChildVisit_Continue;
5593
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005594 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 if (macroRange.getBegin() == macroRange.getEnd())
5596 return CXChildVisit_Continue; // it's not a function macro.
5597
5598 for (; CurIdx < NumTokens; ++CurIdx) {
5599 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5600 macroRange.getBegin()))
5601 break;
5602 }
5603
5604 if (CurIdx == NumTokens)
5605 return CXChildVisit_Break;
5606
5607 for (; CurIdx < NumTokens; ++CurIdx) {
5608 SourceLocation tokLoc = getTokenLoc(CurIdx);
5609 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5610 break;
5611
5612 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5613 }
5614
5615 if (CurIdx == NumTokens)
5616 return CXChildVisit_Break;
5617
5618 return CXChildVisit_Continue;
5619 }
5620
5621private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005622 CXToken &getTok(unsigned Idx) {
5623 assert(Idx < NumTokens);
5624 return Tokens[Idx];
5625 }
5626 const CXToken &getTok(unsigned Idx) const {
5627 assert(Idx < NumTokens);
5628 return Tokens[Idx];
5629 }
5630
Guy Benyei11169dd2012-12-18 14:30:41 +00005631 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005632 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 }
5634
5635 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5636 // The third field is reserved and currently not used. Use it here
5637 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005638 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005639 }
5640};
5641
5642} // end anonymous namespace
5643
5644static CXChildVisitResult
5645MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5646 CXClientData client_data) {
5647 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5648 parent);
5649}
5650
5651namespace {
5652 struct clang_annotateTokens_Data {
5653 CXTranslationUnit TU;
5654 ASTUnit *CXXUnit;
5655 CXToken *Tokens;
5656 unsigned NumTokens;
5657 CXCursor *Cursors;
5658 };
5659}
5660
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005661/// \brief Used by \c annotatePreprocessorTokens.
5662/// \returns true if lexing was finished, false otherwise.
5663static bool lexNext(Lexer &Lex, Token &Tok,
5664 unsigned &NextIdx, unsigned NumTokens) {
5665 if (NextIdx >= NumTokens)
5666 return true;
5667
5668 ++NextIdx;
5669 Lex.LexFromRawLexer(Tok);
5670 if (Tok.is(tok::eof))
5671 return true;
5672
5673 return false;
5674}
5675
Guy Benyei11169dd2012-12-18 14:30:41 +00005676static void annotatePreprocessorTokens(CXTranslationUnit TU,
5677 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005678 CXCursor *Cursors,
5679 CXToken *Tokens,
5680 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005681 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005682
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005683 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005684 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5685 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005686 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005687 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005688 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005689
5690 if (BeginLocInfo.first != EndLocInfo.first)
5691 return;
5692
5693 StringRef Buffer;
5694 bool Invalid = false;
5695 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5696 if (Buffer.empty() || Invalid)
5697 return;
5698
5699 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5700 CXXUnit->getASTContext().getLangOpts(),
5701 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5702 Buffer.end());
5703 Lex.SetCommentRetentionState(true);
5704
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005705 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005706 // Lex tokens in raw mode until we hit the end of the range, to avoid
5707 // entering #includes or expanding macros.
5708 while (true) {
5709 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005710 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5711 break;
5712 unsigned TokIdx = NextIdx-1;
5713 assert(Tok.getLocation() ==
5714 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005715
5716 reprocess:
5717 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005718 // We have found a preprocessing directive. Annotate the tokens
5719 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 //
5721 // FIXME: Some simple tests here could identify macro definitions and
5722 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005723
5724 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005725 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5726 break;
5727
Craig Topper69186e72014-06-08 08:38:04 +00005728 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005729 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005730 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5731 break;
5732
5733 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005734 IdentifierInfo &II =
5735 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005736 SourceLocation MappedTokLoc =
5737 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5738 MI = getMacroInfo(II, MappedTokLoc, TU);
5739 }
5740 }
5741
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005742 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005743 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005744 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5745 finished = true;
5746 break;
5747 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005748 // If we are in a macro definition, check if the token was ever a
5749 // macro name and annotate it if that's the case.
5750 if (MI) {
5751 SourceLocation SaveLoc = Tok.getLocation();
5752 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5753 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5754 Tok.setLocation(SaveLoc);
5755 if (MacroDef)
5756 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5757 Tok.getLocation(), TU);
5758 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005759 } while (!Tok.isAtStartOfLine());
5760
5761 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5762 assert(TokIdx <= LastIdx);
5763 SourceLocation EndLoc =
5764 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5765 CXCursor Cursor =
5766 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5767
5768 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005769 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005770
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005771 if (finished)
5772 break;
5773 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005775 }
5776}
5777
5778// This gets run a separate thread to avoid stack blowout.
5779static void clang_annotateTokensImpl(void *UserData) {
5780 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5781 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5782 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5783 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5784 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5785
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005786 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005787 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5788 setThreadBackgroundPriority();
5789
5790 // Determine the region of interest, which contains all of the tokens.
5791 SourceRange RegionOfInterest;
5792 RegionOfInterest.setBegin(
5793 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5794 RegionOfInterest.setEnd(
5795 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5796 Tokens[NumTokens-1])));
5797
Guy Benyei11169dd2012-12-18 14:30:41 +00005798 // Relex the tokens within the source range to look for preprocessing
5799 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005800 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005801
5802 // If begin location points inside a macro argument, set it to the expansion
5803 // location so we can have the full context when annotating semantically.
5804 {
5805 SourceManager &SM = CXXUnit->getSourceManager();
5806 SourceLocation Loc =
5807 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5808 if (Loc.isMacroID())
5809 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5810 }
5811
Guy Benyei11169dd2012-12-18 14:30:41 +00005812 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5813 // Search and mark tokens that are macro argument expansions.
5814 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5815 Tokens, NumTokens);
5816 CursorVisitor MacroArgMarker(TU,
5817 MarkMacroArgTokensVisitorDelegate, &Visitor,
5818 /*VisitPreprocessorLast=*/true,
5819 /*VisitIncludedEntities=*/false,
5820 RegionOfInterest);
5821 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5822 }
5823
5824 // Annotate all of the source locations in the region of interest that map to
5825 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005826 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005827
5828 // FIXME: We use a ridiculous stack size here because the data-recursion
5829 // algorithm uses a large stack frame than the non-data recursive version,
5830 // and AnnotationTokensWorker currently transforms the data-recursion
5831 // algorithm back into a traditional recursion by explicitly calling
5832 // VisitChildren(). We will need to remove this explicit recursive call.
5833 W.AnnotateTokens();
5834
5835 // If we ran into any entities that involve context-sensitive keywords,
5836 // take another pass through the tokens to mark them as such.
5837 if (W.hasContextSensitiveKeywords()) {
5838 for (unsigned I = 0; I != NumTokens; ++I) {
5839 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5840 continue;
5841
5842 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5843 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005844 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005845 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5846 if (Property->getPropertyAttributesAsWritten() != 0 &&
5847 llvm::StringSwitch<bool>(II->getName())
5848 .Case("readonly", true)
5849 .Case("assign", true)
5850 .Case("unsafe_unretained", true)
5851 .Case("readwrite", true)
5852 .Case("retain", true)
5853 .Case("copy", true)
5854 .Case("nonatomic", true)
5855 .Case("atomic", true)
5856 .Case("getter", true)
5857 .Case("setter", true)
5858 .Case("strong", true)
5859 .Case("weak", true)
5860 .Default(false))
5861 Tokens[I].int_data[0] = CXToken_Keyword;
5862 }
5863 continue;
5864 }
5865
5866 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5867 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5868 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5869 if (llvm::StringSwitch<bool>(II->getName())
5870 .Case("in", true)
5871 .Case("out", true)
5872 .Case("inout", true)
5873 .Case("oneway", true)
5874 .Case("bycopy", true)
5875 .Case("byref", true)
5876 .Default(false))
5877 Tokens[I].int_data[0] = CXToken_Keyword;
5878 continue;
5879 }
5880
5881 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5882 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5883 Tokens[I].int_data[0] = CXToken_Keyword;
5884 continue;
5885 }
5886 }
5887 }
5888}
5889
5890extern "C" {
5891
5892void clang_annotateTokens(CXTranslationUnit TU,
5893 CXToken *Tokens, unsigned NumTokens,
5894 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005895 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005896 LOG_BAD_TU(TU);
5897 return;
5898 }
5899 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005900 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005902 }
5903
5904 LOG_FUNC_SECTION {
5905 *Log << TU << ' ';
5906 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5907 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5908 *Log << clang_getRange(bloc, eloc);
5909 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005910
5911 // Any token we don't specifically annotate will have a NULL cursor.
5912 CXCursor C = clang_getNullCursor();
5913 for (unsigned I = 0; I != NumTokens; ++I)
5914 Cursors[I] = C;
5915
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005916 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005917 if (!CXXUnit)
5918 return;
5919
5920 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5921
5922 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5923 llvm::CrashRecoveryContext CRC;
5924 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5925 GetSafetyThreadStackSize() * 2)) {
5926 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5927 }
5928}
5929
5930} // end: extern "C"
5931
5932//===----------------------------------------------------------------------===//
5933// Operations for querying linkage of a cursor.
5934//===----------------------------------------------------------------------===//
5935
5936extern "C" {
5937CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5938 if (!clang_isDeclaration(cursor.kind))
5939 return CXLinkage_Invalid;
5940
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005941 const Decl *D = cxcursor::getCursorDecl(cursor);
5942 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005943 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005944 case NoLinkage:
5945 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005946 case InternalLinkage: return CXLinkage_Internal;
5947 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5948 case ExternalLinkage: return CXLinkage_External;
5949 };
5950
5951 return CXLinkage_Invalid;
5952}
5953} // end: extern "C"
5954
5955//===----------------------------------------------------------------------===//
5956// Operations for querying language of a cursor.
5957//===----------------------------------------------------------------------===//
5958
5959static CXLanguageKind getDeclLanguage(const Decl *D) {
5960 if (!D)
5961 return CXLanguage_C;
5962
5963 switch (D->getKind()) {
5964 default:
5965 break;
5966 case Decl::ImplicitParam:
5967 case Decl::ObjCAtDefsField:
5968 case Decl::ObjCCategory:
5969 case Decl::ObjCCategoryImpl:
5970 case Decl::ObjCCompatibleAlias:
5971 case Decl::ObjCImplementation:
5972 case Decl::ObjCInterface:
5973 case Decl::ObjCIvar:
5974 case Decl::ObjCMethod:
5975 case Decl::ObjCProperty:
5976 case Decl::ObjCPropertyImpl:
5977 case Decl::ObjCProtocol:
5978 return CXLanguage_ObjC;
5979 case Decl::CXXConstructor:
5980 case Decl::CXXConversion:
5981 case Decl::CXXDestructor:
5982 case Decl::CXXMethod:
5983 case Decl::CXXRecord:
5984 case Decl::ClassTemplate:
5985 case Decl::ClassTemplatePartialSpecialization:
5986 case Decl::ClassTemplateSpecialization:
5987 case Decl::Friend:
5988 case Decl::FriendTemplate:
5989 case Decl::FunctionTemplate:
5990 case Decl::LinkageSpec:
5991 case Decl::Namespace:
5992 case Decl::NamespaceAlias:
5993 case Decl::NonTypeTemplateParm:
5994 case Decl::StaticAssert:
5995 case Decl::TemplateTemplateParm:
5996 case Decl::TemplateTypeParm:
5997 case Decl::UnresolvedUsingTypename:
5998 case Decl::UnresolvedUsingValue:
5999 case Decl::Using:
6000 case Decl::UsingDirective:
6001 case Decl::UsingShadow:
6002 return CXLanguage_CPlusPlus;
6003 }
6004
6005 return CXLanguage_C;
6006}
6007
6008extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006009
6010static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6011 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6012 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006013
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006014 switch (D->getAvailability()) {
6015 case AR_Available:
6016 case AR_NotYetIntroduced:
6017 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006018 return getCursorAvailabilityForDecl(
6019 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006020 return CXAvailability_Available;
6021
6022 case AR_Deprecated:
6023 return CXAvailability_Deprecated;
6024
6025 case AR_Unavailable:
6026 return CXAvailability_NotAvailable;
6027 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006028
6029 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006030}
6031
Guy Benyei11169dd2012-12-18 14:30:41 +00006032enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6033 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006034 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6035 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006036
6037 return CXAvailability_Available;
6038}
6039
6040static CXVersion convertVersion(VersionTuple In) {
6041 CXVersion Out = { -1, -1, -1 };
6042 if (In.empty())
6043 return Out;
6044
6045 Out.Major = In.getMajor();
6046
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006047 Optional<unsigned> Minor = In.getMinor();
6048 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006049 Out.Minor = *Minor;
6050 else
6051 return Out;
6052
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006053 Optional<unsigned> Subminor = In.getSubminor();
6054 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006055 Out.Subminor = *Subminor;
6056
6057 return Out;
6058}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006059
6060static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6061 int *always_deprecated,
6062 CXString *deprecated_message,
6063 int *always_unavailable,
6064 CXString *unavailable_message,
6065 CXPlatformAvailability *availability,
6066 int availability_size) {
6067 bool HadAvailAttr = false;
6068 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006069 for (auto A : D->attrs()) {
6070 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006071 HadAvailAttr = true;
6072 if (always_deprecated)
6073 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006074 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006075 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006076 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006077 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006078 continue;
6079 }
6080
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006081 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006082 HadAvailAttr = true;
6083 if (always_unavailable)
6084 *always_unavailable = 1;
6085 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006086 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006087 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6088 }
6089 continue;
6090 }
6091
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006092 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006093 HadAvailAttr = true;
6094 if (N < availability_size) {
6095 availability[N].Platform
6096 = cxstring::createDup(Avail->getPlatform()->getName());
6097 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6098 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6099 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6100 availability[N].Unavailable = Avail->getUnavailable();
6101 availability[N].Message = cxstring::createDup(Avail->getMessage());
6102 }
6103 ++N;
6104 }
6105 }
6106
6107 if (!HadAvailAttr)
6108 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6109 return getCursorPlatformAvailabilityForDecl(
6110 cast<Decl>(EnumConst->getDeclContext()),
6111 always_deprecated,
6112 deprecated_message,
6113 always_unavailable,
6114 unavailable_message,
6115 availability,
6116 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006117
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006118 return N;
6119}
6120
Guy Benyei11169dd2012-12-18 14:30:41 +00006121int clang_getCursorPlatformAvailability(CXCursor cursor,
6122 int *always_deprecated,
6123 CXString *deprecated_message,
6124 int *always_unavailable,
6125 CXString *unavailable_message,
6126 CXPlatformAvailability *availability,
6127 int availability_size) {
6128 if (always_deprecated)
6129 *always_deprecated = 0;
6130 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006131 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006132 if (always_unavailable)
6133 *always_unavailable = 0;
6134 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006135 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006136
Guy Benyei11169dd2012-12-18 14:30:41 +00006137 if (!clang_isDeclaration(cursor.kind))
6138 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006139
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006140 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006141 if (!D)
6142 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006143
6144 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6145 deprecated_message,
6146 always_unavailable,
6147 unavailable_message,
6148 availability,
6149 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006150}
6151
6152void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6153 clang_disposeString(availability->Platform);
6154 clang_disposeString(availability->Message);
6155}
6156
6157CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6158 if (clang_isDeclaration(cursor.kind))
6159 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6160
6161 return CXLanguage_Invalid;
6162}
6163
6164 /// \brief If the given cursor is the "templated" declaration
6165 /// descibing a class or function template, return the class or
6166 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006167static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006168 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006169 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006170
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006171 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006172 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6173 return FunTmpl;
6174
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006175 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6177 return ClassTmpl;
6178
6179 return D;
6180}
6181
6182CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6183 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006184 if (const Decl *D = getCursorDecl(cursor)) {
6185 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006186 if (!DC)
6187 return clang_getNullCursor();
6188
6189 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6190 getCursorTU(cursor));
6191 }
6192 }
6193
6194 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006195 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006196 return MakeCXCursor(D, getCursorTU(cursor));
6197 }
6198
6199 return clang_getNullCursor();
6200}
6201
6202CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6203 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006204 if (const Decl *D = getCursorDecl(cursor)) {
6205 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006206 if (!DC)
6207 return clang_getNullCursor();
6208
6209 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6210 getCursorTU(cursor));
6211 }
6212 }
6213
6214 // FIXME: Note that we can't easily compute the lexical context of a
6215 // statement or expression, so we return nothing.
6216 return clang_getNullCursor();
6217}
6218
6219CXFile clang_getIncludedFile(CXCursor cursor) {
6220 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006221 return nullptr;
6222
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006223 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006224 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006225}
6226
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006227unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6228 if (C.kind != CXCursor_ObjCPropertyDecl)
6229 return CXObjCPropertyAttr_noattr;
6230
6231 unsigned Result = CXObjCPropertyAttr_noattr;
6232 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6233 ObjCPropertyDecl::PropertyAttributeKind Attr =
6234 PD->getPropertyAttributesAsWritten();
6235
6236#define SET_CXOBJCPROP_ATTR(A) \
6237 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6238 Result |= CXObjCPropertyAttr_##A
6239 SET_CXOBJCPROP_ATTR(readonly);
6240 SET_CXOBJCPROP_ATTR(getter);
6241 SET_CXOBJCPROP_ATTR(assign);
6242 SET_CXOBJCPROP_ATTR(readwrite);
6243 SET_CXOBJCPROP_ATTR(retain);
6244 SET_CXOBJCPROP_ATTR(copy);
6245 SET_CXOBJCPROP_ATTR(nonatomic);
6246 SET_CXOBJCPROP_ATTR(setter);
6247 SET_CXOBJCPROP_ATTR(atomic);
6248 SET_CXOBJCPROP_ATTR(weak);
6249 SET_CXOBJCPROP_ATTR(strong);
6250 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6251#undef SET_CXOBJCPROP_ATTR
6252
6253 return Result;
6254}
6255
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006256unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6257 if (!clang_isDeclaration(C.kind))
6258 return CXObjCDeclQualifier_None;
6259
6260 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6261 const Decl *D = getCursorDecl(C);
6262 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6263 QT = MD->getObjCDeclQualifier();
6264 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6265 QT = PD->getObjCDeclQualifier();
6266 if (QT == Decl::OBJC_TQ_None)
6267 return CXObjCDeclQualifier_None;
6268
6269 unsigned Result = CXObjCDeclQualifier_None;
6270 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6271 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6272 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6273 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6274 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6275 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6276
6277 return Result;
6278}
6279
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006280unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6281 if (!clang_isDeclaration(C.kind))
6282 return 0;
6283
6284 const Decl *D = getCursorDecl(C);
6285 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6286 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6287 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6288 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6289
6290 return 0;
6291}
6292
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006293unsigned clang_Cursor_isVariadic(CXCursor C) {
6294 if (!clang_isDeclaration(C.kind))
6295 return 0;
6296
6297 const Decl *D = getCursorDecl(C);
6298 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6299 return FD->isVariadic();
6300 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6301 return MD->isVariadic();
6302
6303 return 0;
6304}
6305
Guy Benyei11169dd2012-12-18 14:30:41 +00006306CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6307 if (!clang_isDeclaration(C.kind))
6308 return clang_getNullRange();
6309
6310 const Decl *D = getCursorDecl(C);
6311 ASTContext &Context = getCursorContext(C);
6312 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6313 if (!RC)
6314 return clang_getNullRange();
6315
6316 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6317}
6318
6319CXString clang_Cursor_getRawCommentText(CXCursor C) {
6320 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006321 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006322
6323 const Decl *D = getCursorDecl(C);
6324 ASTContext &Context = getCursorContext(C);
6325 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6326 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6327 StringRef();
6328
6329 // Don't duplicate the string because RawText points directly into source
6330 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006331 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006332}
6333
6334CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6335 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006336 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006337
6338 const Decl *D = getCursorDecl(C);
6339 const ASTContext &Context = getCursorContext(C);
6340 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6341
6342 if (RC) {
6343 StringRef BriefText = RC->getBriefText(Context);
6344
6345 // Don't duplicate the string because RawComment ensures that this memory
6346 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006347 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006348 }
6349
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006350 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006351}
6352
Guy Benyei11169dd2012-12-18 14:30:41 +00006353CXModule clang_Cursor_getModule(CXCursor C) {
6354 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006355 if (const ImportDecl *ImportD =
6356 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006357 return ImportD->getImportedModule();
6358 }
6359
Craig Topper69186e72014-06-08 08:38:04 +00006360 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006361}
6362
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006363CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6364 if (isNotUsableTU(TU)) {
6365 LOG_BAD_TU(TU);
6366 return nullptr;
6367 }
6368 if (!File)
6369 return nullptr;
6370 FileEntry *FE = static_cast<FileEntry *>(File);
6371
6372 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6373 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6374 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6375
6376 if (Module *Mod = Header.getModule()) {
6377 if (Header.getRole() != ModuleMap::ExcludedHeader)
6378 return Mod;
6379 }
6380 return nullptr;
6381}
6382
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006383CXFile clang_Module_getASTFile(CXModule CXMod) {
6384 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006385 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006386 Module *Mod = static_cast<Module*>(CXMod);
6387 return const_cast<FileEntry *>(Mod->getASTFile());
6388}
6389
Guy Benyei11169dd2012-12-18 14:30:41 +00006390CXModule clang_Module_getParent(CXModule CXMod) {
6391 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006392 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006393 Module *Mod = static_cast<Module*>(CXMod);
6394 return Mod->Parent;
6395}
6396
6397CXString clang_Module_getName(CXModule CXMod) {
6398 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006399 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006400 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006401 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006402}
6403
6404CXString clang_Module_getFullName(CXModule CXMod) {
6405 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006406 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006407 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006408 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006409}
6410
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006411int clang_Module_isSystem(CXModule CXMod) {
6412 if (!CXMod)
6413 return 0;
6414 Module *Mod = static_cast<Module*>(CXMod);
6415 return Mod->IsSystem;
6416}
6417
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006418unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6419 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006420 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006421 LOG_BAD_TU(TU);
6422 return 0;
6423 }
6424 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006425 return 0;
6426 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006427 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6428 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6429 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006430}
6431
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006432CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6433 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006434 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006435 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006436 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006437 }
6438 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006439 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006440 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006441 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006442
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006443 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6444 if (Index < TopHeaders.size())
6445 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006446
Craig Topper69186e72014-06-08 08:38:04 +00006447 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006448}
6449
6450} // end: extern "C"
6451
6452//===----------------------------------------------------------------------===//
6453// C++ AST instrospection.
6454//===----------------------------------------------------------------------===//
6455
6456extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006457unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6458 if (!clang_isDeclaration(C.kind))
6459 return 0;
6460
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006461 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006462 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006463 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006464 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6465}
6466
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006467unsigned clang_CXXMethod_isConst(CXCursor C) {
6468 if (!clang_isDeclaration(C.kind))
6469 return 0;
6470
6471 const Decl *D = cxcursor::getCursorDecl(C);
6472 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006473 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006474 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6475}
6476
Guy Benyei11169dd2012-12-18 14:30:41 +00006477unsigned clang_CXXMethod_isStatic(CXCursor C) {
6478 if (!clang_isDeclaration(C.kind))
6479 return 0;
6480
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006481 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006482 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006483 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006484 return (Method && Method->isStatic()) ? 1 : 0;
6485}
6486
6487unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6488 if (!clang_isDeclaration(C.kind))
6489 return 0;
6490
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006491 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006492 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006493 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006494 return (Method && Method->isVirtual()) ? 1 : 0;
6495}
6496} // end: extern "C"
6497
6498//===----------------------------------------------------------------------===//
6499// Attribute introspection.
6500//===----------------------------------------------------------------------===//
6501
6502extern "C" {
6503CXType clang_getIBOutletCollectionType(CXCursor C) {
6504 if (C.kind != CXCursor_IBOutletCollectionAttr)
6505 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6506
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006507 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006508 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6509
6510 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6511}
6512} // end: extern "C"
6513
6514//===----------------------------------------------------------------------===//
6515// Inspecting memory usage.
6516//===----------------------------------------------------------------------===//
6517
6518typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6519
6520static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6521 enum CXTUResourceUsageKind k,
6522 unsigned long amount) {
6523 CXTUResourceUsageEntry entry = { k, amount };
6524 entries.push_back(entry);
6525}
6526
6527extern "C" {
6528
6529const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6530 const char *str = "";
6531 switch (kind) {
6532 case CXTUResourceUsage_AST:
6533 str = "ASTContext: expressions, declarations, and types";
6534 break;
6535 case CXTUResourceUsage_Identifiers:
6536 str = "ASTContext: identifiers";
6537 break;
6538 case CXTUResourceUsage_Selectors:
6539 str = "ASTContext: selectors";
6540 break;
6541 case CXTUResourceUsage_GlobalCompletionResults:
6542 str = "Code completion: cached global results";
6543 break;
6544 case CXTUResourceUsage_SourceManagerContentCache:
6545 str = "SourceManager: content cache allocator";
6546 break;
6547 case CXTUResourceUsage_AST_SideTables:
6548 str = "ASTContext: side tables";
6549 break;
6550 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6551 str = "SourceManager: malloc'ed memory buffers";
6552 break;
6553 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6554 str = "SourceManager: mmap'ed memory buffers";
6555 break;
6556 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6557 str = "ExternalASTSource: malloc'ed memory buffers";
6558 break;
6559 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6560 str = "ExternalASTSource: mmap'ed memory buffers";
6561 break;
6562 case CXTUResourceUsage_Preprocessor:
6563 str = "Preprocessor: malloc'ed memory";
6564 break;
6565 case CXTUResourceUsage_PreprocessingRecord:
6566 str = "Preprocessor: PreprocessingRecord";
6567 break;
6568 case CXTUResourceUsage_SourceManager_DataStructures:
6569 str = "SourceManager: data structures and tables";
6570 break;
6571 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6572 str = "Preprocessor: header search tables";
6573 break;
6574 }
6575 return str;
6576}
6577
6578CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006579 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006580 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006581 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006582 return usage;
6583 }
6584
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006585 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006586 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006587 ASTContext &astContext = astUnit->getASTContext();
6588
6589 // How much memory is used by AST nodes and types?
6590 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6591 (unsigned long) astContext.getASTAllocatedMemory());
6592
6593 // How much memory is used by identifiers?
6594 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6595 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6596
6597 // How much memory is used for selectors?
6598 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6599 (unsigned long) astContext.Selectors.getTotalMemory());
6600
6601 // How much memory is used by ASTContext's side tables?
6602 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6603 (unsigned long) astContext.getSideTableAllocatedMemory());
6604
6605 // How much memory is used for caching global code completion results?
6606 unsigned long completionBytes = 0;
6607 if (GlobalCodeCompletionAllocator *completionAllocator =
6608 astUnit->getCachedCompletionAllocator().getPtr()) {
6609 completionBytes = completionAllocator->getTotalMemory();
6610 }
6611 createCXTUResourceUsageEntry(*entries,
6612 CXTUResourceUsage_GlobalCompletionResults,
6613 completionBytes);
6614
6615 // How much memory is being used by SourceManager's content cache?
6616 createCXTUResourceUsageEntry(*entries,
6617 CXTUResourceUsage_SourceManagerContentCache,
6618 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6619
6620 // How much memory is being used by the MemoryBuffer's in SourceManager?
6621 const SourceManager::MemoryBufferSizes &srcBufs =
6622 astUnit->getSourceManager().getMemoryBufferSizes();
6623
6624 createCXTUResourceUsageEntry(*entries,
6625 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6626 (unsigned long) srcBufs.malloc_bytes);
6627 createCXTUResourceUsageEntry(*entries,
6628 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6629 (unsigned long) srcBufs.mmap_bytes);
6630 createCXTUResourceUsageEntry(*entries,
6631 CXTUResourceUsage_SourceManager_DataStructures,
6632 (unsigned long) astContext.getSourceManager()
6633 .getDataStructureSizes());
6634
6635 // How much memory is being used by the ExternalASTSource?
6636 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6637 const ExternalASTSource::MemoryBufferSizes &sizes =
6638 esrc->getMemoryBufferSizes();
6639
6640 createCXTUResourceUsageEntry(*entries,
6641 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6642 (unsigned long) sizes.malloc_bytes);
6643 createCXTUResourceUsageEntry(*entries,
6644 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6645 (unsigned long) sizes.mmap_bytes);
6646 }
6647
6648 // How much memory is being used by the Preprocessor?
6649 Preprocessor &pp = astUnit->getPreprocessor();
6650 createCXTUResourceUsageEntry(*entries,
6651 CXTUResourceUsage_Preprocessor,
6652 pp.getTotalMemory());
6653
6654 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6655 createCXTUResourceUsageEntry(*entries,
6656 CXTUResourceUsage_PreprocessingRecord,
6657 pRec->getTotalMemory());
6658 }
6659
6660 createCXTUResourceUsageEntry(*entries,
6661 CXTUResourceUsage_Preprocessor_HeaderSearch,
6662 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006663
Guy Benyei11169dd2012-12-18 14:30:41 +00006664 CXTUResourceUsage usage = { (void*) entries.get(),
6665 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006666 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006667 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006668 return usage;
6669}
6670
6671void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6672 if (usage.data)
6673 delete (MemUsageEntries*) usage.data;
6674}
6675
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006676CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6677 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006678 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006679 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006680
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006681 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006682 LOG_BAD_TU(TU);
6683 return skipped;
6684 }
6685
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006686 if (!file)
6687 return skipped;
6688
6689 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6690 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6691 if (!ppRec)
6692 return skipped;
6693
6694 ASTContext &Ctx = astUnit->getASTContext();
6695 SourceManager &sm = Ctx.getSourceManager();
6696 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6697 FileID wantedFileID = sm.translateFile(fileEntry);
6698
6699 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6700 std::vector<SourceRange> wantedRanges;
6701 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6702 i != ei; ++i) {
6703 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6704 wantedRanges.push_back(*i);
6705 }
6706
6707 skipped->count = wantedRanges.size();
6708 skipped->ranges = new CXSourceRange[skipped->count];
6709 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6710 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6711
6712 return skipped;
6713}
6714
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006715void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6716 if (ranges) {
6717 delete[] ranges->ranges;
6718 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006719 }
6720}
6721
Guy Benyei11169dd2012-12-18 14:30:41 +00006722} // end extern "C"
6723
6724void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6725 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6726 for (unsigned I = 0; I != Usage.numEntries; ++I)
6727 fprintf(stderr, " %s: %lu\n",
6728 clang_getTUResourceUsageName(Usage.entries[I].kind),
6729 Usage.entries[I].amount);
6730
6731 clang_disposeCXTUResourceUsage(Usage);
6732}
6733
6734//===----------------------------------------------------------------------===//
6735// Misc. utility functions.
6736//===----------------------------------------------------------------------===//
6737
6738/// Default to using an 8 MB stack size on "safety" threads.
6739static unsigned SafetyStackThreadSize = 8 << 20;
6740
6741namespace clang {
6742
6743bool RunSafely(llvm::CrashRecoveryContext &CRC,
6744 void (*Fn)(void*), void *UserData,
6745 unsigned Size) {
6746 if (!Size)
6747 Size = GetSafetyThreadStackSize();
6748 if (Size)
6749 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6750 return CRC.RunSafely(Fn, UserData);
6751}
6752
6753unsigned GetSafetyThreadStackSize() {
6754 return SafetyStackThreadSize;
6755}
6756
6757void SetSafetyThreadStackSize(unsigned Value) {
6758 SafetyStackThreadSize = Value;
6759}
6760
6761}
6762
6763void clang::setThreadBackgroundPriority() {
6764 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6765 return;
6766
6767 // FIXME: Move to llvm/Support and make it cross-platform.
6768#ifdef __APPLE__
6769 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6770#endif
6771}
6772
6773void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6774 if (!Unit)
6775 return;
6776
6777 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6778 DEnd = Unit->stored_diag_end();
6779 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006780 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006781 CXString Msg = clang_formatDiagnostic(&Diag,
6782 clang_defaultDiagnosticDisplayOptions());
6783 fprintf(stderr, "%s\n", clang_getCString(Msg));
6784 clang_disposeString(Msg);
6785 }
6786#ifdef LLVM_ON_WIN32
6787 // On Windows, force a flush, since there may be multiple copies of
6788 // stderr and stdout in the file system, all with different buffers
6789 // but writing to the same device.
6790 fflush(stderr);
6791#endif
6792}
6793
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006794MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6795 SourceLocation MacroDefLoc,
6796 CXTranslationUnit TU){
6797 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006798 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006799 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006800 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006801
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006802 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006803 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006804 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006805 if (MD) {
6806 for (MacroDirective::DefInfo
6807 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6808 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6809 return Def.getMacroInfo();
6810 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006811 }
6812
Craig Topper69186e72014-06-08 08:38:04 +00006813 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006814}
6815
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006816const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6817 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006818 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006819 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006820 const IdentifierInfo *II = MacroDef->getName();
6821 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006822 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006823
6824 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6825}
6826
6827MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6828 const Token &Tok,
6829 CXTranslationUnit TU) {
6830 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006831 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006832 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00006833 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006834
6835 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006836 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006837 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6838 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006839 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006840
6841 // Check that the token is inside the definition and not its argument list.
6842 SourceManager &SM = Unit->getSourceManager();
6843 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00006844 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006845 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00006846 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006847
6848 Preprocessor &PP = Unit->getPreprocessor();
6849 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6850 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00006851 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006852
Alp Toker2d57cea2014-05-17 04:53:25 +00006853 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006854 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006855 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006856
6857 // Check that the identifier is not one of the macro arguments.
6858 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00006859 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006860
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006861 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6862 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00006863 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006864
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006865 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006866}
6867
6868MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6869 SourceLocation Loc,
6870 CXTranslationUnit TU) {
6871 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006872 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006873
6874 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00006875 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006876 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006877 Preprocessor &PP = Unit->getPreprocessor();
6878 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00006879 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006880 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6881 Token Tok;
6882 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00006883 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006884
6885 return checkForMacroInMacroDefinition(MI, Tok, TU);
6886}
6887
Guy Benyei11169dd2012-12-18 14:30:41 +00006888extern "C" {
6889
6890CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006891 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006892}
6893
6894} // end: extern "C"
6895
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006896Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6897 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006898 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006899 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006900 if (Unit->isMainFileAST())
6901 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006902 return *this;
6903 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006904 } else {
6905 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006906 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006907 return *this;
6908}
6909
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006910Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6911 *this << FE->getName();
6912 return *this;
6913}
6914
6915Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6916 CXString cursorName = clang_getCursorDisplayName(cursor);
6917 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6918 clang_disposeString(cursorName);
6919 return *this;
6920}
6921
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006922Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6923 CXFile File;
6924 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00006925 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006926 CXString FileName = clang_getFileName(File);
6927 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6928 clang_disposeString(FileName);
6929 return *this;
6930}
6931
6932Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6933 CXSourceLocation BLoc = clang_getRangeStart(range);
6934 CXSourceLocation ELoc = clang_getRangeEnd(range);
6935
6936 CXFile BFile;
6937 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006938 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006939
6940 CXFile EFile;
6941 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00006942 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006943
6944 CXString BFileName = clang_getFileName(BFile);
6945 if (BFile == EFile) {
6946 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6947 BLine, BColumn, ELine, EColumn);
6948 } else {
6949 CXString EFileName = clang_getFileName(EFile);
6950 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6951 BLine, BColumn)
6952 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6953 ELine, EColumn);
6954 clang_disposeString(EFileName);
6955 }
6956 clang_disposeString(BFileName);
6957 return *this;
6958}
6959
6960Logger &cxindex::Logger::operator<<(CXString Str) {
6961 *this << clang_getCString(Str);
6962 return *this;
6963}
6964
6965Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6966 LogOS << Fmt;
6967 return *this;
6968}
6969
6970cxindex::Logger::~Logger() {
6971 LogOS.flush();
6972
Zachary Turnerf68823b2014-06-17 19:57:15 +00006973 llvm::sys::ScopedLock L(LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006974
6975 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6976
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006977 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006978 OS << "[libclang:" << Name << ':';
6979
6980 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00006981#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006982 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6983 OS << tid << ':';
6984#endif
6985
6986 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6987 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6988 OS << Msg.str() << '\n';
6989
6990 if (Trace) {
6991 llvm::sys::PrintStackTrace(stderr);
6992 OS << "--------------------------------------------------\n";
6993 }
6994}