blob: 6c887e188961cf80a5e4ee9724806fe824a76cd7 [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"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000243 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
244 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000245 PPRec, FID);
246}
247
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000248bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000249 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000250 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000251
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000252 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000253 SourceManager &SM = Unit->getSourceManager();
254
255 std::pair<FileID, unsigned>
256 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
257 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
258
259 if (End.first != Begin.first) {
260 // If the end does not reside in the same file, try to recover by
261 // picking the end of the file of begin location.
262 End.first = Begin.first;
263 End.second = SM.getFileIDSize(Begin.first);
264 }
265
266 assert(Begin.first == End.first);
267 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000268 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
270 FileID File = Begin.first;
271 unsigned Offset = Begin.second;
272 unsigned Length = End.second - Begin.second;
273
274 if (!VisitDeclsOnly && !VisitPreprocessorLast)
275 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000278 if (visitDeclsFromFileRegion(File, Offset, Length))
279 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000280
281 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000282 return visitPreprocessedEntitiesInRegion();
283
284 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000285}
286
287static bool isInLexicalContext(Decl *D, DeclContext *DC) {
288 if (!DC)
289 return false;
290
291 for (DeclContext *DeclDC = D->getLexicalDeclContext();
292 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
293 if (DeclDC == DC)
294 return true;
295 }
296 return false;
297}
298
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000299bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000300 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000301 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000302 SourceManager &SM = Unit->getSourceManager();
303 SourceRange Range = RegionOfInterest;
304
305 SmallVector<Decl *, 16> Decls;
306 Unit->findFileRegionDecls(File, Offset, Length, Decls);
307
308 // If we didn't find any file level decls for the file, try looking at the
309 // file that it was included from.
310 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
311 bool Invalid = false;
312 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
313 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000314 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315
316 SourceLocation Outer;
317 if (SLEntry.isFile())
318 Outer = SLEntry.getFile().getIncludeLoc();
319 else
320 Outer = SLEntry.getExpansion().getExpansionLocStart();
321 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000322 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000323
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000324 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000325 Length = 0;
326 Unit->findFileRegionDecls(File, Offset, Length, Decls);
327 }
328
329 assert(!Decls.empty());
330
331 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000332 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000333 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
334 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000335 Decl *D = *DIt;
336 if (D->getSourceRange().isInvalid())
337 continue;
338
339 if (isInLexicalContext(D, CurDC))
340 continue;
341
342 CurDC = dyn_cast<DeclContext>(D);
343
344 if (TagDecl *TD = dyn_cast<TagDecl>(D))
345 if (!TD->isFreeStanding())
346 continue;
347
348 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
349 if (CompRes == RangeBefore)
350 continue;
351 if (CompRes == RangeAfter)
352 break;
353
354 assert(CompRes == RangeOverlap);
355 VisitedAtLeastOnce = true;
356
357 if (isa<ObjCContainerDecl>(D)) {
358 FileDI_current = &DIt;
359 FileDE_current = DE;
360 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000361 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000362 }
363
364 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000365 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000366 }
367
368 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000369 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000370
371 // No Decls overlapped with the range. Move up the lexical context until there
372 // is a context that contains the range or we reach the translation unit
373 // level.
374 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
375 : (*(DIt-1))->getLexicalDeclContext();
376
377 while (DC && !DC->isTranslationUnit()) {
378 Decl *D = cast<Decl>(DC);
379 SourceRange CurDeclRange = D->getSourceRange();
380 if (CurDeclRange.isInvalid())
381 break;
382
383 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000384 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
385 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000386 }
387
388 DC = D->getLexicalDeclContext();
389 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000390
391 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000392}
393
394bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
395 if (!AU->getPreprocessor().getPreprocessingRecord())
396 return false;
397
398 PreprocessingRecord &PPRec
399 = *AU->getPreprocessor().getPreprocessingRecord();
400 SourceManager &SM = AU->getSourceManager();
401
402 if (RegionOfInterest.isValid()) {
403 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
404 SourceLocation B = MappedRange.getBegin();
405 SourceLocation E = MappedRange.getEnd();
406
407 if (AU->isInPreambleFileID(B)) {
408 if (SM.isLoadedSourceLocation(E))
409 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
410 PPRec, *this);
411
412 // Beginning of range lies in the preamble but it also extends beyond
413 // it into the main file. Split the range into 2 parts, one covering
414 // the preamble and another covering the main file. This allows subsequent
415 // calls to visitPreprocessedEntitiesInRange to accept a source range that
416 // lies in the same FileID, allowing it to skip preprocessed entities that
417 // do not come from the same FileID.
418 bool breaked =
419 visitPreprocessedEntitiesInRange(
420 SourceRange(B, AU->getEndOfPreambleFileID()),
421 PPRec, *this);
422 if (breaked) return true;
423 return visitPreprocessedEntitiesInRange(
424 SourceRange(AU->getStartOfMainFileID(), E),
425 PPRec, *this);
426 }
427
428 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
429 }
430
431 bool OnlyLocalDecls
432 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
433
434 if (OnlyLocalDecls)
435 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
436 PPRec);
437
438 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
439}
440
441template<typename InputIterator>
442bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
443 InputIterator Last,
444 PreprocessingRecord &PPRec,
445 FileID FID) {
446 for (; First != Last; ++First) {
447 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
448 continue;
449
450 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000451 if (!PPE)
452 continue;
453
Guy Benyei11169dd2012-12-18 14:30:41 +0000454 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
455 if (Visit(MakeMacroExpansionCursor(ME, TU)))
456 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000457
Guy Benyei11169dd2012-12-18 14:30:41 +0000458 continue;
459 }
Richard Smith66a81862015-05-04 02:25:31 +0000460
461 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000462 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
463 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000464
Guy Benyei11169dd2012-12-18 14:30:41 +0000465 continue;
466 }
467
468 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
469 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
470 return true;
471
472 continue;
473 }
474 }
475
476 return false;
477}
478
479/// \brief Visit the children of the given cursor.
480///
481/// \returns true if the visitation should be aborted, false if it
482/// should continue.
483bool CursorVisitor::VisitChildren(CXCursor Cursor) {
484 if (clang_isReference(Cursor.kind) &&
485 Cursor.kind != CXCursor_CXXBaseSpecifier) {
486 // By definition, references have no children.
487 return false;
488 }
489
490 // Set the Parent field to Cursor, then back to its old value once we're
491 // done.
492 SetParentRAII SetParent(Parent, StmtParent, Cursor);
493
494 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000495 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000496 if (!D)
497 return false;
498
499 return VisitAttributes(D) || Visit(D);
500 }
501
502 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(S);
505
506 return false;
507 }
508
509 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000510 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000511 return Visit(E);
512
513 return false;
514 }
515
516 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000517 CXTranslationUnit TU = getCursorTU(Cursor);
518 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000519
520 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
521 for (unsigned I = 0; I != 2; ++I) {
522 if (VisitOrder[I]) {
523 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
524 RegionOfInterest.isInvalid()) {
525 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
526 TLEnd = CXXUnit->top_level_end();
527 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000528 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000529 return true;
530 }
531 } else if (VisitDeclContext(
532 CXXUnit->getASTContext().getTranslationUnitDecl()))
533 return true;
534 continue;
535 }
536
537 // Walk the preprocessing record.
538 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
539 visitPreprocessedEntitiesInRegion();
540 }
541
542 return false;
543 }
544
545 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000546 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
548 return Visit(BaseTSInfo->getTypeLoc());
549 }
550 }
551 }
552
553 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000554 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000555 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000556 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000557 return Visit(cxcursor::MakeCursorObjCClassRef(
558 ObjT->getInterface(),
559 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000560 }
561
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000562 // If pointing inside a macro definition, check if the token is an identifier
563 // that was ever defined as a macro. In such a case, create a "pseudo" macro
564 // expansion cursor for that token.
565 SourceLocation BeginLoc = RegionOfInterest.getBegin();
566 if (Cursor.kind == CXCursor_MacroDefinition &&
567 BeginLoc == RegionOfInterest.getEnd()) {
568 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000569 const MacroInfo *MI =
570 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000571 if (MacroDefinitionRecord *MacroDef =
572 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000573 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
574 }
575
Guy Benyei11169dd2012-12-18 14:30:41 +0000576 // Nothing to visit at the moment.
577 return false;
578}
579
580bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
581 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
582 if (Visit(TSInfo->getTypeLoc()))
583 return true;
584
585 if (Stmt *Body = B->getBody())
586 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
587
588 return false;
589}
590
Ted Kremenek03325582013-02-21 01:29:01 +0000591Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000592 if (RegionOfInterest.isValid()) {
593 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
594 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000595 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000596
597 switch (CompareRegionOfInterest(Range)) {
598 case RangeBefore:
599 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000600 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000601
602 case RangeAfter:
603 // This declaration comes after the region of interest; we're done.
604 return false;
605
606 case RangeOverlap:
607 // This declaration overlaps the region of interest; visit it.
608 break;
609 }
610 }
611 return true;
612}
613
614bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
615 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
616
617 // FIXME: Eventually remove. This part of a hack to support proper
618 // iteration over all Decls contained lexically within an ObjC container.
619 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
620 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
621
622 for ( ; I != E; ++I) {
623 Decl *D = *I;
624 if (D->getLexicalDeclContext() != DC)
625 continue;
626 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
627
628 // Ignore synthesized ivars here, otherwise if we have something like:
629 // @synthesize prop = _prop;
630 // and '_prop' is not declared, we will encounter a '_prop' ivar before
631 // encountering the 'prop' synthesize declaration and we will think that
632 // we passed the region-of-interest.
633 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
634 if (ivarD->getSynthesize())
635 continue;
636 }
637
638 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
639 // declarations is a mismatch with the compiler semantics.
640 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
641 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
642 if (!ID->isThisDeclarationADefinition())
643 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
644
645 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
646 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
647 if (!PD->isThisDeclarationADefinition())
648 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
649 }
650
Ted Kremenek03325582013-02-21 01:29:01 +0000651 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000652 if (!V.hasValue())
653 continue;
654 if (!V.getValue())
655 return false;
656 if (Visit(Cursor, true))
657 return true;
658 }
659 return false;
660}
661
662bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
663 llvm_unreachable("Translation units are visited directly by Visit()");
664}
665
666bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
674 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
675 return Visit(TSInfo->getTypeLoc());
676
677 return false;
678}
679
680bool CursorVisitor::VisitTagDecl(TagDecl *D) {
681 return VisitDeclContext(D);
682}
683
684bool CursorVisitor::VisitClassTemplateSpecializationDecl(
685 ClassTemplateSpecializationDecl *D) {
686 bool ShouldVisitBody = false;
687 switch (D->getSpecializationKind()) {
688 case TSK_Undeclared:
689 case TSK_ImplicitInstantiation:
690 // Nothing to visit
691 return false;
692
693 case TSK_ExplicitInstantiationDeclaration:
694 case TSK_ExplicitInstantiationDefinition:
695 break;
696
697 case TSK_ExplicitSpecialization:
698 ShouldVisitBody = true;
699 break;
700 }
701
702 // Visit the template arguments used in the specialization.
703 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
704 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000705 if (TemplateSpecializationTypeLoc TSTLoc =
706 TL.getAs<TemplateSpecializationTypeLoc>()) {
707 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
708 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000709 return true;
710 }
711 }
712
713 if (ShouldVisitBody && VisitCXXRecordDecl(D))
714 return true;
715
716 return false;
717}
718
719bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
720 ClassTemplatePartialSpecializationDecl *D) {
721 // FIXME: Visit the "outer" template parameter lists on the TagDecl
722 // before visiting these template parameters.
723 if (VisitTemplateParameters(D->getTemplateParameters()))
724 return true;
725
726 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000727 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
728 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
729 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000730 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
731 return true;
732
733 return VisitCXXRecordDecl(D);
734}
735
736bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
737 // Visit the default argument.
738 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
739 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
740 if (Visit(DefArg->getTypeLoc()))
741 return true;
742
743 return false;
744}
745
746bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
747 if (Expr *Init = D->getInitExpr())
748 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
749 return false;
750}
751
752bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000753 unsigned NumParamList = DD->getNumTemplateParameterLists();
754 for (unsigned i = 0; i < NumParamList; i++) {
755 TemplateParameterList* Params = DD->getTemplateParameterList(i);
756 if (VisitTemplateParameters(Params))
757 return true;
758 }
759
Guy Benyei11169dd2012-12-18 14:30:41 +0000760 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
761 if (Visit(TSInfo->getTypeLoc()))
762 return true;
763
764 // Visit the nested-name-specifier, if present.
765 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
766 if (VisitNestedNameSpecifierLoc(QualifierLoc))
767 return true;
768
769 return false;
770}
771
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000772/// \brief Compare two base or member initializers based on their source order.
773static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
774 CXXCtorInitializer *const *Y) {
775 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
776}
777
Guy Benyei11169dd2012-12-18 14:30:41 +0000778bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000779 unsigned NumParamList = ND->getNumTemplateParameterLists();
780 for (unsigned i = 0; i < NumParamList; i++) {
781 TemplateParameterList* Params = ND->getTemplateParameterList(i);
782 if (VisitTemplateParameters(Params))
783 return true;
784 }
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
787 // Visit the function declaration's syntactic components in the order
788 // written. This requires a bit of work.
789 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000790 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000791
792 // If we have a function declared directly (without the use of a typedef),
793 // visit just the return type. Otherwise, just visit the function's type
794 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000795 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000796 (!FTL && Visit(TL)))
797 return true;
798
799 // Visit the nested-name-specifier, if present.
800 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
801 if (VisitNestedNameSpecifierLoc(QualifierLoc))
802 return true;
803
804 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000805 if (!isa<CXXDestructorDecl>(ND))
806 if (VisitDeclarationNameInfo(ND->getNameInfo()))
807 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000808
809 // FIXME: Visit explicitly-specified template arguments!
810
811 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000812 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 return true;
814
Bill Wendling44426052012-12-20 19:22:21 +0000815 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000816 }
817
818 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
819 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
820 // Find the initializers that were written in the source.
821 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000822 for (auto *I : Constructor->inits()) {
823 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 continue;
825
Aaron Ballman0ad78302014-03-13 17:34:31 +0000826 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000827 }
828
829 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000830 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
831 &CompareCXXCtorInitializers);
832
Guy Benyei11169dd2012-12-18 14:30:41 +0000833 // Visit the initializers in source order
834 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
835 CXXCtorInitializer *Init = WrittenInits[I];
836 if (Init->isAnyMemberInitializer()) {
837 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
838 Init->getMemberLocation(), TU)))
839 return true;
840 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
841 if (Visit(TInfo->getTypeLoc()))
842 return true;
843 }
844
845 // Visit the initializer value.
846 if (Expr *Initializer = Init->getInit())
847 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
848 return true;
849 }
850 }
851
852 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
853 return true;
854 }
855
856 return false;
857}
858
859bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
860 if (VisitDeclaratorDecl(D))
861 return true;
862
863 if (Expr *BitWidth = D->getBitWidth())
864 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
865
866 return false;
867}
868
869bool CursorVisitor::VisitVarDecl(VarDecl *D) {
870 if (VisitDeclaratorDecl(D))
871 return true;
872
873 if (Expr *Init = D->getInit())
874 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
875
876 return false;
877}
878
879bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
880 if (VisitDeclaratorDecl(D))
881 return true;
882
883 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
884 if (Expr *DefArg = D->getDefaultArgument())
885 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
886
887 return false;
888}
889
890bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
891 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
892 // before visiting these template parameters.
893 if (VisitTemplateParameters(D->getTemplateParameters()))
894 return true;
895
896 return VisitFunctionDecl(D->getTemplatedDecl());
897}
898
899bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
900 // FIXME: Visit the "outer" template parameter lists on the TagDecl
901 // before visiting these template parameters.
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 return VisitCXXRecordDecl(D->getTemplatedDecl());
906}
907
908bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
909 if (VisitTemplateParameters(D->getTemplateParameters()))
910 return true;
911
912 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
913 VisitTemplateArgumentLoc(D->getDefaultArgument()))
914 return true;
915
916 return false;
917}
918
919bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000920 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000921 if (Visit(TSInfo->getTypeLoc()))
922 return true;
923
Aaron Ballman43b68be2014-03-07 17:50:17 +0000924 for (const auto *P : ND->params()) {
925 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000926 return true;
927 }
928
929 if (ND->isThisDeclarationADefinition() &&
930 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
931 return true;
932
933 return false;
934}
935
936template <typename DeclIt>
937static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
938 SourceManager &SM, SourceLocation EndLoc,
939 SmallVectorImpl<Decl *> &Decls) {
940 DeclIt next = *DI_current;
941 while (++next != DE_current) {
942 Decl *D_next = *next;
943 if (!D_next)
944 break;
945 SourceLocation L = D_next->getLocStart();
946 if (!L.isValid())
947 break;
948 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
949 *DI_current = next;
950 Decls.push_back(D_next);
951 continue;
952 }
953 break;
954 }
955}
956
Guy Benyei11169dd2012-12-18 14:30:41 +0000957bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
958 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
959 // an @implementation can lexically contain Decls that are not properly
960 // nested in the AST. When we identify such cases, we need to retrofit
961 // this nesting here.
962 if (!DI_current && !FileDI_current)
963 return VisitDeclContext(D);
964
965 // Scan the Decls that immediately come after the container
966 // in the current DeclContext. If any fall within the
967 // container's lexical region, stash them into a vector
968 // for later processing.
969 SmallVector<Decl *, 24> DeclsInContainer;
970 SourceLocation EndLoc = D->getSourceRange().getEnd();
971 SourceManager &SM = AU->getSourceManager();
972 if (EndLoc.isValid()) {
973 if (DI_current) {
974 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
975 DeclsInContainer);
976 } else {
977 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
978 DeclsInContainer);
979 }
980 }
981
982 // The common case.
983 if (DeclsInContainer.empty())
984 return VisitDeclContext(D);
985
986 // Get all the Decls in the DeclContext, and sort them with the
987 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000988 for (auto *SubDecl : D->decls()) {
989 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
990 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000991 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000992 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000993 }
994
995 // Now sort the Decls so that they appear in lexical order.
996 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000997 [&SM](Decl *A, Decl *B) {
998 SourceLocation L_A = A->getLocStart();
999 SourceLocation L_B = B->getLocStart();
1000 assert(L_A.isValid() && L_B.isValid());
1001 return SM.isBeforeInTranslationUnit(L_A, L_B);
1002 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001003
1004 // Now visit the decls.
1005 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1006 E = DeclsInContainer.end(); I != E; ++I) {
1007 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001008 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001009 if (!V.hasValue())
1010 continue;
1011 if (!V.getValue())
1012 return false;
1013 if (Visit(Cursor, true))
1014 return true;
1015 }
1016 return false;
1017}
1018
1019bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1020 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1021 TU)))
1022 return true;
1023
1024 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1025 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1026 E = ND->protocol_end(); I != E; ++I, ++PL)
1027 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1028 return true;
1029
1030 return VisitObjCContainerDecl(ND);
1031}
1032
1033bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1034 if (!PID->isThisDeclarationADefinition())
1035 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1036
1037 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1038 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1039 E = PID->protocol_end(); I != E; ++I, ++PL)
1040 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1041 return true;
1042
1043 return VisitObjCContainerDecl(PID);
1044}
1045
1046bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1047 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1048 return true;
1049
1050 // FIXME: This implements a workaround with @property declarations also being
1051 // installed in the DeclContext for the @interface. Eventually this code
1052 // should be removed.
1053 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1054 if (!CDecl || !CDecl->IsClassExtension())
1055 return false;
1056
1057 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1058 if (!ID)
1059 return false;
1060
1061 IdentifierInfo *PropertyId = PD->getIdentifier();
1062 ObjCPropertyDecl *prevDecl =
1063 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1064
1065 if (!prevDecl)
1066 return false;
1067
1068 // Visit synthesized methods since they will be skipped when visiting
1069 // the @interface.
1070 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1071 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1072 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1073 return true;
1074
1075 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1076 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1077 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1078 return true;
1079
1080 return false;
1081}
1082
1083bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1084 if (!D->isThisDeclarationADefinition()) {
1085 // Forward declaration is treated like a reference.
1086 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1087 }
1088
1089 // Issue callbacks for super class.
1090 if (D->getSuperClass() &&
1091 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1092 D->getSuperClassLoc(),
1093 TU)))
1094 return true;
1095
1096 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1097 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1098 E = D->protocol_end(); I != E; ++I, ++PL)
1099 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1100 return true;
1101
1102 return VisitObjCContainerDecl(D);
1103}
1104
1105bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1106 return VisitObjCContainerDecl(D);
1107}
1108
1109bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1110 // 'ID' could be null when dealing with invalid code.
1111 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1112 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1113 return true;
1114
1115 return VisitObjCImplDecl(D);
1116}
1117
1118bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1119#if 0
1120 // Issue callbacks for super class.
1121 // FIXME: No source location information!
1122 if (D->getSuperClass() &&
1123 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1124 D->getSuperClassLoc(),
1125 TU)))
1126 return true;
1127#endif
1128
1129 return VisitObjCImplDecl(D);
1130}
1131
1132bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1133 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1134 if (PD->isIvarNameSpecified())
1135 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1136
1137 return false;
1138}
1139
1140bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1141 return VisitDeclContext(D);
1142}
1143
1144bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1145 // Visit nested-name-specifier.
1146 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1147 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1148 return true;
1149
1150 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1151 D->getTargetNameLoc(), TU));
1152}
1153
1154bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1155 // Visit nested-name-specifier.
1156 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1157 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1158 return true;
1159 }
1160
1161 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1162 return true;
1163
1164 return VisitDeclarationNameInfo(D->getNameInfo());
1165}
1166
1167bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1168 // Visit nested-name-specifier.
1169 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1170 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1171 return true;
1172
1173 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1174 D->getIdentLocation(), TU));
1175}
1176
1177bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1178 // Visit nested-name-specifier.
1179 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1180 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1181 return true;
1182 }
1183
1184 return VisitDeclarationNameInfo(D->getNameInfo());
1185}
1186
1187bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1188 UnresolvedUsingTypenameDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return false;
1195}
1196
1197bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1198 switch (Name.getName().getNameKind()) {
1199 case clang::DeclarationName::Identifier:
1200 case clang::DeclarationName::CXXLiteralOperatorName:
1201 case clang::DeclarationName::CXXOperatorName:
1202 case clang::DeclarationName::CXXUsingDirective:
1203 return false;
1204
1205 case clang::DeclarationName::CXXConstructorName:
1206 case clang::DeclarationName::CXXDestructorName:
1207 case clang::DeclarationName::CXXConversionFunctionName:
1208 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1209 return Visit(TSInfo->getTypeLoc());
1210 return false;
1211
1212 case clang::DeclarationName::ObjCZeroArgSelector:
1213 case clang::DeclarationName::ObjCOneArgSelector:
1214 case clang::DeclarationName::ObjCMultiArgSelector:
1215 // FIXME: Per-identifier location info?
1216 return false;
1217 }
1218
1219 llvm_unreachable("Invalid DeclarationName::Kind!");
1220}
1221
1222bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1223 SourceRange Range) {
1224 // FIXME: This whole routine is a hack to work around the lack of proper
1225 // source information in nested-name-specifiers (PR5791). Since we do have
1226 // a beginning source location, we can visit the first component of the
1227 // nested-name-specifier, if it's a single-token component.
1228 if (!NNS)
1229 return false;
1230
1231 // Get the first component in the nested-name-specifier.
1232 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1233 NNS = Prefix;
1234
1235 switch (NNS->getKind()) {
1236 case NestedNameSpecifier::Namespace:
1237 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1238 TU));
1239
1240 case NestedNameSpecifier::NamespaceAlias:
1241 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1242 Range.getBegin(), TU));
1243
1244 case NestedNameSpecifier::TypeSpec: {
1245 // If the type has a form where we know that the beginning of the source
1246 // range matches up with a reference cursor. Visit the appropriate reference
1247 // cursor.
1248 const Type *T = NNS->getAsType();
1249 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1250 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1251 if (const TagType *Tag = dyn_cast<TagType>(T))
1252 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1253 if (const TemplateSpecializationType *TST
1254 = dyn_cast<TemplateSpecializationType>(T))
1255 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1256 break;
1257 }
1258
1259 case NestedNameSpecifier::TypeSpecWithTemplate:
1260 case NestedNameSpecifier::Global:
1261 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001262 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001263 break;
1264 }
1265
1266 return false;
1267}
1268
1269bool
1270CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1271 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1272 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1273 Qualifiers.push_back(Qualifier);
1274
1275 while (!Qualifiers.empty()) {
1276 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1277 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1278 switch (NNS->getKind()) {
1279 case NestedNameSpecifier::Namespace:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::NamespaceAlias:
1288 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1289 Q.getLocalBeginLoc(),
1290 TU)))
1291 return true;
1292
1293 break;
1294
1295 case NestedNameSpecifier::TypeSpec:
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 if (Visit(Q.getTypeLoc()))
1298 return true;
1299
1300 break;
1301
1302 case NestedNameSpecifier::Global:
1303 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001304 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001305 break;
1306 }
1307 }
1308
1309 return false;
1310}
1311
1312bool CursorVisitor::VisitTemplateParameters(
1313 const TemplateParameterList *Params) {
1314 if (!Params)
1315 return false;
1316
1317 for (TemplateParameterList::const_iterator P = Params->begin(),
1318 PEnd = Params->end();
1319 P != PEnd; ++P) {
1320 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1321 return true;
1322 }
1323
1324 return false;
1325}
1326
1327bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1328 switch (Name.getKind()) {
1329 case TemplateName::Template:
1330 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1331
1332 case TemplateName::OverloadedTemplate:
1333 // Visit the overloaded template set.
1334 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1335 return true;
1336
1337 return false;
1338
1339 case TemplateName::DependentTemplate:
1340 // FIXME: Visit nested-name-specifier.
1341 return false;
1342
1343 case TemplateName::QualifiedTemplate:
1344 // FIXME: Visit nested-name-specifier.
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsQualifiedTemplateName()->getDecl(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParm:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1352 Loc, TU));
1353
1354 case TemplateName::SubstTemplateTemplateParmPack:
1355 return Visit(MakeCursorTemplateRef(
1356 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1357 Loc, TU));
1358 }
1359
1360 llvm_unreachable("Invalid TemplateName::Kind!");
1361}
1362
1363bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1364 switch (TAL.getArgument().getKind()) {
1365 case TemplateArgument::Null:
1366 case TemplateArgument::Integral:
1367 case TemplateArgument::Pack:
1368 return false;
1369
1370 case TemplateArgument::Type:
1371 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1372 return Visit(TSInfo->getTypeLoc());
1373 return false;
1374
1375 case TemplateArgument::Declaration:
1376 if (Expr *E = TAL.getSourceDeclExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::NullPtr:
1381 if (Expr *E = TAL.getSourceNullPtrExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Expression:
1386 if (Expr *E = TAL.getSourceExpression())
1387 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1388 return false;
1389
1390 case TemplateArgument::Template:
1391 case TemplateArgument::TemplateExpansion:
1392 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1393 return true;
1394
1395 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1396 TAL.getTemplateNameLoc());
1397 }
1398
1399 llvm_unreachable("Invalid TemplateArgument::Kind!");
1400}
1401
1402bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1403 return VisitDeclContext(D);
1404}
1405
1406bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1407 return Visit(TL.getUnqualifiedLoc());
1408}
1409
1410bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1411 ASTContext &Context = AU->getASTContext();
1412
1413 // Some builtin types (such as Objective-C's "id", "sel", and
1414 // "Class") have associated declarations. Create cursors for those.
1415 QualType VisitType;
1416 switch (TL.getTypePtr()->getKind()) {
1417
1418 case BuiltinType::Void:
1419 case BuiltinType::NullPtr:
1420 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001421 case BuiltinType::OCLImage1d:
1422 case BuiltinType::OCLImage1dArray:
1423 case BuiltinType::OCLImage1dBuffer:
1424 case BuiltinType::OCLImage2d:
1425 case BuiltinType::OCLImage2dArray:
1426 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001427 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001428 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001429#define BUILTIN_TYPE(Id, SingletonId)
1430#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1434#include "clang/AST/BuiltinTypes.def"
1435 break;
1436
1437 case BuiltinType::ObjCId:
1438 VisitType = Context.getObjCIdType();
1439 break;
1440
1441 case BuiltinType::ObjCClass:
1442 VisitType = Context.getObjCClassType();
1443 break;
1444
1445 case BuiltinType::ObjCSel:
1446 VisitType = Context.getObjCSelType();
1447 break;
1448 }
1449
1450 if (!VisitType.isNull()) {
1451 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1452 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1453 TU));
1454 }
1455
1456 return false;
1457}
1458
1459bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1460 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1468 if (TL.isDefinition())
1469 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1470
1471 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1472}
1473
1474bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1475 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1476}
1477
1478bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1479 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1480 return true;
1481
1482 return false;
1483}
1484
1485bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1486 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1487 return true;
1488
1489 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1490 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1491 TU)))
1492 return true;
1493 }
1494
1495 return false;
1496}
1497
1498bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1499 return Visit(TL.getPointeeLoc());
1500}
1501
1502bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1503 return Visit(TL.getInnerLoc());
1504}
1505
1506bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1507 return Visit(TL.getPointeeLoc());
1508}
1509
1510bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1511 return Visit(TL.getPointeeLoc());
1512}
1513
1514bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1515 return Visit(TL.getPointeeLoc());
1516}
1517
1518bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1519 return Visit(TL.getPointeeLoc());
1520}
1521
1522bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1523 return Visit(TL.getPointeeLoc());
1524}
1525
1526bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1527 return Visit(TL.getModifiedLoc());
1528}
1529
1530bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1531 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001532 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001533 return true;
1534
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001535 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1536 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001537 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1538 return true;
1539
1540 return false;
1541}
1542
1543bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1544 if (Visit(TL.getElementLoc()))
1545 return true;
1546
1547 if (Expr *Size = TL.getSizeExpr())
1548 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1549
1550 return false;
1551}
1552
Reid Kleckner8a365022013-06-24 17:51:48 +00001553bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1554 return Visit(TL.getOriginalLoc());
1555}
1556
Reid Kleckner0503a872013-12-05 01:23:43 +00001557bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1558 return Visit(TL.getOriginalLoc());
1559}
1560
Guy Benyei11169dd2012-12-18 14:30:41 +00001561bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1562 TemplateSpecializationTypeLoc TL) {
1563 // Visit the template name.
1564 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1565 TL.getTemplateNameLoc()))
1566 return true;
1567
1568 // Visit the template arguments.
1569 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1570 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1571 return true;
1572
1573 return false;
1574}
1575
1576bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1577 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1578}
1579
1580bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1581 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1582 return Visit(TSInfo->getTypeLoc());
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1588 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1589 return Visit(TSInfo->getTypeLoc());
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1595 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1596 return true;
1597
1598 return false;
1599}
1600
1601bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1602 DependentTemplateSpecializationTypeLoc TL) {
1603 // Visit the nested-name-specifier, if there is one.
1604 if (TL.getQualifierLoc() &&
1605 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1606 return true;
1607
1608 // Visit the template arguments.
1609 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1610 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1611 return true;
1612
1613 return false;
1614}
1615
1616bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1617 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1618 return true;
1619
1620 return Visit(TL.getNamedTypeLoc());
1621}
1622
1623bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1624 return Visit(TL.getPatternLoc());
1625}
1626
1627bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1628 if (Expr *E = TL.getUnderlyingExpr())
1629 return Visit(MakeCXCursor(E, StmtParent, TU));
1630
1631 return false;
1632}
1633
1634bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1635 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1636}
1637
1638bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1639 return Visit(TL.getValueLoc());
1640}
1641
1642#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1643bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1644 return Visit##PARENT##Loc(TL); \
1645}
1646
1647DEFAULT_TYPELOC_IMPL(Complex, Type)
1648DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1652DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1653DEFAULT_TYPELOC_IMPL(Vector, Type)
1654DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1655DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1656DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1657DEFAULT_TYPELOC_IMPL(Record, TagType)
1658DEFAULT_TYPELOC_IMPL(Enum, TagType)
1659DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1660DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1661DEFAULT_TYPELOC_IMPL(Auto, Type)
1662
1663bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1664 // Visit the nested-name-specifier, if present.
1665 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1666 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1667 return true;
1668
1669 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001670 for (const auto &I : D->bases()) {
1671 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001672 return true;
1673 }
1674 }
1675
1676 return VisitTagDecl(D);
1677}
1678
1679bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001680 for (const auto *I : D->attrs())
1681 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001682 return true;
1683
1684 return false;
1685}
1686
1687//===----------------------------------------------------------------------===//
1688// Data-recursive visitor methods.
1689//===----------------------------------------------------------------------===//
1690
1691namespace {
1692#define DEF_JOB(NAME, DATA, KIND)\
1693class NAME : public VisitorJob {\
1694public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001695 NAME(const DATA *d, CXCursor parent) : \
1696 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001697 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001698 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001699};
1700
1701DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1702DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1703DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1704DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1705DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1706 ExplicitTemplateArgsVisitKind)
1707DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1708DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1709DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1710#undef DEF_JOB
1711
1712class DeclVisit : public VisitorJob {
1713public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001714 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001715 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001716 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001717 static bool classof(const VisitorJob *VJ) {
1718 return VJ->getKind() == DeclVisitKind;
1719 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001720 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001721 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001722};
1723class TypeLocVisit : public VisitorJob {
1724public:
1725 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1726 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1727 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1728
1729 static bool classof(const VisitorJob *VJ) {
1730 return VJ->getKind() == TypeLocVisitKind;
1731 }
1732
1733 TypeLoc get() const {
1734 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001735 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001736 }
1737};
1738
1739class LabelRefVisit : public VisitorJob {
1740public:
1741 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1742 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1743 labelLoc.getPtrEncoding()) {}
1744
1745 static bool classof(const VisitorJob *VJ) {
1746 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1747 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 const LabelDecl *get() const {
1749 return static_cast<const LabelDecl *>(data[0]);
1750 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001751 SourceLocation getLoc() const {
1752 return SourceLocation::getFromPtrEncoding(data[1]); }
1753};
1754
1755class NestedNameSpecifierLocVisit : public VisitorJob {
1756public:
1757 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1758 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1759 Qualifier.getNestedNameSpecifier(),
1760 Qualifier.getOpaqueData()) { }
1761
1762 static bool classof(const VisitorJob *VJ) {
1763 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1764 }
1765
1766 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 return NestedNameSpecifierLoc(
1768 const_cast<NestedNameSpecifier *>(
1769 static_cast<const NestedNameSpecifier *>(data[0])),
1770 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001771 }
1772};
1773
1774class DeclarationNameInfoVisit : public VisitorJob {
1775public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001776 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001777 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 static bool classof(const VisitorJob *VJ) {
1779 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1780 }
1781 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001782 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001783 switch (S->getStmtClass()) {
1784 default:
1785 llvm_unreachable("Unhandled Stmt");
1786 case clang::Stmt::MSDependentExistsStmtClass:
1787 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1788 case Stmt::CXXDependentScopeMemberExprClass:
1789 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1790 case Stmt::DependentScopeDeclRefExprClass:
1791 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001792 case Stmt::OMPCriticalDirectiveClass:
1793 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001794 }
1795 }
1796};
1797class MemberRefVisit : public VisitorJob {
1798public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001799 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1801 L.getPtrEncoding()) {}
1802 static bool classof(const VisitorJob *VJ) {
1803 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1804 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001805 const FieldDecl *get() const {
1806 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001807 }
1808 SourceLocation getLoc() const {
1809 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1810 }
1811};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001812class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001813 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001814 VisitorWorkList &WL;
1815 CXCursor Parent;
1816public:
1817 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1818 : WL(wl), Parent(parent) {}
1819
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001820 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1821 void VisitBlockExpr(const BlockExpr *B);
1822 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1823 void VisitCompoundStmt(const CompoundStmt *S);
1824 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1825 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1826 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1827 void VisitCXXNewExpr(const CXXNewExpr *E);
1828 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1829 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1830 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1831 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1832 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1833 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1834 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1835 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001836 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001837 void VisitDeclRefExpr(const DeclRefExpr *D);
1838 void VisitDeclStmt(const DeclStmt *S);
1839 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1840 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1841 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1842 void VisitForStmt(const ForStmt *FS);
1843 void VisitGotoStmt(const GotoStmt *GS);
1844 void VisitIfStmt(const IfStmt *If);
1845 void VisitInitListExpr(const InitListExpr *IE);
1846 void VisitMemberExpr(const MemberExpr *M);
1847 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1848 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1849 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1850 void VisitOverloadExpr(const OverloadExpr *E);
1851 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1852 void VisitStmt(const Stmt *S);
1853 void VisitSwitchStmt(const SwitchStmt *S);
1854 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1856 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1857 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1858 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1859 void VisitVAArgExpr(const VAArgExpr *E);
1860 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1861 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1862 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1863 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001865 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001867 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001868 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001869 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001870 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001871 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001872 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001873 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001874 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001875 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001876 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001877 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001878 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001879 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001880 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001881 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001882 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001883 void
1884 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001885 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001886 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001887 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001888 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001889 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001890 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891
Guy Benyei11169dd2012-12-18 14:30:41 +00001892private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001894 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1895 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1897 void AddStmt(const Stmt *S);
1898 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001899 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001901 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001902};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001903} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001904
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001905void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001906 // 'S' should always be non-null, since it comes from the
1907 // statement we are visiting.
1908 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1909}
1910
1911void
1912EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1913 if (Qualifier)
1914 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1915}
1916
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001918 if (S)
1919 WL.push_back(StmtVisit(S, Parent));
1920}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001921void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001922 if (D)
1923 WL.push_back(DeclVisit(D, Parent, isFirst));
1924}
1925void EnqueueVisitor::
1926 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1927 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001928 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001929}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001930void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001931 if (D)
1932 WL.push_back(MemberRefVisit(D, L, Parent));
1933}
1934void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1935 if (TI)
1936 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1937 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001938void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001939 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001940 for (const Stmt *SubStmt : S->children()) {
1941 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001942 }
1943 if (size == WL.size())
1944 return;
1945 // Now reverse the entries we just added. This will match the DFS
1946 // ordering performed by the worklist.
1947 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1948 std::reverse(I, E);
1949}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001950namespace {
1951class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1952 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001953 /// \brief Process clauses with list of variables.
1954 template <typename T>
1955 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001956public:
1957 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1958#define OPENMP_CLAUSE(Name, Class) \
1959 void Visit##Class(const Class *C);
1960#include "clang/Basic/OpenMPKinds.def"
1961};
1962
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001963void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1964 Visitor->AddStmt(C->getCondition());
1965}
1966
Alexey Bataev3778b602014-07-17 07:32:53 +00001967void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1968 Visitor->AddStmt(C->getCondition());
1969}
1970
Alexey Bataev568a8332014-03-06 06:15:19 +00001971void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1972 Visitor->AddStmt(C->getNumThreads());
1973}
1974
Alexey Bataev62c87d22014-03-21 04:51:18 +00001975void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1976 Visitor->AddStmt(C->getSafelen());
1977}
1978
Alexander Musman8bd31e62014-05-27 15:12:19 +00001979void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1980 Visitor->AddStmt(C->getNumForLoops());
1981}
1982
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001983void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001984
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001985void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1986
Alexey Bataev56dafe82014-06-20 07:16:17 +00001987void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1988 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00001989 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00001990}
1991
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001992void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1993
Alexey Bataev236070f2014-06-20 11:19:47 +00001994void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1995
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001996void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1997
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001998void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1999
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002000void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2001
Alexey Bataevdea47612014-07-23 07:46:59 +00002002void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2003
Alexey Bataev67a4f222014-07-23 10:25:33 +00002004void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2005
Alexey Bataev459dec02014-07-24 06:46:57 +00002006void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2007
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002008void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2009
Alexey Bataev756c1962013-09-24 03:17:45 +00002010template<typename T>
2011void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002012 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002013 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002014 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002015}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002016
2017void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002018 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002019 for (const auto *E : C->private_copies()) {
2020 Visitor->AddStmt(E);
2021 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002022}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002023void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2024 const OMPFirstprivateClause *C) {
2025 VisitOMPClauseList(C);
2026}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002027void OMPClauseEnqueue::VisitOMPLastprivateClause(
2028 const OMPLastprivateClause *C) {
2029 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002030 for (auto *E : C->private_copies()) {
2031 Visitor->AddStmt(E);
2032 }
2033 for (auto *E : C->source_exprs()) {
2034 Visitor->AddStmt(E);
2035 }
2036 for (auto *E : C->destination_exprs()) {
2037 Visitor->AddStmt(E);
2038 }
2039 for (auto *E : C->assignment_ops()) {
2040 Visitor->AddStmt(E);
2041 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002042}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002043void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002044 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002045}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002046void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2047 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002048 for (auto *E : C->lhs_exprs()) {
2049 Visitor->AddStmt(E);
2050 }
2051 for (auto *E : C->rhs_exprs()) {
2052 Visitor->AddStmt(E);
2053 }
2054 for (auto *E : C->reduction_ops()) {
2055 Visitor->AddStmt(E);
2056 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002057}
Alexander Musman8dba6642014-04-22 13:09:42 +00002058void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2059 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002060 for (const auto *E : C->inits()) {
2061 Visitor->AddStmt(E);
2062 }
2063 for (const auto *E : C->updates()) {
2064 Visitor->AddStmt(E);
2065 }
2066 for (const auto *E : C->finals()) {
2067 Visitor->AddStmt(E);
2068 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002069 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002070 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002071}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002072void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2073 VisitOMPClauseList(C);
2074 Visitor->AddStmt(C->getAlignment());
2075}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002076void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2077 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002078 for (auto *E : C->source_exprs()) {
2079 Visitor->AddStmt(E);
2080 }
2081 for (auto *E : C->destination_exprs()) {
2082 Visitor->AddStmt(E);
2083 }
2084 for (auto *E : C->assignment_ops()) {
2085 Visitor->AddStmt(E);
2086 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002087}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002088void
2089OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2090 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002091 for (auto *E : C->source_exprs()) {
2092 Visitor->AddStmt(E);
2093 }
2094 for (auto *E : C->destination_exprs()) {
2095 Visitor->AddStmt(E);
2096 }
2097 for (auto *E : C->assignment_ops()) {
2098 Visitor->AddStmt(E);
2099 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002100}
Alexey Bataev6125da92014-07-21 11:26:11 +00002101void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2102 VisitOMPClauseList(C);
2103}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002104void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2105 VisitOMPClauseList(C);
2106}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002107}
Alexey Bataev756c1962013-09-24 03:17:45 +00002108
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002109void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2110 unsigned size = WL.size();
2111 OMPClauseEnqueue Visitor(this);
2112 Visitor.Visit(S);
2113 if (size == WL.size())
2114 return;
2115 // Now reverse the entries we just added. This will match the DFS
2116 // ordering performed by the worklist.
2117 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2118 std::reverse(I, E);
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 AddDecl(B->getBlockDecl());
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 EnqueueChildren(E);
2128 AddTypeLoc(E->getTypeSourceInfo());
2129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2131 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 E = S->body_rend(); I != E; ++I) {
2133 AddStmt(*I);
2134 }
2135}
2136void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 AddStmt(S->getSubStmt());
2139 AddDeclarationNameInfo(S);
2140 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2141 AddNestedNameSpecifierLoc(QualifierLoc);
2142}
2143
2144void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002145VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002146 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2147 AddDeclarationNameInfo(E);
2148 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2149 AddNestedNameSpecifierLoc(QualifierLoc);
2150 if (!E->isImplicitAccess())
2151 AddStmt(E->getBase());
2152}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 // Enqueue the initializer , if any.
2155 AddStmt(E->getInitializer());
2156 // Enqueue the array size, if any.
2157 AddStmt(E->getArraySize());
2158 // Enqueue the allocated type.
2159 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2160 // Enqueue the placement arguments.
2161 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2162 AddStmt(E->getPlacementArg(I-1));
2163}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2166 AddStmt(CE->getArg(I-1));
2167 AddStmt(CE->getCallee());
2168 AddStmt(CE->getArg(0));
2169}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002170void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2171 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 // Visit the name of the type being destroyed.
2173 AddTypeLoc(E->getDestroyedTypeInfo());
2174 // Visit the scope type that looks disturbingly like the nested-name-specifier
2175 // but isn't.
2176 AddTypeLoc(E->getScopeTypeInfo());
2177 // Visit the nested-name-specifier.
2178 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2179 AddNestedNameSpecifierLoc(QualifierLoc);
2180 // Visit base expression.
2181 AddStmt(E->getBase());
2182}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2184 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 AddTypeLoc(E->getTypeSourceInfo());
2186}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2188 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 EnqueueChildren(E);
2190 AddTypeLoc(E->getTypeSourceInfo());
2191}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 EnqueueChildren(E);
2194 if (E->isTypeOperand())
2195 AddTypeLoc(E->getTypeOperandSourceInfo());
2196}
2197
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2199 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 EnqueueChildren(E);
2201 AddTypeLoc(E->getTypeSourceInfo());
2202}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 EnqueueChildren(E);
2205 if (E->isTypeOperand())
2206 AddTypeLoc(E->getTypeOperandSourceInfo());
2207}
2208
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 EnqueueChildren(S);
2211 AddDecl(S->getExceptionDecl());
2212}
2213
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002214void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002215 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002216 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002217 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002218}
2219
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 if (DR->hasExplicitTemplateArgs()) {
2222 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2223 }
2224 WL.push_back(DeclRefExprParts(DR, Parent));
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2227 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2229 AddDeclarationNameInfo(E);
2230 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2231}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 unsigned size = WL.size();
2234 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002235 for (const auto *D : S->decls()) {
2236 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 isFirst = false;
2238 }
2239 if (size == WL.size())
2240 return;
2241 // Now reverse the entries we just added. This will match the DFS
2242 // ordering performed by the worklist.
2243 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2244 std::reverse(I, E);
2245}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002246void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 D = E->designators_rbegin(), DEnd = E->designators_rend();
2250 D != DEnd; ++D) {
2251 if (D->isFieldDesignator()) {
2252 if (FieldDecl *Field = D->getField())
2253 AddMemberRef(Field, D->getFieldLoc());
2254 continue;
2255 }
2256 if (D->isArrayDesignator()) {
2257 AddStmt(E->getArrayIndex(*D));
2258 continue;
2259 }
2260 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2261 AddStmt(E->getArrayRangeEnd(*D));
2262 AddStmt(E->getArrayRangeStart(*D));
2263 }
2264}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 EnqueueChildren(E);
2267 AddTypeLoc(E->getTypeInfoAsWritten());
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 AddStmt(FS->getBody());
2271 AddStmt(FS->getInc());
2272 AddStmt(FS->getCond());
2273 AddDecl(FS->getConditionVariable());
2274 AddStmt(FS->getInit());
2275}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2278}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 AddStmt(If->getElse());
2281 AddStmt(If->getThen());
2282 AddStmt(If->getCond());
2283 AddDecl(If->getConditionVariable());
2284}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 // We care about the syntactic form of the initializer list, only.
2287 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2288 IE = Syntactic;
2289 EnqueueChildren(IE);
2290}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 WL.push_back(MemberExprParts(M, Parent));
2293
2294 // If the base of the member access expression is an implicit 'this', don't
2295 // visit it.
2296 // FIXME: If we ever want to show these implicit accesses, this will be
2297 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002298 if (M->isImplicitAccess())
2299 return;
2300
2301 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2302 // real field that that we are interested in.
2303 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2304 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2305 if (FD->isAnonymousStructOrUnion()) {
2306 AddStmt(SubME->getBase());
2307 return;
2308 }
2309 }
2310 }
2311
2312 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 AddTypeLoc(E->getEncodedTypeSourceInfo());
2316}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002317void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002318 EnqueueChildren(M);
2319 AddTypeLoc(M->getClassReceiverTypeInfo());
2320}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002321void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002322 // Visit the components of the offsetof expression.
2323 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2324 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2325 const OffsetOfNode &Node = E->getComponent(I-1);
2326 switch (Node.getKind()) {
2327 case OffsetOfNode::Array:
2328 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2329 break;
2330 case OffsetOfNode::Field:
2331 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2332 break;
2333 case OffsetOfNode::Identifier:
2334 case OffsetOfNode::Base:
2335 continue;
2336 }
2337 }
2338 // Visit the type into which we're computing the offset.
2339 AddTypeLoc(E->getTypeSourceInfo());
2340}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002341void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002342 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2343 WL.push_back(OverloadExprParts(E, Parent));
2344}
2345void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002346 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002347 EnqueueChildren(E);
2348 if (E->isArgumentType())
2349 AddTypeLoc(E->getArgumentTypeInfo());
2350}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002351void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002352 EnqueueChildren(S);
2353}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002354void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002355 AddStmt(S->getBody());
2356 AddStmt(S->getCond());
2357 AddDecl(S->getConditionVariable());
2358}
2359
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002361 AddStmt(W->getBody());
2362 AddStmt(W->getCond());
2363 AddDecl(W->getConditionVariable());
2364}
2365
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002366void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002367 for (unsigned I = E->getNumArgs(); I > 0; --I)
2368 AddTypeLoc(E->getArg(I-1));
2369}
2370
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002371void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002372 AddTypeLoc(E->getQueriedTypeSourceInfo());
2373}
2374
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002375void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002376 EnqueueChildren(E);
2377}
2378
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002379void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002380 VisitOverloadExpr(U);
2381 if (!U->isImplicitAccess())
2382 AddStmt(U->getBase());
2383}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002384void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002385 AddStmt(E->getSubExpr());
2386 AddTypeLoc(E->getWrittenTypeInfo());
2387}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002388void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002389 WL.push_back(SizeOfPackExprParts(E, Parent));
2390}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002391void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002392 // If the opaque value has a source expression, just transparently
2393 // visit that. This is useful for (e.g.) pseudo-object expressions.
2394 if (Expr *SourceExpr = E->getSourceExpr())
2395 return Visit(SourceExpr);
2396}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 AddStmt(E->getBody());
2399 WL.push_back(LambdaExprParts(E, Parent));
2400}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002401void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002402 // Treat the expression like its syntactic form.
2403 Visit(E->getSyntacticForm());
2404}
2405
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002406void EnqueueVisitor::VisitOMPExecutableDirective(
2407 const OMPExecutableDirective *D) {
2408 EnqueueChildren(D);
2409 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2410 E = D->clauses().end();
2411 I != E; ++I)
2412 EnqueueChildren(*I);
2413}
2414
Alexander Musman3aaab662014-08-19 11:27:13 +00002415void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2416 VisitOMPExecutableDirective(D);
2417}
2418
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002419void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2420 VisitOMPExecutableDirective(D);
2421}
2422
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002423void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002424 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002425}
2426
Alexey Bataevf29276e2014-06-18 04:14:57 +00002427void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002428 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002429}
2430
Alexander Musmanf82886e2014-09-18 05:12:34 +00002431void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2432 VisitOMPLoopDirective(D);
2433}
2434
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002435void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2436 VisitOMPExecutableDirective(D);
2437}
2438
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002439void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2440 VisitOMPExecutableDirective(D);
2441}
2442
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002443void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2444 VisitOMPExecutableDirective(D);
2445}
2446
Alexander Musman80c22892014-07-17 08:54:58 +00002447void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2448 VisitOMPExecutableDirective(D);
2449}
2450
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002451void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2452 VisitOMPExecutableDirective(D);
2453 AddDeclarationNameInfo(D);
2454}
2455
Alexey Bataev4acb8592014-07-07 13:01:15 +00002456void
2457EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002458 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002459}
2460
Alexander Musmane4e893b2014-09-23 09:33:00 +00002461void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2462 const OMPParallelForSimdDirective *D) {
2463 VisitOMPLoopDirective(D);
2464}
2465
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002466void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2467 const OMPParallelSectionsDirective *D) {
2468 VisitOMPExecutableDirective(D);
2469}
2470
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002471void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2472 VisitOMPExecutableDirective(D);
2473}
2474
Alexey Bataev68446b72014-07-18 07:47:19 +00002475void
2476EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2477 VisitOMPExecutableDirective(D);
2478}
2479
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002480void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2481 VisitOMPExecutableDirective(D);
2482}
2483
Alexey Bataev2df347a2014-07-18 10:17:07 +00002484void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2485 VisitOMPExecutableDirective(D);
2486}
2487
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002488void EnqueueVisitor::VisitOMPTaskgroupDirective(
2489 const OMPTaskgroupDirective *D) {
2490 VisitOMPExecutableDirective(D);
2491}
2492
Alexey Bataev6125da92014-07-21 11:26:11 +00002493void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2494 VisitOMPExecutableDirective(D);
2495}
2496
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002497void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2498 VisitOMPExecutableDirective(D);
2499}
2500
Alexey Bataev0162e452014-07-22 10:10:35 +00002501void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2502 VisitOMPExecutableDirective(D);
2503}
2504
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002505void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2506 VisitOMPExecutableDirective(D);
2507}
2508
Alexey Bataev13314bf2014-10-09 04:18:56 +00002509void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2510 VisitOMPExecutableDirective(D);
2511}
2512
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002513void EnqueueVisitor::VisitOMPCancellationPointDirective(
2514 const OMPCancellationPointDirective *D) {
2515 VisitOMPExecutableDirective(D);
2516}
2517
Alexey Bataev80909872015-07-02 11:25:17 +00002518void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2519 VisitOMPExecutableDirective(D);
2520}
2521
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002522void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002523 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2524}
2525
2526bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2527 if (RegionOfInterest.isValid()) {
2528 SourceRange Range = getRawCursorExtent(C);
2529 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2530 return false;
2531 }
2532 return true;
2533}
2534
2535bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2536 while (!WL.empty()) {
2537 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002538 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002539
2540 // Set the Parent field, then back to its old value once we're done.
2541 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2542
2543 switch (LI.getKind()) {
2544 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002545 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002546 if (!D)
2547 continue;
2548
2549 // For now, perform default visitation for Decls.
2550 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2551 cast<DeclVisit>(&LI)->isFirst())))
2552 return true;
2553
2554 continue;
2555 }
2556 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2557 const ASTTemplateArgumentListInfo *ArgList =
2558 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2559 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2560 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2561 Arg != ArgEnd; ++Arg) {
2562 if (VisitTemplateArgumentLoc(*Arg))
2563 return true;
2564 }
2565 continue;
2566 }
2567 case VisitorJob::TypeLocVisitKind: {
2568 // Perform default visitation for TypeLocs.
2569 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2570 return true;
2571 continue;
2572 }
2573 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002574 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002575 if (LabelStmt *stmt = LS->getStmt()) {
2576 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2577 TU))) {
2578 return true;
2579 }
2580 }
2581 continue;
2582 }
2583
2584 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2585 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2586 if (VisitNestedNameSpecifierLoc(V->get()))
2587 return true;
2588 continue;
2589 }
2590
2591 case VisitorJob::DeclarationNameInfoVisitKind: {
2592 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2593 ->get()))
2594 return true;
2595 continue;
2596 }
2597 case VisitorJob::MemberRefVisitKind: {
2598 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2599 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2600 return true;
2601 continue;
2602 }
2603 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002604 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002605 if (!S)
2606 continue;
2607
2608 // Update the current cursor.
2609 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2610 if (!IsInRegionOfInterest(Cursor))
2611 continue;
2612 switch (Visitor(Cursor, Parent, ClientData)) {
2613 case CXChildVisit_Break: return true;
2614 case CXChildVisit_Continue: break;
2615 case CXChildVisit_Recurse:
2616 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002617 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002618 EnqueueWorkList(WL, S);
2619 break;
2620 }
2621 continue;
2622 }
2623 case VisitorJob::MemberExprPartsKind: {
2624 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002625 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002626
2627 // Visit the nested-name-specifier
2628 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2629 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2630 return true;
2631
2632 // Visit the declaration name.
2633 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2634 return true;
2635
2636 // Visit the explicitly-specified template arguments, if any.
2637 if (M->hasExplicitTemplateArgs()) {
2638 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2639 *ArgEnd = Arg + M->getNumTemplateArgs();
2640 Arg != ArgEnd; ++Arg) {
2641 if (VisitTemplateArgumentLoc(*Arg))
2642 return true;
2643 }
2644 }
2645 continue;
2646 }
2647 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002648 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002649 // Visit nested-name-specifier, if present.
2650 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2651 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2652 return true;
2653 // Visit declaration name.
2654 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2655 return true;
2656 continue;
2657 }
2658 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002659 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002660 // Visit the nested-name-specifier.
2661 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2662 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2663 return true;
2664 // Visit the declaration name.
2665 if (VisitDeclarationNameInfo(O->getNameInfo()))
2666 return true;
2667 // Visit the overloaded declaration reference.
2668 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2669 return true;
2670 continue;
2671 }
2672 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002673 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002674 NamedDecl *Pack = E->getPack();
2675 if (isa<TemplateTypeParmDecl>(Pack)) {
2676 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2677 E->getPackLoc(), TU)))
2678 return true;
2679
2680 continue;
2681 }
2682
2683 if (isa<TemplateTemplateParmDecl>(Pack)) {
2684 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2685 E->getPackLoc(), TU)))
2686 return true;
2687
2688 continue;
2689 }
2690
2691 // Non-type template parameter packs and function parameter packs are
2692 // treated like DeclRefExpr cursors.
2693 continue;
2694 }
2695
2696 case VisitorJob::LambdaExprPartsKind: {
2697 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002698 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002699 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2700 CEnd = E->explicit_capture_end();
2701 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002702 // FIXME: Lambda init-captures.
2703 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002704 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002705
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2707 C->getLocation(),
2708 TU)))
2709 return true;
2710 }
2711
2712 // Visit parameters and return type, if present.
2713 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2714 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2715 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2716 // Visit the whole type.
2717 if (Visit(TL))
2718 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002719 } else if (FunctionProtoTypeLoc Proto =
2720 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002721 if (E->hasExplicitParameters()) {
2722 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002723 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2724 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002725 return true;
2726 } else {
2727 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002728 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002729 return true;
2730 }
2731 }
2732 }
2733 break;
2734 }
2735
2736 case VisitorJob::PostChildrenVisitKind:
2737 if (PostChildrenVisitor(Parent, ClientData))
2738 return true;
2739 break;
2740 }
2741 }
2742 return false;
2743}
2744
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002745bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002746 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002747 if (!WorkListFreeList.empty()) {
2748 WL = WorkListFreeList.back();
2749 WL->clear();
2750 WorkListFreeList.pop_back();
2751 }
2752 else {
2753 WL = new VisitorWorkList();
2754 WorkListCache.push_back(WL);
2755 }
2756 EnqueueWorkList(*WL, S);
2757 bool result = RunVisitorWorkList(*WL);
2758 WorkListFreeList.push_back(WL);
2759 return result;
2760}
2761
2762namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002763typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002764RefNamePieces
2765buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2766 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2767 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002768 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2769 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2770 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2771
2772 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2773
2774 RefNamePieces Pieces;
2775
2776 if (WantQualifier && QLoc.isValid())
2777 Pieces.push_back(QLoc);
2778
2779 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2780 Pieces.push_back(NI.getLoc());
2781
2782 if (WantTemplateArgs && TemplateArgs)
2783 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2784 TemplateArgs->RAngleLoc));
2785
2786 if (Kind == DeclarationName::CXXOperatorName) {
2787 Pieces.push_back(SourceLocation::getFromRawEncoding(
2788 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2789 Pieces.push_back(SourceLocation::getFromRawEncoding(
2790 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2791 }
2792
2793 if (WantSinglePiece) {
2794 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2795 Pieces.clear();
2796 Pieces.push_back(R);
2797 }
2798
2799 return Pieces;
2800}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002801}
Guy Benyei11169dd2012-12-18 14:30:41 +00002802
2803//===----------------------------------------------------------------------===//
2804// Misc. API hooks.
2805//===----------------------------------------------------------------------===//
2806
Chad Rosier05c71aa2013-03-27 18:28:23 +00002807static void fatal_error_handler(void *user_data, const std::string& reason,
2808 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002809 // Write the result out to stderr avoiding errs() because raw_ostreams can
2810 // call report_fatal_error.
2811 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2812 ::abort();
2813}
2814
Chandler Carruth66660742014-06-27 16:37:27 +00002815namespace {
2816struct RegisterFatalErrorHandler {
2817 RegisterFatalErrorHandler() {
2818 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2819 }
2820};
2821}
2822
2823static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2824
Guy Benyei11169dd2012-12-18 14:30:41 +00002825extern "C" {
2826CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2827 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002828 // We use crash recovery to make some of our APIs more reliable, implicitly
2829 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002830 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2831 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002832
Chandler Carruth66660742014-06-27 16:37:27 +00002833 // Look through the managed static to trigger construction of the managed
2834 // static which registers our fatal error handler. This ensures it is only
2835 // registered once.
2836 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002837
2838 CIndexer *CIdxr = new CIndexer();
2839 if (excludeDeclarationsFromPCH)
2840 CIdxr->setOnlyLocalDecls();
2841 if (displayDiagnostics)
2842 CIdxr->setDisplayDiagnostics();
2843
2844 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2845 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2846 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2847 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2848 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2849 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2850
2851 return CIdxr;
2852}
2853
2854void clang_disposeIndex(CXIndex CIdx) {
2855 if (CIdx)
2856 delete static_cast<CIndexer *>(CIdx);
2857}
2858
2859void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2860 if (CIdx)
2861 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2862}
2863
2864unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2865 if (CIdx)
2866 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2867 return 0;
2868}
2869
2870void clang_toggleCrashRecovery(unsigned isEnabled) {
2871 if (isEnabled)
2872 llvm::CrashRecoveryContext::Enable();
2873 else
2874 llvm::CrashRecoveryContext::Disable();
2875}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002876
Guy Benyei11169dd2012-12-18 14:30:41 +00002877CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2878 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002879 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002880 enum CXErrorCode Result =
2881 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002882 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002883 assert((TU && Result == CXError_Success) ||
2884 (!TU && Result != CXError_Success));
2885 return TU;
2886}
2887
2888enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2889 const char *ast_filename,
2890 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002891 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002892 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002893
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002894 if (!CIdx || !ast_filename || !out_TU)
2895 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002896
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002897 LOG_FUNC_SECTION {
2898 *Log << ast_filename;
2899 }
2900
Guy Benyei11169dd2012-12-18 14:30:41 +00002901 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2902 FileSystemOptions FileSystemOpts;
2903
Justin Bognerd512c1e2014-10-15 00:33:06 +00002904 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2905 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002906 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00002907 ast_filename, CXXIdx->getPCHContainerOperations(), Diags, FileSystemOpts,
2908 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002909 /*CaptureDiagnostics=*/true,
2910 /*AllowPCHWithCompilerErrors=*/true,
2911 /*UserFilesAreVolatile=*/true);
2912 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002913 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002914}
2915
2916unsigned clang_defaultEditingTranslationUnitOptions() {
2917 return CXTranslationUnit_PrecompiledPreamble |
2918 CXTranslationUnit_CacheCompletionResults;
2919}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002920
Guy Benyei11169dd2012-12-18 14:30:41 +00002921CXTranslationUnit
2922clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2923 const char *source_filename,
2924 int num_command_line_args,
2925 const char * const *command_line_args,
2926 unsigned num_unsaved_files,
2927 struct CXUnsavedFile *unsaved_files) {
2928 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2929 return clang_parseTranslationUnit(CIdx, source_filename,
2930 command_line_args, num_command_line_args,
2931 unsaved_files, num_unsaved_files,
2932 Options);
2933}
2934
2935struct ParseTranslationUnitInfo {
2936 CXIndex CIdx;
2937 const char *source_filename;
2938 const char *const *command_line_args;
2939 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002940 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002941 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002942 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002943 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002944};
2945static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002946 const ParseTranslationUnitInfo *PTUI =
2947 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002948 CXIndex CIdx = PTUI->CIdx;
2949 const char *source_filename = PTUI->source_filename;
2950 const char * const *command_line_args = PTUI->command_line_args;
2951 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002952 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002953 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002954
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002955 // Set up the initial return values.
2956 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002957 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002958
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002959 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002960 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002961 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002962 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002963 }
2964
Guy Benyei11169dd2012-12-18 14:30:41 +00002965 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2966
2967 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2968 setThreadBackgroundPriority();
2969
2970 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2971 // FIXME: Add a flag for modules.
2972 TranslationUnitKind TUKind
2973 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002974 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002975 = options & CXTranslationUnit_CacheCompletionResults;
2976 bool IncludeBriefCommentsInCodeCompletion
2977 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2978 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2979 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2980
2981 // Configure the diagnostics.
2982 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002983 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002984
2985 // Recover resources if we crash before exiting this function.
2986 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2987 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002988 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002989
Ahmed Charlesb8984322014-03-07 20:03:18 +00002990 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2991 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002992
2993 // Recover resources if we crash before exiting this function.
2994 llvm::CrashRecoveryContextCleanupRegistrar<
2995 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2996
Alp Toker9d85b182014-07-07 01:23:14 +00002997 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002998 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002999 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003000 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003001 }
3002
Ahmed Charlesb8984322014-03-07 20:03:18 +00003003 std::unique_ptr<std::vector<const char *>> Args(
3004 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003005
3006 // Recover resources if we crash before exiting this method.
3007 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3008 ArgsCleanup(Args.get());
3009
3010 // Since the Clang C library is primarily used by batch tools dealing with
3011 // (often very broken) source code, where spell-checking can have a
3012 // significant negative impact on performance (particularly when
3013 // precompiled headers are involved), we disable it by default.
3014 // Only do this if we haven't found a spell-checking-related argument.
3015 bool FoundSpellCheckingArgument = false;
3016 for (int I = 0; I != num_command_line_args; ++I) {
3017 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3018 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3019 FoundSpellCheckingArgument = true;
3020 break;
3021 }
3022 }
3023 if (!FoundSpellCheckingArgument)
3024 Args->push_back("-fno-spell-checking");
3025
3026 Args->insert(Args->end(), command_line_args,
3027 command_line_args + num_command_line_args);
3028
3029 // The 'source_filename' argument is optional. If the caller does not
3030 // specify it then it is assumed that the source file is specified
3031 // in the actual argument list.
3032 // Put the source file after command_line_args otherwise if '-x' flag is
3033 // present it will be unused.
3034 if (source_filename)
3035 Args->push_back(source_filename);
3036
3037 // Do we need the detailed preprocessing record?
3038 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3039 Args->push_back("-Xclang");
3040 Args->push_back("-detailed-preprocessing-record");
3041 }
3042
3043 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003044 std::unique_ptr<ASTUnit> ErrUnit;
3045 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003046 Args->data(), Args->data() + Args->size(),
3047 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003048 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3049 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3050 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3051 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3052 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3053 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003054
3055 if (NumErrors != Diags->getClient()->getNumErrors()) {
3056 // Make sure to check that 'Unit' is non-NULL.
3057 if (CXXIdx->getDisplayDiagnostics())
3058 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3059 }
3060
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003061 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3062 PTUI->result = CXError_ASTReadError;
3063 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003064 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003065 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3066 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003067}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003068
3069CXTranslationUnit
3070clang_parseTranslationUnit(CXIndex CIdx,
3071 const char *source_filename,
3072 const char *const *command_line_args,
3073 int num_command_line_args,
3074 struct CXUnsavedFile *unsaved_files,
3075 unsigned num_unsaved_files,
3076 unsigned options) {
3077 CXTranslationUnit TU;
3078 enum CXErrorCode Result = clang_parseTranslationUnit2(
3079 CIdx, source_filename, command_line_args, num_command_line_args,
3080 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003081 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003082 assert((TU && Result == CXError_Success) ||
3083 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003084 return TU;
3085}
3086
3087enum CXErrorCode clang_parseTranslationUnit2(
3088 CXIndex CIdx,
3089 const char *source_filename,
3090 const char *const *command_line_args,
3091 int num_command_line_args,
3092 struct CXUnsavedFile *unsaved_files,
3093 unsigned num_unsaved_files,
3094 unsigned options,
3095 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003096 LOG_FUNC_SECTION {
3097 *Log << source_filename << ": ";
3098 for (int i = 0; i != num_command_line_args; ++i)
3099 *Log << command_line_args[i] << " ";
3100 }
3101
Alp Toker9d85b182014-07-07 01:23:14 +00003102 if (num_unsaved_files && !unsaved_files)
3103 return CXError_InvalidArguments;
3104
Alp Toker5c532982014-07-07 22:42:03 +00003105 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003106 ParseTranslationUnitInfo PTUI = {
3107 CIdx,
3108 source_filename,
3109 command_line_args,
3110 num_command_line_args,
3111 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3112 options,
3113 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003114 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003115 llvm::CrashRecoveryContext CRC;
3116
3117 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3118 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3119 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3120 fprintf(stderr, " 'command_line_args' : [");
3121 for (int i = 0; i != num_command_line_args; ++i) {
3122 if (i)
3123 fprintf(stderr, ", ");
3124 fprintf(stderr, "'%s'", command_line_args[i]);
3125 }
3126 fprintf(stderr, "],\n");
3127 fprintf(stderr, " 'unsaved_files' : [");
3128 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3129 if (i)
3130 fprintf(stderr, ", ");
3131 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3132 unsaved_files[i].Length);
3133 }
3134 fprintf(stderr, "],\n");
3135 fprintf(stderr, " 'options' : %d,\n", options);
3136 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003137
3138 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003139 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003140 if (CXTranslationUnit *TU = PTUI.out_TU)
3141 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003142 }
Alp Toker5c532982014-07-07 22:42:03 +00003143
3144 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003145}
3146
3147unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3148 return CXSaveTranslationUnit_None;
3149}
3150
3151namespace {
3152
3153struct SaveTranslationUnitInfo {
3154 CXTranslationUnit TU;
3155 const char *FileName;
3156 unsigned options;
3157 CXSaveError result;
3158};
3159
3160}
3161
3162static void clang_saveTranslationUnit_Impl(void *UserData) {
3163 SaveTranslationUnitInfo *STUI =
3164 static_cast<SaveTranslationUnitInfo*>(UserData);
3165
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003166 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3168 setThreadBackgroundPriority();
3169
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003170 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3172}
3173
3174int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3175 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003176 LOG_FUNC_SECTION {
3177 *Log << TU << ' ' << FileName;
3178 }
3179
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003180 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003181 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003183 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003184
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003185 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3187 if (!CXXUnit->hasSema())
3188 return CXSaveError_InvalidTU;
3189
3190 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3191
3192 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3193 getenv("LIBCLANG_NOTHREADS")) {
3194 clang_saveTranslationUnit_Impl(&STUI);
3195
3196 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3197 PrintLibclangResourceUsage(TU);
3198
3199 return STUI.result;
3200 }
3201
3202 // We have an AST that has invalid nodes due to compiler errors.
3203 // Use a crash recovery thread for protection.
3204
3205 llvm::CrashRecoveryContext CRC;
3206
3207 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3208 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3209 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3210 fprintf(stderr, " 'options' : %d,\n", options);
3211 fprintf(stderr, "}\n");
3212
3213 return CXSaveError_Unknown;
3214
3215 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3216 PrintLibclangResourceUsage(TU);
3217 }
3218
3219 return STUI.result;
3220}
3221
3222void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3223 if (CTUnit) {
3224 // If the translation unit has been marked as unsafe to free, just discard
3225 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003226 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3227 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003228 return;
3229
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003230 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003231 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3233 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003234 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 delete CTUnit;
3236 }
3237}
3238
3239unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3240 return CXReparse_None;
3241}
3242
3243struct ReparseTranslationUnitInfo {
3244 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003245 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003246 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003247 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003248};
3249
3250static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003251 const ReparseTranslationUnitInfo *RTUI =
3252 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003254 unsigned options = RTUI->options;
3255 (void) options;
3256
3257 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003258 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003259 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003260 RTUI->result = CXError_InvalidArguments;
3261 return;
3262 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003263
3264 // Reset the associated diagnostics.
3265 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003266 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003267
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003268 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3270 setThreadBackgroundPriority();
3271
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003272 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003274
3275 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3276 new std::vector<ASTUnit::RemappedFile>());
3277
Guy Benyei11169dd2012-12-18 14:30:41 +00003278 // Recover resources if we crash before exiting this function.
3279 llvm::CrashRecoveryContextCleanupRegistrar<
3280 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003281
3282 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003283 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003284 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003285 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003286 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003287
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003288 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3289 *RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003290 RTUI->result = CXError_Success;
3291 else if (isASTReadError(CXXUnit))
3292 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003293}
3294
3295int clang_reparseTranslationUnit(CXTranslationUnit TU,
3296 unsigned num_unsaved_files,
3297 struct CXUnsavedFile *unsaved_files,
3298 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003299 LOG_FUNC_SECTION {
3300 *Log << TU;
3301 }
3302
Alp Toker9d85b182014-07-07 01:23:14 +00003303 if (num_unsaved_files && !unsaved_files)
3304 return CXError_InvalidArguments;
3305
Alp Toker5c532982014-07-07 22:42:03 +00003306 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003307 ReparseTranslationUnitInfo RTUI = {
3308 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003309 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003310
3311 if (getenv("LIBCLANG_NOTHREADS")) {
3312 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003313 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 }
3315
3316 llvm::CrashRecoveryContext CRC;
3317
3318 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3319 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003320 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003321 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3323 PrintLibclangResourceUsage(TU);
3324
Alp Toker5c532982014-07-07 22:42:03 +00003325 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003326}
3327
3328
3329CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003330 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003331 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003332 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003333 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003334
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003335 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003336 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003337}
3338
3339CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003340 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003341 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003342 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003343 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003344
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003345 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3347}
3348
3349} // end: extern "C"
3350
3351//===----------------------------------------------------------------------===//
3352// CXFile Operations.
3353//===----------------------------------------------------------------------===//
3354
3355extern "C" {
3356CXString clang_getFileName(CXFile SFile) {
3357 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003358 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003359
3360 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003361 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003362}
3363
3364time_t clang_getFileTime(CXFile SFile) {
3365 if (!SFile)
3366 return 0;
3367
3368 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3369 return FEnt->getModificationTime();
3370}
3371
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003372CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003373 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003374 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003375 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003376 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003377
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003378 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003379
3380 FileManager &FMgr = CXXUnit->getFileManager();
3381 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3382}
3383
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003384unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3385 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003386 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003387 LOG_BAD_TU(TU);
3388 return 0;
3389 }
3390
3391 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 return 0;
3393
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003394 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003395 FileEntry *FEnt = static_cast<FileEntry *>(file);
3396 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3397 .isFileMultipleIncludeGuarded(FEnt);
3398}
3399
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003400int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3401 if (!file || !outID)
3402 return 1;
3403
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003404 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003405 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3406 outID->data[0] = ID.getDevice();
3407 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003408 outID->data[2] = FEnt->getModificationTime();
3409 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003410}
3411
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003412int clang_File_isEqual(CXFile file1, CXFile file2) {
3413 if (file1 == file2)
3414 return true;
3415
3416 if (!file1 || !file2)
3417 return false;
3418
3419 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3420 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3421 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3422}
3423
Guy Benyei11169dd2012-12-18 14:30:41 +00003424} // end: extern "C"
3425
3426//===----------------------------------------------------------------------===//
3427// CXCursor Operations.
3428//===----------------------------------------------------------------------===//
3429
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003430static const Decl *getDeclFromExpr(const Stmt *E) {
3431 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 return getDeclFromExpr(CE->getSubExpr());
3433
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003434 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003436 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003438 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003440 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 if (PRE->isExplicitProperty())
3442 return PRE->getExplicitProperty();
3443 // It could be messaging both getter and setter as in:
3444 // ++myobj.myprop;
3445 // in which case prefer to associate the setter since it is less obvious
3446 // from inspecting the source that the setter is going to get called.
3447 if (PRE->isMessagingSetter())
3448 return PRE->getImplicitPropertySetter();
3449 return PRE->getImplicitPropertyGetter();
3450 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003451 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003453 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 if (Expr *Src = OVE->getSourceExpr())
3455 return getDeclFromExpr(Src);
3456
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003457 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003459 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 if (!CE->isElidable())
3461 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003462 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 return OME->getMethodDecl();
3464
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003465 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003467 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3469 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003470 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3472 isa<ParmVarDecl>(SizeOfPack->getPack()))
3473 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003474
3475 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003476}
3477
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003478static SourceLocation getLocationFromExpr(const Expr *E) {
3479 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 return getLocationFromExpr(CE->getSubExpr());
3481
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003482 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003484 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003486 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003488 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003490 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003492 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 return PropRef->getLocation();
3494
3495 return E->getLocStart();
3496}
3497
3498extern "C" {
3499
3500unsigned clang_visitChildren(CXCursor parent,
3501 CXCursorVisitor visitor,
3502 CXClientData client_data) {
3503 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3504 /*VisitPreprocessorLast=*/false);
3505 return CursorVis.VisitChildren(parent);
3506}
3507
3508#ifndef __has_feature
3509#define __has_feature(x) 0
3510#endif
3511#if __has_feature(blocks)
3512typedef enum CXChildVisitResult
3513 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3514
3515static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3516 CXClientData client_data) {
3517 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3518 return block(cursor, parent);
3519}
3520#else
3521// If we are compiled with a compiler that doesn't have native blocks support,
3522// define and call the block manually, so the
3523typedef struct _CXChildVisitResult
3524{
3525 void *isa;
3526 int flags;
3527 int reserved;
3528 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3529 CXCursor);
3530} *CXCursorVisitorBlock;
3531
3532static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3533 CXClientData client_data) {
3534 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3535 return block->invoke(block, cursor, parent);
3536}
3537#endif
3538
3539
3540unsigned clang_visitChildrenWithBlock(CXCursor parent,
3541 CXCursorVisitorBlock block) {
3542 return clang_visitChildren(parent, visitWithBlock, block);
3543}
3544
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003545static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003547 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003548
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003549 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003550 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003551 if (const ObjCPropertyImplDecl *PropImpl =
3552 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003554 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003555
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003556 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003558 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003559
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003560 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 }
3562
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003563 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003564 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003565
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003566 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3568 // and returns different names. NamedDecl returns the class name and
3569 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003570 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003571
3572 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003573 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003574
3575 SmallString<1024> S;
3576 llvm::raw_svector_ostream os(S);
3577 ND->printName(os);
3578
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003579 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003580}
3581
3582CXString clang_getCursorSpelling(CXCursor C) {
3583 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003584 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003585
3586 if (clang_isReference(C.kind)) {
3587 switch (C.kind) {
3588 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003589 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003590 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 }
3592 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003593 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003594 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 }
3596 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003597 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003599 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 }
3601 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003602 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003603 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 }
3605 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003606 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 assert(Type && "Missing type decl");
3608
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003609 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 getAsString());
3611 }
3612 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003613 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 assert(Template && "Missing template decl");
3615
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003616 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 }
3618
3619 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003620 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 assert(NS && "Missing namespace decl");
3622
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003623 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 }
3625
3626 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003627 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 assert(Field && "Missing member decl");
3629
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003630 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 }
3632
3633 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003634 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 assert(Label && "Missing label");
3636
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 }
3639
3640 case CXCursor_OverloadedDeclRef: {
3641 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003642 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3643 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003644 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003645 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003647 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003648 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 OverloadedTemplateStorage *Ovl
3650 = Storage.get<OverloadedTemplateStorage*>();
3651 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003652 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003653 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 }
3655
3656 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003657 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 assert(Var && "Missing variable decl");
3659
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003660 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 }
3662
3663 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 }
3666 }
3667
3668 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003669 const Expr *E = getCursorExpr(C);
3670
3671 if (C.kind == CXCursor_ObjCStringLiteral ||
3672 C.kind == CXCursor_StringLiteral) {
3673 const StringLiteral *SLit;
3674 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3675 SLit = OSL->getString();
3676 } else {
3677 SLit = cast<StringLiteral>(E);
3678 }
3679 SmallString<256> Buf;
3680 llvm::raw_svector_ostream OS(Buf);
3681 SLit->outputString(OS);
3682 return cxstring::createDup(OS.str());
3683 }
3684
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003685 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 if (D)
3687 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003688 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 }
3690
3691 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003692 const Stmt *S = getCursorStmt(C);
3693 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003695
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003696 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 }
3698
3699 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 ->getNameStart());
3702
3703 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 ->getNameStart());
3706
3707 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003708 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003709
3710 if (clang_isDeclaration(C.kind))
3711 return getDeclSpelling(getCursorDecl(C));
3712
3713 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003714 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003715 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 }
3717
3718 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003719 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003720 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 }
3722
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003723 if (C.kind == CXCursor_PackedAttr) {
3724 return cxstring::createRef("packed");
3725 }
3726
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003727 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003728}
3729
3730CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3731 unsigned pieceIndex,
3732 unsigned options) {
3733 if (clang_Cursor_isNull(C))
3734 return clang_getNullRange();
3735
3736 ASTContext &Ctx = getCursorContext(C);
3737
3738 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003739 const Stmt *S = getCursorStmt(C);
3740 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 if (pieceIndex > 0)
3742 return clang_getNullRange();
3743 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3744 }
3745
3746 return clang_getNullRange();
3747 }
3748
3749 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003750 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3752 if (pieceIndex >= ME->getNumSelectorLocs())
3753 return clang_getNullRange();
3754 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3755 }
3756 }
3757
3758 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3759 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003760 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3762 if (pieceIndex >= MD->getNumSelectorLocs())
3763 return clang_getNullRange();
3764 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3765 }
3766 }
3767
3768 if (C.kind == CXCursor_ObjCCategoryDecl ||
3769 C.kind == CXCursor_ObjCCategoryImplDecl) {
3770 if (pieceIndex > 0)
3771 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003772 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3774 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003775 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3777 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3778 }
3779
3780 if (C.kind == CXCursor_ModuleImportDecl) {
3781 if (pieceIndex > 0)
3782 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003783 if (const ImportDecl *ImportD =
3784 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3786 if (!Locs.empty())
3787 return cxloc::translateSourceRange(Ctx,
3788 SourceRange(Locs.front(), Locs.back()));
3789 }
3790 return clang_getNullRange();
3791 }
3792
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003793 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3794 C.kind == CXCursor_ConversionFunction) {
3795 if (pieceIndex > 0)
3796 return clang_getNullRange();
3797 if (const FunctionDecl *FD =
3798 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3799 DeclarationNameInfo FunctionName = FD->getNameInfo();
3800 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3801 }
3802 return clang_getNullRange();
3803 }
3804
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 // FIXME: A CXCursor_InclusionDirective should give the location of the
3806 // filename, but we don't keep track of this.
3807
3808 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3809 // but we don't keep track of this.
3810
3811 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3812 // but we don't keep track of this.
3813
3814 // Default handling, give the location of the cursor.
3815
3816 if (pieceIndex > 0)
3817 return clang_getNullRange();
3818
3819 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3820 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3821 return cxloc::translateSourceRange(Ctx, Loc);
3822}
3823
Eli Bendersky44a206f2014-07-31 18:04:56 +00003824CXString clang_Cursor_getMangling(CXCursor C) {
3825 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3826 return cxstring::createEmpty();
3827
Eli Bendersky44a206f2014-07-31 18:04:56 +00003828 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003829 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003830 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3831 return cxstring::createEmpty();
3832
Eli Bendersky79759592014-08-01 15:01:10 +00003833 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003834 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003835 ASTContext &Ctx = ND->getASTContext();
3836 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003837
Eli Bendersky79759592014-08-01 15:01:10 +00003838 std::string FrontendBuf;
3839 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3840 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003841
Eli Bendersky79759592014-08-01 15:01:10 +00003842 // Now apply backend mangling.
3843 std::unique_ptr<llvm::DataLayout> DL(
3844 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
Eli Bendersky79759592014-08-01 15:01:10 +00003845
3846 std::string FinalBuf;
3847 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003848 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3849 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003850
3851 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003852}
3853
Guy Benyei11169dd2012-12-18 14:30:41 +00003854CXString clang_getCursorDisplayName(CXCursor C) {
3855 if (!clang_isDeclaration(C.kind))
3856 return clang_getCursorSpelling(C);
3857
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003858 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003860 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003861
3862 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003863 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 D = FunTmpl->getTemplatedDecl();
3865
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003866 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 SmallString<64> Str;
3868 llvm::raw_svector_ostream OS(Str);
3869 OS << *Function;
3870 if (Function->getPrimaryTemplate())
3871 OS << "<>";
3872 OS << "(";
3873 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3874 if (I)
3875 OS << ", ";
3876 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3877 }
3878
3879 if (Function->isVariadic()) {
3880 if (Function->getNumParams())
3881 OS << ", ";
3882 OS << "...";
3883 }
3884 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003885 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 }
3887
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003888 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 SmallString<64> Str;
3890 llvm::raw_svector_ostream OS(Str);
3891 OS << *ClassTemplate;
3892 OS << "<";
3893 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3894 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3895 if (I)
3896 OS << ", ";
3897
3898 NamedDecl *Param = Params->getParam(I);
3899 if (Param->getIdentifier()) {
3900 OS << Param->getIdentifier()->getName();
3901 continue;
3902 }
3903
3904 // There is no parameter name, which makes this tricky. Try to come up
3905 // with something useful that isn't too long.
3906 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3907 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3908 else if (NonTypeTemplateParmDecl *NTTP
3909 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3910 OS << NTTP->getType().getAsString(Policy);
3911 else
3912 OS << "template<...> class";
3913 }
3914
3915 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003916 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 }
3918
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003919 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3921 // If the type was explicitly written, use that.
3922 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003923 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003924
Benjamin Kramer9170e912013-02-22 15:46:01 +00003925 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 llvm::raw_svector_ostream OS(Str);
3927 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003928 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 ClassSpec->getTemplateArgs().data(),
3930 ClassSpec->getTemplateArgs().size(),
3931 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003932 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 }
3934
3935 return clang_getCursorSpelling(C);
3936}
3937
3938CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3939 switch (Kind) {
3940 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004068 case CXCursor_ObjCSelfExpr:
4069 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004158 case CXCursor_SEHLeaveStmt:
4159 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004188 case CXCursor_PackedAttr:
4189 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004190 case CXCursor_PureAttr:
4191 return cxstring::createRef("attribute(pure)");
4192 case CXCursor_ConstAttr:
4193 return cxstring::createRef("attribute(const)");
4194 case CXCursor_NoDuplicateAttr:
4195 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004196 case CXCursor_CUDAConstantAttr:
4197 return cxstring::createRef("attribute(constant)");
4198 case CXCursor_CUDADeviceAttr:
4199 return cxstring::createRef("attribute(device)");
4200 case CXCursor_CUDAGlobalAttr:
4201 return cxstring::createRef("attribute(global)");
4202 case CXCursor_CUDAHostAttr:
4203 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004204 case CXCursor_CUDASharedAttr:
4205 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004243 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004245 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004247 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004249 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004251 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004253 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004254 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004255 return cxstring::createRef("OMPParallelDirective");
4256 case CXCursor_OMPSimdDirective:
4257 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004258 case CXCursor_OMPForDirective:
4259 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004260 case CXCursor_OMPForSimdDirective:
4261 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004262 case CXCursor_OMPSectionsDirective:
4263 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004264 case CXCursor_OMPSectionDirective:
4265 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004266 case CXCursor_OMPSingleDirective:
4267 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004268 case CXCursor_OMPMasterDirective:
4269 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004270 case CXCursor_OMPCriticalDirective:
4271 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004272 case CXCursor_OMPParallelForDirective:
4273 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004274 case CXCursor_OMPParallelForSimdDirective:
4275 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004276 case CXCursor_OMPParallelSectionsDirective:
4277 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004278 case CXCursor_OMPTaskDirective:
4279 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004280 case CXCursor_OMPTaskyieldDirective:
4281 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004282 case CXCursor_OMPBarrierDirective:
4283 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004284 case CXCursor_OMPTaskwaitDirective:
4285 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004286 case CXCursor_OMPTaskgroupDirective:
4287 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004288 case CXCursor_OMPFlushDirective:
4289 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004290 case CXCursor_OMPOrderedDirective:
4291 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004292 case CXCursor_OMPAtomicDirective:
4293 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004294 case CXCursor_OMPTargetDirective:
4295 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004296 case CXCursor_OMPTeamsDirective:
4297 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004298 case CXCursor_OMPCancellationPointDirective:
4299 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004300 case CXCursor_OMPCancelDirective:
4301 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004302 case CXCursor_OverloadCandidate:
4303 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 }
4305
4306 llvm_unreachable("Unhandled CXCursorKind");
4307}
4308
4309struct GetCursorData {
4310 SourceLocation TokenBeginLoc;
4311 bool PointsAtMacroArgExpansion;
4312 bool VisitedObjCPropertyImplDecl;
4313 SourceLocation VisitedDeclaratorDeclStartLoc;
4314 CXCursor &BestCursor;
4315
4316 GetCursorData(SourceManager &SM,
4317 SourceLocation tokenBegin, CXCursor &outputCursor)
4318 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4319 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4320 VisitedObjCPropertyImplDecl = false;
4321 }
4322};
4323
4324static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4325 CXCursor parent,
4326 CXClientData client_data) {
4327 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4328 CXCursor *BestCursor = &Data->BestCursor;
4329
4330 // If we point inside a macro argument we should provide info of what the
4331 // token is so use the actual cursor, don't replace it with a macro expansion
4332 // cursor.
4333 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4334 return CXChildVisit_Recurse;
4335
4336 if (clang_isDeclaration(cursor.kind)) {
4337 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004338 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004339 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4340 if (MD->isImplicit())
4341 return CXChildVisit_Break;
4342
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004343 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004344 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4345 // Check that when we have multiple @class references in the same line,
4346 // that later ones do not override the previous ones.
4347 // If we have:
4348 // @class Foo, Bar;
4349 // source ranges for both start at '@', so 'Bar' will end up overriding
4350 // 'Foo' even though the cursor location was at 'Foo'.
4351 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4352 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004353 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4355 if (PrevID != ID &&
4356 !PrevID->isThisDeclarationADefinition() &&
4357 !ID->isThisDeclarationADefinition())
4358 return CXChildVisit_Break;
4359 }
4360
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004361 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4363 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4364 // Check that when we have multiple declarators in the same line,
4365 // that later ones do not override the previous ones.
4366 // If we have:
4367 // int Foo, Bar;
4368 // source ranges for both start at 'int', so 'Bar' will end up overriding
4369 // 'Foo' even though the cursor location was at 'Foo'.
4370 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4371 return CXChildVisit_Break;
4372 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4373
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004374 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004375 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4376 (void)PropImp;
4377 // Check that when we have multiple @synthesize in the same line,
4378 // that later ones do not override the previous ones.
4379 // If we have:
4380 // @synthesize Foo, Bar;
4381 // source ranges for both start at '@', so 'Bar' will end up overriding
4382 // 'Foo' even though the cursor location was at 'Foo'.
4383 if (Data->VisitedObjCPropertyImplDecl)
4384 return CXChildVisit_Break;
4385 Data->VisitedObjCPropertyImplDecl = true;
4386 }
4387 }
4388
4389 if (clang_isExpression(cursor.kind) &&
4390 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004391 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004392 // Avoid having the cursor of an expression replace the declaration cursor
4393 // when the expression source range overlaps the declaration range.
4394 // This can happen for C++ constructor expressions whose range generally
4395 // include the variable declaration, e.g.:
4396 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4397 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4398 D->getLocation() == Data->TokenBeginLoc)
4399 return CXChildVisit_Break;
4400 }
4401 }
4402
4403 // If our current best cursor is the construction of a temporary object,
4404 // don't replace that cursor with a type reference, because we want
4405 // clang_getCursor() to point at the constructor.
4406 if (clang_isExpression(BestCursor->kind) &&
4407 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4408 cursor.kind == CXCursor_TypeRef) {
4409 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4410 // as having the actual point on the type reference.
4411 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4412 return CXChildVisit_Recurse;
4413 }
4414
4415 *BestCursor = cursor;
4416 return CXChildVisit_Recurse;
4417}
4418
4419CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004420 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004421 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004423 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004424
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004425 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004426 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4427
4428 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4429 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4430
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004431 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 CXFile SearchFile;
4433 unsigned SearchLine, SearchColumn;
4434 CXFile ResultFile;
4435 unsigned ResultLine, ResultColumn;
4436 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4437 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4438 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004439
4440 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4441 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004442 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004443 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 SearchFileName = clang_getFileName(SearchFile);
4445 ResultFileName = clang_getFileName(ResultFile);
4446 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4447 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004448 *Log << llvm::format("(%s:%d:%d) = %s",
4449 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4450 clang_getCString(KindSpelling))
4451 << llvm::format("(%s:%d:%d):%s%s",
4452 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4453 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004454 clang_disposeString(SearchFileName);
4455 clang_disposeString(ResultFileName);
4456 clang_disposeString(KindSpelling);
4457 clang_disposeString(USR);
4458
4459 CXCursor Definition = clang_getCursorDefinition(Result);
4460 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4461 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4462 CXString DefinitionKindSpelling
4463 = clang_getCursorKindSpelling(Definition.kind);
4464 CXFile DefinitionFile;
4465 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004466 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004467 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004469 *Log << llvm::format(" -> %s(%s:%d:%d)",
4470 clang_getCString(DefinitionKindSpelling),
4471 clang_getCString(DefinitionFileName),
4472 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 clang_disposeString(DefinitionFileName);
4474 clang_disposeString(DefinitionKindSpelling);
4475 }
4476 }
4477
4478 return Result;
4479}
4480
4481CXCursor clang_getNullCursor(void) {
4482 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4483}
4484
4485unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004486 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4487 // can't set consistently. For example, when visiting a DeclStmt we will set
4488 // it but we don't set it on the result of clang_getCursorDefinition for
4489 // a reference of the same declaration.
4490 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4491 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4492 // to provide that kind of info.
4493 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004494 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004495 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004496 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004497
Guy Benyei11169dd2012-12-18 14:30:41 +00004498 return X == Y;
4499}
4500
4501unsigned clang_hashCursor(CXCursor C) {
4502 unsigned Index = 0;
4503 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4504 Index = 1;
4505
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004506 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 std::make_pair(C.kind, C.data[Index]));
4508}
4509
4510unsigned clang_isInvalid(enum CXCursorKind K) {
4511 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4512}
4513
4514unsigned clang_isDeclaration(enum CXCursorKind K) {
4515 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4516 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4517}
4518
4519unsigned clang_isReference(enum CXCursorKind K) {
4520 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4521}
4522
4523unsigned clang_isExpression(enum CXCursorKind K) {
4524 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4525}
4526
4527unsigned clang_isStatement(enum CXCursorKind K) {
4528 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4529}
4530
4531unsigned clang_isAttribute(enum CXCursorKind K) {
4532 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4533}
4534
4535unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4536 return K == CXCursor_TranslationUnit;
4537}
4538
4539unsigned clang_isPreprocessing(enum CXCursorKind K) {
4540 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4541}
4542
4543unsigned clang_isUnexposed(enum CXCursorKind K) {
4544 switch (K) {
4545 case CXCursor_UnexposedDecl:
4546 case CXCursor_UnexposedExpr:
4547 case CXCursor_UnexposedStmt:
4548 case CXCursor_UnexposedAttr:
4549 return true;
4550 default:
4551 return false;
4552 }
4553}
4554
4555CXCursorKind clang_getCursorKind(CXCursor C) {
4556 return C.kind;
4557}
4558
4559CXSourceLocation clang_getCursorLocation(CXCursor C) {
4560 if (clang_isReference(C.kind)) {
4561 switch (C.kind) {
4562 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004563 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 = getCursorObjCSuperClassRef(C);
4565 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4566 }
4567
4568 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004569 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 = getCursorObjCProtocolRef(C);
4571 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4572 }
4573
4574 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004575 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004576 = getCursorObjCClassRef(C);
4577 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4578 }
4579
4580 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004581 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4583 }
4584
4585 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004586 std::pair<const TemplateDecl *, SourceLocation> P =
4587 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4589 }
4590
4591 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004592 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4594 }
4595
4596 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004597 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4599 }
4600
4601 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004602 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4604 }
4605
4606 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004607 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 if (!BaseSpec)
4609 return clang_getNullLocation();
4610
4611 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4612 return cxloc::translateSourceLocation(getCursorContext(C),
4613 TSInfo->getTypeLoc().getBeginLoc());
4614
4615 return cxloc::translateSourceLocation(getCursorContext(C),
4616 BaseSpec->getLocStart());
4617 }
4618
4619 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004620 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4622 }
4623
4624 case CXCursor_OverloadedDeclRef:
4625 return cxloc::translateSourceLocation(getCursorContext(C),
4626 getCursorOverloadedDeclRef(C).second);
4627
4628 default:
4629 // FIXME: Need a way to enumerate all non-reference cases.
4630 llvm_unreachable("Missed a reference kind");
4631 }
4632 }
4633
4634 if (clang_isExpression(C.kind))
4635 return cxloc::translateSourceLocation(getCursorContext(C),
4636 getLocationFromExpr(getCursorExpr(C)));
4637
4638 if (clang_isStatement(C.kind))
4639 return cxloc::translateSourceLocation(getCursorContext(C),
4640 getCursorStmt(C)->getLocStart());
4641
4642 if (C.kind == CXCursor_PreprocessingDirective) {
4643 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4644 return cxloc::translateSourceLocation(getCursorContext(C), L);
4645 }
4646
4647 if (C.kind == CXCursor_MacroExpansion) {
4648 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004649 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 return cxloc::translateSourceLocation(getCursorContext(C), L);
4651 }
4652
4653 if (C.kind == CXCursor_MacroDefinition) {
4654 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4655 return cxloc::translateSourceLocation(getCursorContext(C), L);
4656 }
4657
4658 if (C.kind == CXCursor_InclusionDirective) {
4659 SourceLocation L
4660 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4661 return cxloc::translateSourceLocation(getCursorContext(C), L);
4662 }
4663
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004664 if (clang_isAttribute(C.kind)) {
4665 SourceLocation L
4666 = cxcursor::getCursorAttr(C)->getLocation();
4667 return cxloc::translateSourceLocation(getCursorContext(C), L);
4668 }
4669
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 if (!clang_isDeclaration(C.kind))
4671 return clang_getNullLocation();
4672
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004673 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004674 if (!D)
4675 return clang_getNullLocation();
4676
4677 SourceLocation Loc = D->getLocation();
4678 // FIXME: Multiple variables declared in a single declaration
4679 // currently lack the information needed to correctly determine their
4680 // ranges when accounting for the type-specifier. We use context
4681 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4682 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004683 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 if (!cxcursor::isFirstInDeclGroup(C))
4685 Loc = VD->getLocation();
4686 }
4687
4688 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004689 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 Loc = MD->getSelectorStartLoc();
4691
4692 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4693}
4694
4695} // end extern "C"
4696
4697CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4698 assert(TU);
4699
4700 // Guard against an invalid SourceLocation, or we may assert in one
4701 // of the following calls.
4702 if (SLoc.isInvalid())
4703 return clang_getNullCursor();
4704
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004705 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004706
4707 // Translate the given source location to make it point at the beginning of
4708 // the token under the cursor.
4709 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4710 CXXUnit->getASTContext().getLangOpts());
4711
4712 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4713 if (SLoc.isValid()) {
4714 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4715 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4716 /*VisitPreprocessorLast=*/true,
4717 /*VisitIncludedEntities=*/false,
4718 SourceLocation(SLoc));
4719 CursorVis.visitFileRegion();
4720 }
4721
4722 return Result;
4723}
4724
4725static SourceRange getRawCursorExtent(CXCursor C) {
4726 if (clang_isReference(C.kind)) {
4727 switch (C.kind) {
4728 case CXCursor_ObjCSuperClassRef:
4729 return getCursorObjCSuperClassRef(C).second;
4730
4731 case CXCursor_ObjCProtocolRef:
4732 return getCursorObjCProtocolRef(C).second;
4733
4734 case CXCursor_ObjCClassRef:
4735 return getCursorObjCClassRef(C).second;
4736
4737 case CXCursor_TypeRef:
4738 return getCursorTypeRef(C).second;
4739
4740 case CXCursor_TemplateRef:
4741 return getCursorTemplateRef(C).second;
4742
4743 case CXCursor_NamespaceRef:
4744 return getCursorNamespaceRef(C).second;
4745
4746 case CXCursor_MemberRef:
4747 return getCursorMemberRef(C).second;
4748
4749 case CXCursor_CXXBaseSpecifier:
4750 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4751
4752 case CXCursor_LabelRef:
4753 return getCursorLabelRef(C).second;
4754
4755 case CXCursor_OverloadedDeclRef:
4756 return getCursorOverloadedDeclRef(C).second;
4757
4758 case CXCursor_VariableRef:
4759 return getCursorVariableRef(C).second;
4760
4761 default:
4762 // FIXME: Need a way to enumerate all non-reference cases.
4763 llvm_unreachable("Missed a reference kind");
4764 }
4765 }
4766
4767 if (clang_isExpression(C.kind))
4768 return getCursorExpr(C)->getSourceRange();
4769
4770 if (clang_isStatement(C.kind))
4771 return getCursorStmt(C)->getSourceRange();
4772
4773 if (clang_isAttribute(C.kind))
4774 return getCursorAttr(C)->getRange();
4775
4776 if (C.kind == CXCursor_PreprocessingDirective)
4777 return cxcursor::getCursorPreprocessingDirective(C);
4778
4779 if (C.kind == CXCursor_MacroExpansion) {
4780 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004781 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004782 return TU->mapRangeFromPreamble(Range);
4783 }
4784
4785 if (C.kind == CXCursor_MacroDefinition) {
4786 ASTUnit *TU = getCursorASTUnit(C);
4787 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4788 return TU->mapRangeFromPreamble(Range);
4789 }
4790
4791 if (C.kind == CXCursor_InclusionDirective) {
4792 ASTUnit *TU = getCursorASTUnit(C);
4793 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4794 return TU->mapRangeFromPreamble(Range);
4795 }
4796
4797 if (C.kind == CXCursor_TranslationUnit) {
4798 ASTUnit *TU = getCursorASTUnit(C);
4799 FileID MainID = TU->getSourceManager().getMainFileID();
4800 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4801 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4802 return SourceRange(Start, End);
4803 }
4804
4805 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004806 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 if (!D)
4808 return SourceRange();
4809
4810 SourceRange R = D->getSourceRange();
4811 // FIXME: Multiple variables declared in a single declaration
4812 // currently lack the information needed to correctly determine their
4813 // ranges when accounting for the type-specifier. We use context
4814 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4815 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004816 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 if (!cxcursor::isFirstInDeclGroup(C))
4818 R.setBegin(VD->getLocation());
4819 }
4820 return R;
4821 }
4822 return SourceRange();
4823}
4824
4825/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4826/// the decl-specifier-seq for declarations.
4827static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4828 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004829 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 if (!D)
4831 return SourceRange();
4832
4833 SourceRange R = D->getSourceRange();
4834
4835 // Adjust the start of the location for declarations preceded by
4836 // declaration specifiers.
4837 SourceLocation StartLoc;
4838 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4839 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4840 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004841 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004842 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4843 StartLoc = TI->getTypeLoc().getLocStart();
4844 }
4845
4846 if (StartLoc.isValid() && R.getBegin().isValid() &&
4847 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4848 R.setBegin(StartLoc);
4849
4850 // FIXME: Multiple variables declared in a single declaration
4851 // currently lack the information needed to correctly determine their
4852 // ranges when accounting for the type-specifier. We use context
4853 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4854 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004855 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004856 if (!cxcursor::isFirstInDeclGroup(C))
4857 R.setBegin(VD->getLocation());
4858 }
4859
4860 return R;
4861 }
4862
4863 return getRawCursorExtent(C);
4864}
4865
4866extern "C" {
4867
4868CXSourceRange clang_getCursorExtent(CXCursor C) {
4869 SourceRange R = getRawCursorExtent(C);
4870 if (R.isInvalid())
4871 return clang_getNullRange();
4872
4873 return cxloc::translateSourceRange(getCursorContext(C), R);
4874}
4875
4876CXCursor clang_getCursorReferenced(CXCursor C) {
4877 if (clang_isInvalid(C.kind))
4878 return clang_getNullCursor();
4879
4880 CXTranslationUnit tu = getCursorTU(C);
4881 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004883 if (!D)
4884 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004885 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004886 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004887 if (const ObjCPropertyImplDecl *PropImpl =
4888 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004889 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4890 return MakeCXCursor(Property, tu);
4891
4892 return C;
4893 }
4894
4895 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004896 const Expr *E = getCursorExpr(C);
4897 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004898 if (D) {
4899 CXCursor declCursor = MakeCXCursor(D, tu);
4900 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4901 declCursor);
4902 return declCursor;
4903 }
4904
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004905 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004906 return MakeCursorOverloadedDeclRef(Ovl, tu);
4907
4908 return clang_getNullCursor();
4909 }
4910
4911 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004912 const Stmt *S = getCursorStmt(C);
4913 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 if (LabelDecl *label = Goto->getLabel())
4915 if (LabelStmt *labelS = label->getStmt())
4916 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4917
4918 return clang_getNullCursor();
4919 }
Richard Smith66a81862015-05-04 02:25:31 +00004920
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004922 if (const MacroDefinitionRecord *Def =
4923 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 return MakeMacroDefinitionCursor(Def, tu);
4925 }
4926
4927 if (!clang_isReference(C.kind))
4928 return clang_getNullCursor();
4929
4930 switch (C.kind) {
4931 case CXCursor_ObjCSuperClassRef:
4932 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4933
4934 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004935 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4936 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004937 return MakeCXCursor(Def, tu);
4938
4939 return MakeCXCursor(Prot, tu);
4940 }
4941
4942 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004943 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4944 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 return MakeCXCursor(Def, tu);
4946
4947 return MakeCXCursor(Class, tu);
4948 }
4949
4950 case CXCursor_TypeRef:
4951 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4952
4953 case CXCursor_TemplateRef:
4954 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4955
4956 case CXCursor_NamespaceRef:
4957 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4958
4959 case CXCursor_MemberRef:
4960 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4961
4962 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004963 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004964 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4965 tu ));
4966 }
4967
4968 case CXCursor_LabelRef:
4969 // FIXME: We end up faking the "parent" declaration here because we
4970 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004971 return MakeCXCursor(getCursorLabelRef(C).first,
4972 cxtu::getASTUnit(tu)->getASTContext()
4973 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004974 tu);
4975
4976 case CXCursor_OverloadedDeclRef:
4977 return C;
4978
4979 case CXCursor_VariableRef:
4980 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4981
4982 default:
4983 // We would prefer to enumerate all non-reference cursor kinds here.
4984 llvm_unreachable("Unhandled reference cursor kind");
4985 }
4986}
4987
4988CXCursor clang_getCursorDefinition(CXCursor C) {
4989 if (clang_isInvalid(C.kind))
4990 return clang_getNullCursor();
4991
4992 CXTranslationUnit TU = getCursorTU(C);
4993
4994 bool WasReference = false;
4995 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4996 C = clang_getCursorReferenced(C);
4997 WasReference = true;
4998 }
4999
5000 if (C.kind == CXCursor_MacroExpansion)
5001 return clang_getCursorReferenced(C);
5002
5003 if (!clang_isDeclaration(C.kind))
5004 return clang_getNullCursor();
5005
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005006 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 if (!D)
5008 return clang_getNullCursor();
5009
5010 switch (D->getKind()) {
5011 // Declaration kinds that don't really separate the notions of
5012 // declaration and definition.
5013 case Decl::Namespace:
5014 case Decl::Typedef:
5015 case Decl::TypeAlias:
5016 case Decl::TypeAliasTemplate:
5017 case Decl::TemplateTypeParm:
5018 case Decl::EnumConstant:
5019 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005020 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005021 case Decl::IndirectField:
5022 case Decl::ObjCIvar:
5023 case Decl::ObjCAtDefsField:
5024 case Decl::ImplicitParam:
5025 case Decl::ParmVar:
5026 case Decl::NonTypeTemplateParm:
5027 case Decl::TemplateTemplateParm:
5028 case Decl::ObjCCategoryImpl:
5029 case Decl::ObjCImplementation:
5030 case Decl::AccessSpec:
5031 case Decl::LinkageSpec:
5032 case Decl::ObjCPropertyImpl:
5033 case Decl::FileScopeAsm:
5034 case Decl::StaticAssert:
5035 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005036 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005037 case Decl::Label: // FIXME: Is this right??
5038 case Decl::ClassScopeFunctionSpecialization:
5039 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005040 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005041 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 return C;
5043
5044 // Declaration kinds that don't make any sense here, but are
5045 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005046 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005048 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 break;
5050
5051 // Declaration kinds for which the definition is not resolvable.
5052 case Decl::UnresolvedUsingTypename:
5053 case Decl::UnresolvedUsingValue:
5054 break;
5055
5056 case Decl::UsingDirective:
5057 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5058 TU);
5059
5060 case Decl::NamespaceAlias:
5061 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5062
5063 case Decl::Enum:
5064 case Decl::Record:
5065 case Decl::CXXRecord:
5066 case Decl::ClassTemplateSpecialization:
5067 case Decl::ClassTemplatePartialSpecialization:
5068 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5069 return MakeCXCursor(Def, TU);
5070 return clang_getNullCursor();
5071
5072 case Decl::Function:
5073 case Decl::CXXMethod:
5074 case Decl::CXXConstructor:
5075 case Decl::CXXDestructor:
5076 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005077 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005078 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005079 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005080 return clang_getNullCursor();
5081 }
5082
Larisse Voufo39a1e502013-08-06 01:03:05 +00005083 case Decl::Var:
5084 case Decl::VarTemplateSpecialization:
5085 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005086 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005087 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005088 return MakeCXCursor(Def, TU);
5089 return clang_getNullCursor();
5090 }
5091
5092 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005093 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5095 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5096 return clang_getNullCursor();
5097 }
5098
5099 case Decl::ClassTemplate: {
5100 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5101 ->getDefinition())
5102 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5103 TU);
5104 return clang_getNullCursor();
5105 }
5106
Larisse Voufo39a1e502013-08-06 01:03:05 +00005107 case Decl::VarTemplate: {
5108 if (VarDecl *Def =
5109 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5110 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5111 return clang_getNullCursor();
5112 }
5113
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 case Decl::Using:
5115 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5116 D->getLocation(), TU);
5117
5118 case Decl::UsingShadow:
5119 return clang_getCursorDefinition(
5120 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5121 TU));
5122
5123 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005124 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005125 if (Method->isThisDeclarationADefinition())
5126 return C;
5127
5128 // Dig out the method definition in the associated
5129 // @implementation, if we have it.
5130 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005131 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5133 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5134 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5135 Method->isInstanceMethod()))
5136 if (Def->isThisDeclarationADefinition())
5137 return MakeCXCursor(Def, TU);
5138
5139 return clang_getNullCursor();
5140 }
5141
5142 case Decl::ObjCCategory:
5143 if (ObjCCategoryImplDecl *Impl
5144 = cast<ObjCCategoryDecl>(D)->getImplementation())
5145 return MakeCXCursor(Impl, TU);
5146 return clang_getNullCursor();
5147
5148 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005149 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 return MakeCXCursor(Def, TU);
5151 return clang_getNullCursor();
5152
5153 case Decl::ObjCInterface: {
5154 // There are two notions of a "definition" for an Objective-C
5155 // class: the interface and its implementation. When we resolved a
5156 // reference to an Objective-C class, produce the @interface as
5157 // the definition; when we were provided with the interface,
5158 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005159 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005161 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 return MakeCXCursor(Def, TU);
5163 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5164 return MakeCXCursor(Impl, TU);
5165 return clang_getNullCursor();
5166 }
5167
5168 case Decl::ObjCProperty:
5169 // FIXME: We don't really know where to find the
5170 // ObjCPropertyImplDecls that implement this property.
5171 return clang_getNullCursor();
5172
5173 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005174 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005175 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005176 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 return MakeCXCursor(Def, TU);
5178
5179 return clang_getNullCursor();
5180
5181 case Decl::Friend:
5182 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5183 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5184 return clang_getNullCursor();
5185
5186 case Decl::FriendTemplate:
5187 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5188 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5189 return clang_getNullCursor();
5190 }
5191
5192 return clang_getNullCursor();
5193}
5194
5195unsigned clang_isCursorDefinition(CXCursor C) {
5196 if (!clang_isDeclaration(C.kind))
5197 return 0;
5198
5199 return clang_getCursorDefinition(C) == C;
5200}
5201
5202CXCursor clang_getCanonicalCursor(CXCursor C) {
5203 if (!clang_isDeclaration(C.kind))
5204 return C;
5205
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005206 if (const Decl *D = getCursorDecl(C)) {
5207 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5209 return MakeCXCursor(CatD, getCursorTU(C));
5210
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005211 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5212 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 return MakeCXCursor(IFD, getCursorTU(C));
5214
5215 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5216 }
5217
5218 return C;
5219}
5220
5221int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5222 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5223}
5224
5225unsigned clang_getNumOverloadedDecls(CXCursor C) {
5226 if (C.kind != CXCursor_OverloadedDeclRef)
5227 return 0;
5228
5229 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005230 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005231 return E->getNumDecls();
5232
5233 if (OverloadedTemplateStorage *S
5234 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5235 return S->size();
5236
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005237 const Decl *D = Storage.get<const Decl *>();
5238 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005239 return Using->shadow_size();
5240
5241 return 0;
5242}
5243
5244CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5245 if (cursor.kind != CXCursor_OverloadedDeclRef)
5246 return clang_getNullCursor();
5247
5248 if (index >= clang_getNumOverloadedDecls(cursor))
5249 return clang_getNullCursor();
5250
5251 CXTranslationUnit TU = getCursorTU(cursor);
5252 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005253 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 return MakeCXCursor(E->decls_begin()[index], TU);
5255
5256 if (OverloadedTemplateStorage *S
5257 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5258 return MakeCXCursor(S->begin()[index], TU);
5259
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005260 const Decl *D = Storage.get<const Decl *>();
5261 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 // FIXME: This is, unfortunately, linear time.
5263 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5264 std::advance(Pos, index);
5265 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5266 }
5267
5268 return clang_getNullCursor();
5269}
5270
5271void clang_getDefinitionSpellingAndExtent(CXCursor C,
5272 const char **startBuf,
5273 const char **endBuf,
5274 unsigned *startLine,
5275 unsigned *startColumn,
5276 unsigned *endLine,
5277 unsigned *endColumn) {
5278 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005279 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5281
5282 SourceManager &SM = FD->getASTContext().getSourceManager();
5283 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5284 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5285 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5286 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5287 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5288 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5289}
5290
5291
5292CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5293 unsigned PieceIndex) {
5294 RefNamePieces Pieces;
5295
5296 switch (C.kind) {
5297 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005298 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005299 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5300 E->getQualifierLoc().getSourceRange());
5301 break;
5302
5303 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005304 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5306 E->getQualifierLoc().getSourceRange(),
5307 E->getOptionalExplicitTemplateArgs());
5308 break;
5309
5310 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005311 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005313 const Expr *Callee = OCE->getCallee();
5314 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005315 Callee = ICE->getSubExpr();
5316
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005317 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5319 DRE->getQualifierLoc().getSourceRange());
5320 }
5321 break;
5322
5323 default:
5324 break;
5325 }
5326
5327 if (Pieces.empty()) {
5328 if (PieceIndex == 0)
5329 return clang_getCursorExtent(C);
5330 } else if (PieceIndex < Pieces.size()) {
5331 SourceRange R = Pieces[PieceIndex];
5332 if (R.isValid())
5333 return cxloc::translateSourceRange(getCursorContext(C), R);
5334 }
5335
5336 return clang_getNullRange();
5337}
5338
5339void clang_enableStackTraces(void) {
5340 llvm::sys::PrintStackTraceOnErrorSignal();
5341}
5342
5343void clang_executeOnThread(void (*fn)(void*), void *user_data,
5344 unsigned stack_size) {
5345 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5346}
5347
5348} // end: extern "C"
5349
5350//===----------------------------------------------------------------------===//
5351// Token-based Operations.
5352//===----------------------------------------------------------------------===//
5353
5354/* CXToken layout:
5355 * int_data[0]: a CXTokenKind
5356 * int_data[1]: starting token location
5357 * int_data[2]: token length
5358 * int_data[3]: reserved
5359 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5360 * otherwise unused.
5361 */
5362extern "C" {
5363
5364CXTokenKind clang_getTokenKind(CXToken CXTok) {
5365 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5366}
5367
5368CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5369 switch (clang_getTokenKind(CXTok)) {
5370 case CXToken_Identifier:
5371 case CXToken_Keyword:
5372 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005373 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 ->getNameStart());
5375
5376 case CXToken_Literal: {
5377 // We have stashed the starting pointer in the ptr_data field. Use it.
5378 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005379 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 }
5381
5382 case CXToken_Punctuation:
5383 case CXToken_Comment:
5384 break;
5385 }
5386
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005387 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005388 LOG_BAD_TU(TU);
5389 return cxstring::createEmpty();
5390 }
5391
Guy Benyei11169dd2012-12-18 14:30:41 +00005392 // We have to find the starting buffer pointer the hard way, by
5393 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005394 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005396 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005397
5398 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5399 std::pair<FileID, unsigned> LocInfo
5400 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5401 bool Invalid = false;
5402 StringRef Buffer
5403 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5404 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005405 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005406
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005407 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005408}
5409
5410CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005411 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005412 LOG_BAD_TU(TU);
5413 return clang_getNullLocation();
5414 }
5415
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005416 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005417 if (!CXXUnit)
5418 return clang_getNullLocation();
5419
5420 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5421 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5422}
5423
5424CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005425 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005426 LOG_BAD_TU(TU);
5427 return clang_getNullRange();
5428 }
5429
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005430 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 if (!CXXUnit)
5432 return clang_getNullRange();
5433
5434 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5435 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5436}
5437
5438static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5439 SmallVectorImpl<CXToken> &CXTokens) {
5440 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5441 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005442 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005444 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005445
5446 // Cannot tokenize across files.
5447 if (BeginLocInfo.first != EndLocInfo.first)
5448 return;
5449
5450 // Create a lexer
5451 bool Invalid = false;
5452 StringRef Buffer
5453 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5454 if (Invalid)
5455 return;
5456
5457 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5458 CXXUnit->getASTContext().getLangOpts(),
5459 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5460 Lex.SetCommentRetentionState(true);
5461
5462 // Lex tokens until we hit the end of the range.
5463 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5464 Token Tok;
5465 bool previousWasAt = false;
5466 do {
5467 // Lex the next token
5468 Lex.LexFromRawLexer(Tok);
5469 if (Tok.is(tok::eof))
5470 break;
5471
5472 // Initialize the CXToken.
5473 CXToken CXTok;
5474
5475 // - Common fields
5476 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5477 CXTok.int_data[2] = Tok.getLength();
5478 CXTok.int_data[3] = 0;
5479
5480 // - Kind-specific fields
5481 if (Tok.isLiteral()) {
5482 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005483 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 } else if (Tok.is(tok::raw_identifier)) {
5485 // Lookup the identifier to determine whether we have a keyword.
5486 IdentifierInfo *II
5487 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5488
5489 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5490 CXTok.int_data[0] = CXToken_Keyword;
5491 }
5492 else {
5493 CXTok.int_data[0] = Tok.is(tok::identifier)
5494 ? CXToken_Identifier
5495 : CXToken_Keyword;
5496 }
5497 CXTok.ptr_data = II;
5498 } else if (Tok.is(tok::comment)) {
5499 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005500 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005501 } else {
5502 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005503 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005504 }
5505 CXTokens.push_back(CXTok);
5506 previousWasAt = Tok.is(tok::at);
5507 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5508}
5509
5510void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5511 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005512 LOG_FUNC_SECTION {
5513 *Log << TU << ' ' << Range;
5514 }
5515
Guy Benyei11169dd2012-12-18 14:30:41 +00005516 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005517 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005518 if (NumTokens)
5519 *NumTokens = 0;
5520
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005521 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005522 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005523 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005524 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005525
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005526 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005527 if (!CXXUnit || !Tokens || !NumTokens)
5528 return;
5529
5530 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5531
5532 SourceRange R = cxloc::translateCXSourceRange(Range);
5533 if (R.isInvalid())
5534 return;
5535
5536 SmallVector<CXToken, 32> CXTokens;
5537 getTokens(CXXUnit, R, CXTokens);
5538
5539 if (CXTokens.empty())
5540 return;
5541
5542 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5543 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5544 *NumTokens = CXTokens.size();
5545}
5546
5547void clang_disposeTokens(CXTranslationUnit TU,
5548 CXToken *Tokens, unsigned NumTokens) {
5549 free(Tokens);
5550}
5551
5552} // end: extern "C"
5553
5554//===----------------------------------------------------------------------===//
5555// Token annotation APIs.
5556//===----------------------------------------------------------------------===//
5557
Guy Benyei11169dd2012-12-18 14:30:41 +00005558static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5559 CXCursor parent,
5560 CXClientData client_data);
5561static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5562 CXClientData client_data);
5563
5564namespace {
5565class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005566 CXToken *Tokens;
5567 CXCursor *Cursors;
5568 unsigned NumTokens;
5569 unsigned TokIdx;
5570 unsigned PreprocessingTokIdx;
5571 CursorVisitor AnnotateVis;
5572 SourceManager &SrcMgr;
5573 bool HasContextSensitiveKeywords;
5574
5575 struct PostChildrenInfo {
5576 CXCursor Cursor;
5577 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005578 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005579 unsigned BeforeChildrenTokenIdx;
5580 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005581 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005582
5583 CXToken &getTok(unsigned Idx) {
5584 assert(Idx < NumTokens);
5585 return Tokens[Idx];
5586 }
5587 const CXToken &getTok(unsigned Idx) const {
5588 assert(Idx < NumTokens);
5589 return Tokens[Idx];
5590 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005591 bool MoreTokens() const { return TokIdx < NumTokens; }
5592 unsigned NextToken() const { return TokIdx; }
5593 void AdvanceToken() { ++TokIdx; }
5594 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005595 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 }
5597 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005598 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 }
5600 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005601 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005602 }
5603
5604 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005605 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005606 SourceRange);
5607
5608public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005609 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005610 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005611 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005612 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005613 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005614 AnnotateTokensVisitor, this,
5615 /*VisitPreprocessorLast=*/true,
5616 /*VisitIncludedEntities=*/false,
5617 RegionOfInterest,
5618 /*VisitDeclsOnly=*/false,
5619 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005620 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005621 HasContextSensitiveKeywords(false) { }
5622
5623 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5624 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5625 bool postVisitChildren(CXCursor cursor);
5626 void AnnotateTokens();
5627
5628 /// \brief Determine whether the annotator saw any cursors that have
5629 /// context-sensitive keywords.
5630 bool hasContextSensitiveKeywords() const {
5631 return HasContextSensitiveKeywords;
5632 }
5633
5634 ~AnnotateTokensWorker() {
5635 assert(PostChildrenInfos.empty());
5636 }
5637};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005638}
Guy Benyei11169dd2012-12-18 14:30:41 +00005639
5640void AnnotateTokensWorker::AnnotateTokens() {
5641 // Walk the AST within the region of interest, annotating tokens
5642 // along the way.
5643 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005644}
Guy Benyei11169dd2012-12-18 14:30:41 +00005645
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005646static inline void updateCursorAnnotation(CXCursor &Cursor,
5647 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005648 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005649 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005650 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005651}
5652
5653/// \brief It annotates and advances tokens with a cursor until the comparison
5654//// between the cursor location and the source range is the same as
5655/// \arg compResult.
5656///
5657/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5658/// Pass RangeOverlap to annotate tokens inside a range.
5659void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5660 RangeComparisonResult compResult,
5661 SourceRange range) {
5662 while (MoreTokens()) {
5663 const unsigned I = NextToken();
5664 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005665 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5666 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005667
5668 SourceLocation TokLoc = GetTokenLoc(I);
5669 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005670 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005671 AdvanceToken();
5672 continue;
5673 }
5674 break;
5675 }
5676}
5677
5678/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005679/// \returns true if it advanced beyond all macro tokens, false otherwise.
5680bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 CXCursor updateC,
5682 RangeComparisonResult compResult,
5683 SourceRange range) {
5684 assert(MoreTokens());
5685 assert(isFunctionMacroToken(NextToken()) &&
5686 "Should be called only for macro arg tokens");
5687
5688 // This works differently than annotateAndAdvanceTokens; because expanded
5689 // macro arguments can have arbitrary translation-unit source order, we do not
5690 // advance the token index one by one until a token fails the range test.
5691 // We only advance once past all of the macro arg tokens if all of them
5692 // pass the range test. If one of them fails we keep the token index pointing
5693 // at the start of the macro arg tokens so that the failing token will be
5694 // annotated by a subsequent annotation try.
5695
5696 bool atLeastOneCompFail = false;
5697
5698 unsigned I = NextToken();
5699 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5700 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5701 if (TokLoc.isFileID())
5702 continue; // not macro arg token, it's parens or comma.
5703 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5704 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5705 Cursors[I] = updateC;
5706 } else
5707 atLeastOneCompFail = true;
5708 }
5709
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005710 if (atLeastOneCompFail)
5711 return false;
5712
5713 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5714 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005715}
5716
5717enum CXChildVisitResult
5718AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005719 SourceRange cursorRange = getRawCursorExtent(cursor);
5720 if (cursorRange.isInvalid())
5721 return CXChildVisit_Recurse;
5722
5723 if (!HasContextSensitiveKeywords) {
5724 // Objective-C properties can have context-sensitive keywords.
5725 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005726 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005727 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5728 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5729 }
5730 // Objective-C methods can have context-sensitive keywords.
5731 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5732 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005733 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5735 if (Method->getObjCDeclQualifier())
5736 HasContextSensitiveKeywords = true;
5737 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005738 for (const auto *P : Method->params()) {
5739 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005740 HasContextSensitiveKeywords = true;
5741 break;
5742 }
5743 }
5744 }
5745 }
5746 }
5747 // C++ methods can have context-sensitive keywords.
5748 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005749 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5751 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5752 HasContextSensitiveKeywords = true;
5753 }
5754 }
5755 // C++ classes can have context-sensitive keywords.
5756 else if (cursor.kind == CXCursor_StructDecl ||
5757 cursor.kind == CXCursor_ClassDecl ||
5758 cursor.kind == CXCursor_ClassTemplate ||
5759 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005760 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 if (D->hasAttr<FinalAttr>())
5762 HasContextSensitiveKeywords = true;
5763 }
5764 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005765
5766 // Don't override a property annotation with its getter/setter method.
5767 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5768 parent.kind == CXCursor_ObjCPropertyDecl)
5769 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005770
5771 if (clang_isPreprocessing(cursor.kind)) {
5772 // Items in the preprocessing record are kept separate from items in
5773 // declarations, so we keep a separate token index.
5774 unsigned SavedTokIdx = TokIdx;
5775 TokIdx = PreprocessingTokIdx;
5776
5777 // Skip tokens up until we catch up to the beginning of the preprocessing
5778 // entry.
5779 while (MoreTokens()) {
5780 const unsigned I = NextToken();
5781 SourceLocation TokLoc = GetTokenLoc(I);
5782 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5783 case RangeBefore:
5784 AdvanceToken();
5785 continue;
5786 case RangeAfter:
5787 case RangeOverlap:
5788 break;
5789 }
5790 break;
5791 }
5792
5793 // Look at all of the tokens within this range.
5794 while (MoreTokens()) {
5795 const unsigned I = NextToken();
5796 SourceLocation TokLoc = GetTokenLoc(I);
5797 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5798 case RangeBefore:
5799 llvm_unreachable("Infeasible");
5800 case RangeAfter:
5801 break;
5802 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005803 // For macro expansions, just note where the beginning of the macro
5804 // expansion occurs.
5805 if (cursor.kind == CXCursor_MacroExpansion) {
5806 if (TokLoc == cursorRange.getBegin())
5807 Cursors[I] = cursor;
5808 AdvanceToken();
5809 break;
5810 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005811 // We may have already annotated macro names inside macro definitions.
5812 if (Cursors[I].kind != CXCursor_MacroExpansion)
5813 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005814 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005815 continue;
5816 }
5817 break;
5818 }
5819
5820 // Save the preprocessing token index; restore the non-preprocessing
5821 // token index.
5822 PreprocessingTokIdx = TokIdx;
5823 TokIdx = SavedTokIdx;
5824 return CXChildVisit_Recurse;
5825 }
5826
5827 if (cursorRange.isInvalid())
5828 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005829
5830 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005831 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005832 const enum CXCursorKind K = clang_getCursorKind(parent);
5833 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005834 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5835 // Attributes are annotated out-of-order, skip tokens until we reach it.
5836 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005837 ? clang_getNullCursor() : parent;
5838
5839 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5840
5841 // Avoid having the cursor of an expression "overwrite" the annotation of the
5842 // variable declaration that it belongs to.
5843 // This can happen for C++ constructor expressions whose range generally
5844 // include the variable declaration, e.g.:
5845 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005846 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005847 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005848 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005849 const unsigned I = NextToken();
5850 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5851 E->getLocStart() == D->getLocation() &&
5852 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005853 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005854 AdvanceToken();
5855 }
5856 }
5857 }
5858
5859 // Before recursing into the children keep some state that we are going
5860 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5861 // extra work after the child nodes are visited.
5862 // Note that we don't call VisitChildren here to avoid traversing statements
5863 // code-recursively which can blow the stack.
5864
5865 PostChildrenInfo Info;
5866 Info.Cursor = cursor;
5867 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005868 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005869 Info.BeforeChildrenTokenIdx = NextToken();
5870 PostChildrenInfos.push_back(Info);
5871
5872 return CXChildVisit_Recurse;
5873}
5874
5875bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5876 if (PostChildrenInfos.empty())
5877 return false;
5878 const PostChildrenInfo &Info = PostChildrenInfos.back();
5879 if (!clang_equalCursors(Info.Cursor, cursor))
5880 return false;
5881
5882 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5883 const unsigned AfterChildren = NextToken();
5884 SourceRange cursorRange = Info.CursorRange;
5885
5886 // Scan the tokens that are at the end of the cursor, but are not captured
5887 // but the child cursors.
5888 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5889
5890 // Scan the tokens that are at the beginning of the cursor, but are not
5891 // capture by the child cursors.
5892 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5893 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5894 break;
5895
5896 Cursors[I] = cursor;
5897 }
5898
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005899 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5900 // encountered the attribute cursor.
5901 if (clang_isAttribute(cursor.kind))
5902 TokIdx = Info.BeforeReachingCursorIdx;
5903
Guy Benyei11169dd2012-12-18 14:30:41 +00005904 PostChildrenInfos.pop_back();
5905 return false;
5906}
5907
5908static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5909 CXCursor parent,
5910 CXClientData client_data) {
5911 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5912}
5913
5914static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5915 CXClientData client_data) {
5916 return static_cast<AnnotateTokensWorker*>(client_data)->
5917 postVisitChildren(cursor);
5918}
5919
5920namespace {
5921
5922/// \brief Uses the macro expansions in the preprocessing record to find
5923/// and mark tokens that are macro arguments. This info is used by the
5924/// AnnotateTokensWorker.
5925class MarkMacroArgTokensVisitor {
5926 SourceManager &SM;
5927 CXToken *Tokens;
5928 unsigned NumTokens;
5929 unsigned CurIdx;
5930
5931public:
5932 MarkMacroArgTokensVisitor(SourceManager &SM,
5933 CXToken *tokens, unsigned numTokens)
5934 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5935
5936 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5937 if (cursor.kind != CXCursor_MacroExpansion)
5938 return CXChildVisit_Continue;
5939
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005940 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005941 if (macroRange.getBegin() == macroRange.getEnd())
5942 return CXChildVisit_Continue; // it's not a function macro.
5943
5944 for (; CurIdx < NumTokens; ++CurIdx) {
5945 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5946 macroRange.getBegin()))
5947 break;
5948 }
5949
5950 if (CurIdx == NumTokens)
5951 return CXChildVisit_Break;
5952
5953 for (; CurIdx < NumTokens; ++CurIdx) {
5954 SourceLocation tokLoc = getTokenLoc(CurIdx);
5955 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5956 break;
5957
5958 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5959 }
5960
5961 if (CurIdx == NumTokens)
5962 return CXChildVisit_Break;
5963
5964 return CXChildVisit_Continue;
5965 }
5966
5967private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005968 CXToken &getTok(unsigned Idx) {
5969 assert(Idx < NumTokens);
5970 return Tokens[Idx];
5971 }
5972 const CXToken &getTok(unsigned Idx) const {
5973 assert(Idx < NumTokens);
5974 return Tokens[Idx];
5975 }
5976
Guy Benyei11169dd2012-12-18 14:30:41 +00005977 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005978 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005979 }
5980
5981 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5982 // The third field is reserved and currently not used. Use it here
5983 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005984 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005985 }
5986};
5987
5988} // end anonymous namespace
5989
5990static CXChildVisitResult
5991MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5992 CXClientData client_data) {
5993 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5994 parent);
5995}
5996
5997namespace {
5998 struct clang_annotateTokens_Data {
5999 CXTranslationUnit TU;
6000 ASTUnit *CXXUnit;
6001 CXToken *Tokens;
6002 unsigned NumTokens;
6003 CXCursor *Cursors;
6004 };
6005}
6006
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006007/// \brief Used by \c annotatePreprocessorTokens.
6008/// \returns true if lexing was finished, false otherwise.
6009static bool lexNext(Lexer &Lex, Token &Tok,
6010 unsigned &NextIdx, unsigned NumTokens) {
6011 if (NextIdx >= NumTokens)
6012 return true;
6013
6014 ++NextIdx;
6015 Lex.LexFromRawLexer(Tok);
6016 if (Tok.is(tok::eof))
6017 return true;
6018
6019 return false;
6020}
6021
Guy Benyei11169dd2012-12-18 14:30:41 +00006022static void annotatePreprocessorTokens(CXTranslationUnit TU,
6023 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006024 CXCursor *Cursors,
6025 CXToken *Tokens,
6026 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006027 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006028
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006029 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006030 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6031 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006032 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006033 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006034 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006035
6036 if (BeginLocInfo.first != EndLocInfo.first)
6037 return;
6038
6039 StringRef Buffer;
6040 bool Invalid = false;
6041 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6042 if (Buffer.empty() || Invalid)
6043 return;
6044
6045 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6046 CXXUnit->getASTContext().getLangOpts(),
6047 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6048 Buffer.end());
6049 Lex.SetCommentRetentionState(true);
6050
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006051 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006052 // Lex tokens in raw mode until we hit the end of the range, to avoid
6053 // entering #includes or expanding macros.
6054 while (true) {
6055 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006056 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6057 break;
6058 unsigned TokIdx = NextIdx-1;
6059 assert(Tok.getLocation() ==
6060 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006061
6062 reprocess:
6063 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006064 // We have found a preprocessing directive. Annotate the tokens
6065 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006066 //
6067 // FIXME: Some simple tests here could identify macro definitions and
6068 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006069
6070 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006071 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6072 break;
6073
Craig Topper69186e72014-06-08 08:38:04 +00006074 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006075 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006076 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6077 break;
6078
6079 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006080 IdentifierInfo &II =
6081 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006082 SourceLocation MappedTokLoc =
6083 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6084 MI = getMacroInfo(II, MappedTokLoc, TU);
6085 }
6086 }
6087
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006088 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006089 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006090 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6091 finished = true;
6092 break;
6093 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006094 // If we are in a macro definition, check if the token was ever a
6095 // macro name and annotate it if that's the case.
6096 if (MI) {
6097 SourceLocation SaveLoc = Tok.getLocation();
6098 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006099 MacroDefinitionRecord *MacroDef =
6100 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006101 Tok.setLocation(SaveLoc);
6102 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006103 Cursors[NextIdx - 1] =
6104 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006105 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006106 } while (!Tok.isAtStartOfLine());
6107
6108 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6109 assert(TokIdx <= LastIdx);
6110 SourceLocation EndLoc =
6111 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6112 CXCursor Cursor =
6113 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6114
6115 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006116 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006117
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006118 if (finished)
6119 break;
6120 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006122 }
6123}
6124
6125// This gets run a separate thread to avoid stack blowout.
6126static void clang_annotateTokensImpl(void *UserData) {
6127 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6128 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6129 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6130 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6131 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6132
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006133 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006134 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6135 setThreadBackgroundPriority();
6136
6137 // Determine the region of interest, which contains all of the tokens.
6138 SourceRange RegionOfInterest;
6139 RegionOfInterest.setBegin(
6140 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6141 RegionOfInterest.setEnd(
6142 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6143 Tokens[NumTokens-1])));
6144
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 // Relex the tokens within the source range to look for preprocessing
6146 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006147 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006148
6149 // If begin location points inside a macro argument, set it to the expansion
6150 // location so we can have the full context when annotating semantically.
6151 {
6152 SourceManager &SM = CXXUnit->getSourceManager();
6153 SourceLocation Loc =
6154 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6155 if (Loc.isMacroID())
6156 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6157 }
6158
Guy Benyei11169dd2012-12-18 14:30:41 +00006159 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6160 // Search and mark tokens that are macro argument expansions.
6161 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6162 Tokens, NumTokens);
6163 CursorVisitor MacroArgMarker(TU,
6164 MarkMacroArgTokensVisitorDelegate, &Visitor,
6165 /*VisitPreprocessorLast=*/true,
6166 /*VisitIncludedEntities=*/false,
6167 RegionOfInterest);
6168 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6169 }
6170
6171 // Annotate all of the source locations in the region of interest that map to
6172 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006173 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006174
6175 // FIXME: We use a ridiculous stack size here because the data-recursion
6176 // algorithm uses a large stack frame than the non-data recursive version,
6177 // and AnnotationTokensWorker currently transforms the data-recursion
6178 // algorithm back into a traditional recursion by explicitly calling
6179 // VisitChildren(). We will need to remove this explicit recursive call.
6180 W.AnnotateTokens();
6181
6182 // If we ran into any entities that involve context-sensitive keywords,
6183 // take another pass through the tokens to mark them as such.
6184 if (W.hasContextSensitiveKeywords()) {
6185 for (unsigned I = 0; I != NumTokens; ++I) {
6186 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6187 continue;
6188
6189 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6190 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006191 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006192 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6193 if (Property->getPropertyAttributesAsWritten() != 0 &&
6194 llvm::StringSwitch<bool>(II->getName())
6195 .Case("readonly", true)
6196 .Case("assign", true)
6197 .Case("unsafe_unretained", true)
6198 .Case("readwrite", true)
6199 .Case("retain", true)
6200 .Case("copy", true)
6201 .Case("nonatomic", true)
6202 .Case("atomic", true)
6203 .Case("getter", true)
6204 .Case("setter", true)
6205 .Case("strong", true)
6206 .Case("weak", true)
6207 .Default(false))
6208 Tokens[I].int_data[0] = CXToken_Keyword;
6209 }
6210 continue;
6211 }
6212
6213 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6214 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6215 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6216 if (llvm::StringSwitch<bool>(II->getName())
6217 .Case("in", true)
6218 .Case("out", true)
6219 .Case("inout", true)
6220 .Case("oneway", true)
6221 .Case("bycopy", true)
6222 .Case("byref", true)
6223 .Default(false))
6224 Tokens[I].int_data[0] = CXToken_Keyword;
6225 continue;
6226 }
6227
6228 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6229 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6230 Tokens[I].int_data[0] = CXToken_Keyword;
6231 continue;
6232 }
6233 }
6234 }
6235}
6236
6237extern "C" {
6238
6239void clang_annotateTokens(CXTranslationUnit TU,
6240 CXToken *Tokens, unsigned NumTokens,
6241 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006242 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006243 LOG_BAD_TU(TU);
6244 return;
6245 }
6246 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006247 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006248 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006249 }
6250
6251 LOG_FUNC_SECTION {
6252 *Log << TU << ' ';
6253 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6254 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6255 *Log << clang_getRange(bloc, eloc);
6256 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006257
6258 // Any token we don't specifically annotate will have a NULL cursor.
6259 CXCursor C = clang_getNullCursor();
6260 for (unsigned I = 0; I != NumTokens; ++I)
6261 Cursors[I] = C;
6262
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006263 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006264 if (!CXXUnit)
6265 return;
6266
6267 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6268
6269 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6270 llvm::CrashRecoveryContext CRC;
6271 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6272 GetSafetyThreadStackSize() * 2)) {
6273 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6274 }
6275}
6276
6277} // end: extern "C"
6278
6279//===----------------------------------------------------------------------===//
6280// Operations for querying linkage of a cursor.
6281//===----------------------------------------------------------------------===//
6282
6283extern "C" {
6284CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6285 if (!clang_isDeclaration(cursor.kind))
6286 return CXLinkage_Invalid;
6287
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006288 const Decl *D = cxcursor::getCursorDecl(cursor);
6289 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006290 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006291 case NoLinkage:
6292 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006293 case InternalLinkage: return CXLinkage_Internal;
6294 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6295 case ExternalLinkage: return CXLinkage_External;
6296 };
6297
6298 return CXLinkage_Invalid;
6299}
6300} // end: extern "C"
6301
6302//===----------------------------------------------------------------------===//
6303// Operations for querying language of a cursor.
6304//===----------------------------------------------------------------------===//
6305
6306static CXLanguageKind getDeclLanguage(const Decl *D) {
6307 if (!D)
6308 return CXLanguage_C;
6309
6310 switch (D->getKind()) {
6311 default:
6312 break;
6313 case Decl::ImplicitParam:
6314 case Decl::ObjCAtDefsField:
6315 case Decl::ObjCCategory:
6316 case Decl::ObjCCategoryImpl:
6317 case Decl::ObjCCompatibleAlias:
6318 case Decl::ObjCImplementation:
6319 case Decl::ObjCInterface:
6320 case Decl::ObjCIvar:
6321 case Decl::ObjCMethod:
6322 case Decl::ObjCProperty:
6323 case Decl::ObjCPropertyImpl:
6324 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006325 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006326 return CXLanguage_ObjC;
6327 case Decl::CXXConstructor:
6328 case Decl::CXXConversion:
6329 case Decl::CXXDestructor:
6330 case Decl::CXXMethod:
6331 case Decl::CXXRecord:
6332 case Decl::ClassTemplate:
6333 case Decl::ClassTemplatePartialSpecialization:
6334 case Decl::ClassTemplateSpecialization:
6335 case Decl::Friend:
6336 case Decl::FriendTemplate:
6337 case Decl::FunctionTemplate:
6338 case Decl::LinkageSpec:
6339 case Decl::Namespace:
6340 case Decl::NamespaceAlias:
6341 case Decl::NonTypeTemplateParm:
6342 case Decl::StaticAssert:
6343 case Decl::TemplateTemplateParm:
6344 case Decl::TemplateTypeParm:
6345 case Decl::UnresolvedUsingTypename:
6346 case Decl::UnresolvedUsingValue:
6347 case Decl::Using:
6348 case Decl::UsingDirective:
6349 case Decl::UsingShadow:
6350 return CXLanguage_CPlusPlus;
6351 }
6352
6353 return CXLanguage_C;
6354}
6355
6356extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006357
6358static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6359 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6360 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006361
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006362 switch (D->getAvailability()) {
6363 case AR_Available:
6364 case AR_NotYetIntroduced:
6365 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006366 return getCursorAvailabilityForDecl(
6367 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006368 return CXAvailability_Available;
6369
6370 case AR_Deprecated:
6371 return CXAvailability_Deprecated;
6372
6373 case AR_Unavailable:
6374 return CXAvailability_NotAvailable;
6375 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006376
6377 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006378}
6379
Guy Benyei11169dd2012-12-18 14:30:41 +00006380enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6381 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006382 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6383 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006384
6385 return CXAvailability_Available;
6386}
6387
6388static CXVersion convertVersion(VersionTuple In) {
6389 CXVersion Out = { -1, -1, -1 };
6390 if (In.empty())
6391 return Out;
6392
6393 Out.Major = In.getMajor();
6394
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006395 Optional<unsigned> Minor = In.getMinor();
6396 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006397 Out.Minor = *Minor;
6398 else
6399 return Out;
6400
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006401 Optional<unsigned> Subminor = In.getSubminor();
6402 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006403 Out.Subminor = *Subminor;
6404
6405 return Out;
6406}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006407
6408static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6409 int *always_deprecated,
6410 CXString *deprecated_message,
6411 int *always_unavailable,
6412 CXString *unavailable_message,
6413 CXPlatformAvailability *availability,
6414 int availability_size) {
6415 bool HadAvailAttr = false;
6416 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006417 for (auto A : D->attrs()) {
6418 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006419 HadAvailAttr = true;
6420 if (always_deprecated)
6421 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006422 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006423 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006424 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006425 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006426 continue;
6427 }
6428
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006429 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006430 HadAvailAttr = true;
6431 if (always_unavailable)
6432 *always_unavailable = 1;
6433 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006434 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006435 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6436 }
6437 continue;
6438 }
6439
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006440 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006441 HadAvailAttr = true;
6442 if (N < availability_size) {
6443 availability[N].Platform
6444 = cxstring::createDup(Avail->getPlatform()->getName());
6445 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6446 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6447 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6448 availability[N].Unavailable = Avail->getUnavailable();
6449 availability[N].Message = cxstring::createDup(Avail->getMessage());
6450 }
6451 ++N;
6452 }
6453 }
6454
6455 if (!HadAvailAttr)
6456 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6457 return getCursorPlatformAvailabilityForDecl(
6458 cast<Decl>(EnumConst->getDeclContext()),
6459 always_deprecated,
6460 deprecated_message,
6461 always_unavailable,
6462 unavailable_message,
6463 availability,
6464 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006465
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006466 return N;
6467}
6468
Guy Benyei11169dd2012-12-18 14:30:41 +00006469int clang_getCursorPlatformAvailability(CXCursor cursor,
6470 int *always_deprecated,
6471 CXString *deprecated_message,
6472 int *always_unavailable,
6473 CXString *unavailable_message,
6474 CXPlatformAvailability *availability,
6475 int availability_size) {
6476 if (always_deprecated)
6477 *always_deprecated = 0;
6478 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006479 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006480 if (always_unavailable)
6481 *always_unavailable = 0;
6482 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006483 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006484
Guy Benyei11169dd2012-12-18 14:30:41 +00006485 if (!clang_isDeclaration(cursor.kind))
6486 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006487
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006488 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006489 if (!D)
6490 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006491
6492 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6493 deprecated_message,
6494 always_unavailable,
6495 unavailable_message,
6496 availability,
6497 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006498}
6499
6500void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6501 clang_disposeString(availability->Platform);
6502 clang_disposeString(availability->Message);
6503}
6504
6505CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6506 if (clang_isDeclaration(cursor.kind))
6507 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6508
6509 return CXLanguage_Invalid;
6510}
6511
6512 /// \brief If the given cursor is the "templated" declaration
6513 /// descibing a class or function template, return the class or
6514 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006515static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006516 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006517 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006518
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006519 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006520 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6521 return FunTmpl;
6522
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006523 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006524 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6525 return ClassTmpl;
6526
6527 return D;
6528}
6529
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006530
6531enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6532 StorageClass sc = SC_None;
6533 const Decl *D = getCursorDecl(C);
6534 if (D) {
6535 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6536 sc = FD->getStorageClass();
6537 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6538 sc = VD->getStorageClass();
6539 } else {
6540 return CX_SC_Invalid;
6541 }
6542 } else {
6543 return CX_SC_Invalid;
6544 }
6545 switch (sc) {
6546 case SC_None:
6547 return CX_SC_None;
6548 case SC_Extern:
6549 return CX_SC_Extern;
6550 case SC_Static:
6551 return CX_SC_Static;
6552 case SC_PrivateExtern:
6553 return CX_SC_PrivateExtern;
6554 case SC_OpenCLWorkGroupLocal:
6555 return CX_SC_OpenCLWorkGroupLocal;
6556 case SC_Auto:
6557 return CX_SC_Auto;
6558 case SC_Register:
6559 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006560 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006561 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006562}
6563
Guy Benyei11169dd2012-12-18 14:30:41 +00006564CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6565 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006566 if (const Decl *D = getCursorDecl(cursor)) {
6567 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006568 if (!DC)
6569 return clang_getNullCursor();
6570
6571 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6572 getCursorTU(cursor));
6573 }
6574 }
6575
6576 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006577 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006578 return MakeCXCursor(D, getCursorTU(cursor));
6579 }
6580
6581 return clang_getNullCursor();
6582}
6583
6584CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6585 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006586 if (const Decl *D = getCursorDecl(cursor)) {
6587 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006588 if (!DC)
6589 return clang_getNullCursor();
6590
6591 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6592 getCursorTU(cursor));
6593 }
6594 }
6595
6596 // FIXME: Note that we can't easily compute the lexical context of a
6597 // statement or expression, so we return nothing.
6598 return clang_getNullCursor();
6599}
6600
6601CXFile clang_getIncludedFile(CXCursor cursor) {
6602 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006603 return nullptr;
6604
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006605 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006606 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006607}
6608
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006609unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6610 if (C.kind != CXCursor_ObjCPropertyDecl)
6611 return CXObjCPropertyAttr_noattr;
6612
6613 unsigned Result = CXObjCPropertyAttr_noattr;
6614 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6615 ObjCPropertyDecl::PropertyAttributeKind Attr =
6616 PD->getPropertyAttributesAsWritten();
6617
6618#define SET_CXOBJCPROP_ATTR(A) \
6619 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6620 Result |= CXObjCPropertyAttr_##A
6621 SET_CXOBJCPROP_ATTR(readonly);
6622 SET_CXOBJCPROP_ATTR(getter);
6623 SET_CXOBJCPROP_ATTR(assign);
6624 SET_CXOBJCPROP_ATTR(readwrite);
6625 SET_CXOBJCPROP_ATTR(retain);
6626 SET_CXOBJCPROP_ATTR(copy);
6627 SET_CXOBJCPROP_ATTR(nonatomic);
6628 SET_CXOBJCPROP_ATTR(setter);
6629 SET_CXOBJCPROP_ATTR(atomic);
6630 SET_CXOBJCPROP_ATTR(weak);
6631 SET_CXOBJCPROP_ATTR(strong);
6632 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6633#undef SET_CXOBJCPROP_ATTR
6634
6635 return Result;
6636}
6637
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006638unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6639 if (!clang_isDeclaration(C.kind))
6640 return CXObjCDeclQualifier_None;
6641
6642 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6643 const Decl *D = getCursorDecl(C);
6644 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6645 QT = MD->getObjCDeclQualifier();
6646 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6647 QT = PD->getObjCDeclQualifier();
6648 if (QT == Decl::OBJC_TQ_None)
6649 return CXObjCDeclQualifier_None;
6650
6651 unsigned Result = CXObjCDeclQualifier_None;
6652 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6653 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6654 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6655 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6656 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6657 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6658
6659 return Result;
6660}
6661
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006662unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6663 if (!clang_isDeclaration(C.kind))
6664 return 0;
6665
6666 const Decl *D = getCursorDecl(C);
6667 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6668 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6669 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6670 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6671
6672 return 0;
6673}
6674
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006675unsigned clang_Cursor_isVariadic(CXCursor C) {
6676 if (!clang_isDeclaration(C.kind))
6677 return 0;
6678
6679 const Decl *D = getCursorDecl(C);
6680 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6681 return FD->isVariadic();
6682 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6683 return MD->isVariadic();
6684
6685 return 0;
6686}
6687
Guy Benyei11169dd2012-12-18 14:30:41 +00006688CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6689 if (!clang_isDeclaration(C.kind))
6690 return clang_getNullRange();
6691
6692 const Decl *D = getCursorDecl(C);
6693 ASTContext &Context = getCursorContext(C);
6694 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6695 if (!RC)
6696 return clang_getNullRange();
6697
6698 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6699}
6700
6701CXString clang_Cursor_getRawCommentText(CXCursor C) {
6702 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006703 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006704
6705 const Decl *D = getCursorDecl(C);
6706 ASTContext &Context = getCursorContext(C);
6707 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6708 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6709 StringRef();
6710
6711 // Don't duplicate the string because RawText points directly into source
6712 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006713 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006714}
6715
6716CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6717 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006718 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006719
6720 const Decl *D = getCursorDecl(C);
6721 const ASTContext &Context = getCursorContext(C);
6722 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6723
6724 if (RC) {
6725 StringRef BriefText = RC->getBriefText(Context);
6726
6727 // Don't duplicate the string because RawComment ensures that this memory
6728 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006729 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006730 }
6731
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006732 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006733}
6734
Guy Benyei11169dd2012-12-18 14:30:41 +00006735CXModule clang_Cursor_getModule(CXCursor C) {
6736 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006737 if (const ImportDecl *ImportD =
6738 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006739 return ImportD->getImportedModule();
6740 }
6741
Craig Topper69186e72014-06-08 08:38:04 +00006742 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006743}
6744
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006745CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6746 if (isNotUsableTU(TU)) {
6747 LOG_BAD_TU(TU);
6748 return nullptr;
6749 }
6750 if (!File)
6751 return nullptr;
6752 FileEntry *FE = static_cast<FileEntry *>(File);
6753
6754 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6755 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6756 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6757
Richard Smithfeb54b62014-10-23 02:01:19 +00006758 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006759}
6760
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006761CXFile clang_Module_getASTFile(CXModule CXMod) {
6762 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006763 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006764 Module *Mod = static_cast<Module*>(CXMod);
6765 return const_cast<FileEntry *>(Mod->getASTFile());
6766}
6767
Guy Benyei11169dd2012-12-18 14:30:41 +00006768CXModule clang_Module_getParent(CXModule CXMod) {
6769 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006770 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006771 Module *Mod = static_cast<Module*>(CXMod);
6772 return Mod->Parent;
6773}
6774
6775CXString clang_Module_getName(CXModule CXMod) {
6776 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006777 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006778 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006779 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006780}
6781
6782CXString clang_Module_getFullName(CXModule CXMod) {
6783 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006784 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006785 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006786 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006787}
6788
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006789int clang_Module_isSystem(CXModule CXMod) {
6790 if (!CXMod)
6791 return 0;
6792 Module *Mod = static_cast<Module*>(CXMod);
6793 return Mod->IsSystem;
6794}
6795
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006796unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6797 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006798 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006799 LOG_BAD_TU(TU);
6800 return 0;
6801 }
6802 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006803 return 0;
6804 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006805 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6806 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6807 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006808}
6809
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006810CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6811 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006812 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006813 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006814 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006815 }
6816 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006817 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006818 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006819 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006820
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006821 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6822 if (Index < TopHeaders.size())
6823 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006824
Craig Topper69186e72014-06-08 08:38:04 +00006825 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006826}
6827
6828} // end: extern "C"
6829
6830//===----------------------------------------------------------------------===//
6831// C++ AST instrospection.
6832//===----------------------------------------------------------------------===//
6833
6834extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006835unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6836 if (!clang_isDeclaration(C.kind))
6837 return 0;
6838
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006839 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006840 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006841 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006842 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6843}
6844
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006845unsigned clang_CXXMethod_isConst(CXCursor C) {
6846 if (!clang_isDeclaration(C.kind))
6847 return 0;
6848
6849 const Decl *D = cxcursor::getCursorDecl(C);
6850 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006851 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006852 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6853}
6854
Guy Benyei11169dd2012-12-18 14:30:41 +00006855unsigned clang_CXXMethod_isStatic(CXCursor C) {
6856 if (!clang_isDeclaration(C.kind))
6857 return 0;
6858
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006859 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006860 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006861 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006862 return (Method && Method->isStatic()) ? 1 : 0;
6863}
6864
6865unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6866 if (!clang_isDeclaration(C.kind))
6867 return 0;
6868
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006869 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006870 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006871 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006872 return (Method && Method->isVirtual()) ? 1 : 0;
6873}
6874} // end: extern "C"
6875
6876//===----------------------------------------------------------------------===//
6877// Attribute introspection.
6878//===----------------------------------------------------------------------===//
6879
6880extern "C" {
6881CXType clang_getIBOutletCollectionType(CXCursor C) {
6882 if (C.kind != CXCursor_IBOutletCollectionAttr)
6883 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6884
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006885 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006886 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6887
6888 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6889}
6890} // end: extern "C"
6891
6892//===----------------------------------------------------------------------===//
6893// Inspecting memory usage.
6894//===----------------------------------------------------------------------===//
6895
6896typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6897
6898static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6899 enum CXTUResourceUsageKind k,
6900 unsigned long amount) {
6901 CXTUResourceUsageEntry entry = { k, amount };
6902 entries.push_back(entry);
6903}
6904
6905extern "C" {
6906
6907const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6908 const char *str = "";
6909 switch (kind) {
6910 case CXTUResourceUsage_AST:
6911 str = "ASTContext: expressions, declarations, and types";
6912 break;
6913 case CXTUResourceUsage_Identifiers:
6914 str = "ASTContext: identifiers";
6915 break;
6916 case CXTUResourceUsage_Selectors:
6917 str = "ASTContext: selectors";
6918 break;
6919 case CXTUResourceUsage_GlobalCompletionResults:
6920 str = "Code completion: cached global results";
6921 break;
6922 case CXTUResourceUsage_SourceManagerContentCache:
6923 str = "SourceManager: content cache allocator";
6924 break;
6925 case CXTUResourceUsage_AST_SideTables:
6926 str = "ASTContext: side tables";
6927 break;
6928 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6929 str = "SourceManager: malloc'ed memory buffers";
6930 break;
6931 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6932 str = "SourceManager: mmap'ed memory buffers";
6933 break;
6934 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6935 str = "ExternalASTSource: malloc'ed memory buffers";
6936 break;
6937 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6938 str = "ExternalASTSource: mmap'ed memory buffers";
6939 break;
6940 case CXTUResourceUsage_Preprocessor:
6941 str = "Preprocessor: malloc'ed memory";
6942 break;
6943 case CXTUResourceUsage_PreprocessingRecord:
6944 str = "Preprocessor: PreprocessingRecord";
6945 break;
6946 case CXTUResourceUsage_SourceManager_DataStructures:
6947 str = "SourceManager: data structures and tables";
6948 break;
6949 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6950 str = "Preprocessor: header search tables";
6951 break;
6952 }
6953 return str;
6954}
6955
6956CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006957 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006958 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006959 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006960 return usage;
6961 }
6962
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006963 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006964 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006965 ASTContext &astContext = astUnit->getASTContext();
6966
6967 // How much memory is used by AST nodes and types?
6968 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6969 (unsigned long) astContext.getASTAllocatedMemory());
6970
6971 // How much memory is used by identifiers?
6972 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6973 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6974
6975 // How much memory is used for selectors?
6976 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6977 (unsigned long) astContext.Selectors.getTotalMemory());
6978
6979 // How much memory is used by ASTContext's side tables?
6980 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6981 (unsigned long) astContext.getSideTableAllocatedMemory());
6982
6983 // How much memory is used for caching global code completion results?
6984 unsigned long completionBytes = 0;
6985 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006986 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006987 completionBytes = completionAllocator->getTotalMemory();
6988 }
6989 createCXTUResourceUsageEntry(*entries,
6990 CXTUResourceUsage_GlobalCompletionResults,
6991 completionBytes);
6992
6993 // How much memory is being used by SourceManager's content cache?
6994 createCXTUResourceUsageEntry(*entries,
6995 CXTUResourceUsage_SourceManagerContentCache,
6996 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6997
6998 // How much memory is being used by the MemoryBuffer's in SourceManager?
6999 const SourceManager::MemoryBufferSizes &srcBufs =
7000 astUnit->getSourceManager().getMemoryBufferSizes();
7001
7002 createCXTUResourceUsageEntry(*entries,
7003 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7004 (unsigned long) srcBufs.malloc_bytes);
7005 createCXTUResourceUsageEntry(*entries,
7006 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7007 (unsigned long) srcBufs.mmap_bytes);
7008 createCXTUResourceUsageEntry(*entries,
7009 CXTUResourceUsage_SourceManager_DataStructures,
7010 (unsigned long) astContext.getSourceManager()
7011 .getDataStructureSizes());
7012
7013 // How much memory is being used by the ExternalASTSource?
7014 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7015 const ExternalASTSource::MemoryBufferSizes &sizes =
7016 esrc->getMemoryBufferSizes();
7017
7018 createCXTUResourceUsageEntry(*entries,
7019 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7020 (unsigned long) sizes.malloc_bytes);
7021 createCXTUResourceUsageEntry(*entries,
7022 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7023 (unsigned long) sizes.mmap_bytes);
7024 }
7025
7026 // How much memory is being used by the Preprocessor?
7027 Preprocessor &pp = astUnit->getPreprocessor();
7028 createCXTUResourceUsageEntry(*entries,
7029 CXTUResourceUsage_Preprocessor,
7030 pp.getTotalMemory());
7031
7032 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7033 createCXTUResourceUsageEntry(*entries,
7034 CXTUResourceUsage_PreprocessingRecord,
7035 pRec->getTotalMemory());
7036 }
7037
7038 createCXTUResourceUsageEntry(*entries,
7039 CXTUResourceUsage_Preprocessor_HeaderSearch,
7040 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007041
Guy Benyei11169dd2012-12-18 14:30:41 +00007042 CXTUResourceUsage usage = { (void*) entries.get(),
7043 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007044 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007045 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007046 return usage;
7047}
7048
7049void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7050 if (usage.data)
7051 delete (MemUsageEntries*) usage.data;
7052}
7053
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007054CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7055 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007056 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007057 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007058
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007059 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007060 LOG_BAD_TU(TU);
7061 return skipped;
7062 }
7063
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007064 if (!file)
7065 return skipped;
7066
7067 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7068 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7069 if (!ppRec)
7070 return skipped;
7071
7072 ASTContext &Ctx = astUnit->getASTContext();
7073 SourceManager &sm = Ctx.getSourceManager();
7074 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7075 FileID wantedFileID = sm.translateFile(fileEntry);
7076
7077 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7078 std::vector<SourceRange> wantedRanges;
7079 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7080 i != ei; ++i) {
7081 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7082 wantedRanges.push_back(*i);
7083 }
7084
7085 skipped->count = wantedRanges.size();
7086 skipped->ranges = new CXSourceRange[skipped->count];
7087 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7088 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7089
7090 return skipped;
7091}
7092
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007093void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7094 if (ranges) {
7095 delete[] ranges->ranges;
7096 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007097 }
7098}
7099
Guy Benyei11169dd2012-12-18 14:30:41 +00007100} // end extern "C"
7101
7102void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7103 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7104 for (unsigned I = 0; I != Usage.numEntries; ++I)
7105 fprintf(stderr, " %s: %lu\n",
7106 clang_getTUResourceUsageName(Usage.entries[I].kind),
7107 Usage.entries[I].amount);
7108
7109 clang_disposeCXTUResourceUsage(Usage);
7110}
7111
7112//===----------------------------------------------------------------------===//
7113// Misc. utility functions.
7114//===----------------------------------------------------------------------===//
7115
7116/// Default to using an 8 MB stack size on "safety" threads.
7117static unsigned SafetyStackThreadSize = 8 << 20;
7118
7119namespace clang {
7120
7121bool RunSafely(llvm::CrashRecoveryContext &CRC,
7122 void (*Fn)(void*), void *UserData,
7123 unsigned Size) {
7124 if (!Size)
7125 Size = GetSafetyThreadStackSize();
7126 if (Size)
7127 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7128 return CRC.RunSafely(Fn, UserData);
7129}
7130
7131unsigned GetSafetyThreadStackSize() {
7132 return SafetyStackThreadSize;
7133}
7134
7135void SetSafetyThreadStackSize(unsigned Value) {
7136 SafetyStackThreadSize = Value;
7137}
7138
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007139}
Guy Benyei11169dd2012-12-18 14:30:41 +00007140
7141void clang::setThreadBackgroundPriority() {
7142 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7143 return;
7144
Alp Toker1a86ad22014-07-06 06:24:00 +00007145#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007146 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7147#endif
7148}
7149
7150void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7151 if (!Unit)
7152 return;
7153
7154 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7155 DEnd = Unit->stored_diag_end();
7156 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007157 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007158 CXString Msg = clang_formatDiagnostic(&Diag,
7159 clang_defaultDiagnosticDisplayOptions());
7160 fprintf(stderr, "%s\n", clang_getCString(Msg));
7161 clang_disposeString(Msg);
7162 }
7163#ifdef LLVM_ON_WIN32
7164 // On Windows, force a flush, since there may be multiple copies of
7165 // stderr and stdout in the file system, all with different buffers
7166 // but writing to the same device.
7167 fflush(stderr);
7168#endif
7169}
7170
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007171MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7172 SourceLocation MacroDefLoc,
7173 CXTranslationUnit TU){
7174 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007175 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007176 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007177 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007178
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007179 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007180 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007181 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007182 if (MD) {
7183 for (MacroDirective::DefInfo
7184 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7185 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7186 return Def.getMacroInfo();
7187 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007188 }
7189
Craig Topper69186e72014-06-08 08:38:04 +00007190 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007191}
7192
Richard Smith66a81862015-05-04 02:25:31 +00007193const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007194 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007195 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007196 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007197 const IdentifierInfo *II = MacroDef->getName();
7198 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007199 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007200
7201 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7202}
7203
Richard Smith66a81862015-05-04 02:25:31 +00007204MacroDefinitionRecord *
7205cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7206 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007207 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007208 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007209 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007210 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007211
7212 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007213 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007214 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7215 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007216 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007217
7218 // Check that the token is inside the definition and not its argument list.
7219 SourceManager &SM = Unit->getSourceManager();
7220 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007221 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007222 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007223 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007224
7225 Preprocessor &PP = Unit->getPreprocessor();
7226 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7227 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007228 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007229
Alp Toker2d57cea2014-05-17 04:53:25 +00007230 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007231 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007232 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007233
7234 // Check that the identifier is not one of the macro arguments.
7235 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007236 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007237
Richard Smith20e883e2015-04-29 23:20:19 +00007238 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007239 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007240 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007241
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007242 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007243}
7244
Richard Smith66a81862015-05-04 02:25:31 +00007245MacroDefinitionRecord *
7246cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7247 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007248 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007249 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007250
7251 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007252 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007254 Preprocessor &PP = Unit->getPreprocessor();
7255 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007256 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007257 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7258 Token Tok;
7259 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007260 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007261
7262 return checkForMacroInMacroDefinition(MI, Tok, TU);
7263}
7264
Guy Benyei11169dd2012-12-18 14:30:41 +00007265extern "C" {
7266
7267CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007268 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007269}
7270
7271} // end: extern "C"
7272
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007273Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7274 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007275 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007276 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007277 if (Unit->isMainFileAST())
7278 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007279 return *this;
7280 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007281 } else {
7282 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007283 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007284 return *this;
7285}
7286
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007287Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7288 *this << FE->getName();
7289 return *this;
7290}
7291
7292Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7293 CXString cursorName = clang_getCursorDisplayName(cursor);
7294 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7295 clang_disposeString(cursorName);
7296 return *this;
7297}
7298
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007299Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7300 CXFile File;
7301 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007302 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007303 CXString FileName = clang_getFileName(File);
7304 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7305 clang_disposeString(FileName);
7306 return *this;
7307}
7308
7309Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7310 CXSourceLocation BLoc = clang_getRangeStart(range);
7311 CXSourceLocation ELoc = clang_getRangeEnd(range);
7312
7313 CXFile BFile;
7314 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007315 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007316
7317 CXFile EFile;
7318 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007319 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007320
7321 CXString BFileName = clang_getFileName(BFile);
7322 if (BFile == EFile) {
7323 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7324 BLine, BColumn, ELine, EColumn);
7325 } else {
7326 CXString EFileName = clang_getFileName(EFile);
7327 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7328 BLine, BColumn)
7329 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7330 ELine, EColumn);
7331 clang_disposeString(EFileName);
7332 }
7333 clang_disposeString(BFileName);
7334 return *this;
7335}
7336
7337Logger &cxindex::Logger::operator<<(CXString Str) {
7338 *this << clang_getCString(Str);
7339 return *this;
7340}
7341
7342Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7343 LogOS << Fmt;
7344 return *this;
7345}
7346
Chandler Carruth37ad2582014-06-27 15:14:39 +00007347static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7348
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007349cxindex::Logger::~Logger() {
7350 LogOS.flush();
7351
Chandler Carruth37ad2582014-06-27 15:14:39 +00007352 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007353
7354 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7355
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007356 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007357 OS << "[libclang:" << Name << ':';
7358
Alp Toker1a86ad22014-07-06 06:24:00 +00007359#ifdef USE_DARWIN_THREADS
7360 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007361 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7362 OS << tid << ':';
7363#endif
7364
7365 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7366 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007367 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007368
7369 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007370 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007371 OS << "--------------------------------------------------\n";
7372 }
7373}