blob: 6a17f576484067a301d6c27bd6083998f386502f [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 Bataev6125da92014-07-21 11:26:11 +00001883 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001884 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001885 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001886 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001887 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888
Guy Benyei11169dd2012-12-18 14:30:41 +00001889private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1892 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1894 void AddStmt(const Stmt *S);
1895 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001896 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001898 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001899};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001900} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001901
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 // 'S' should always be non-null, since it comes from the
1904 // statement we are visiting.
1905 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1906}
1907
1908void
1909EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1910 if (Qualifier)
1911 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1912}
1913
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001914void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001915 if (S)
1916 WL.push_back(StmtVisit(S, Parent));
1917}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001918void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001919 if (D)
1920 WL.push_back(DeclVisit(D, Parent, isFirst));
1921}
1922void EnqueueVisitor::
1923 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1924 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001925 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001926}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001927void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001928 if (D)
1929 WL.push_back(MemberRefVisit(D, L, Parent));
1930}
1931void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1932 if (TI)
1933 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1934 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001935void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001936 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001937 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001938 AddStmt(*Child);
1939 }
1940 if (size == WL.size())
1941 return;
1942 // Now reverse the entries we just added. This will match the DFS
1943 // ordering performed by the worklist.
1944 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1945 std::reverse(I, E);
1946}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947namespace {
1948class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1949 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001950 /// \brief Process clauses with list of variables.
1951 template <typename T>
1952 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001953public:
1954 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1955#define OPENMP_CLAUSE(Name, Class) \
1956 void Visit##Class(const Class *C);
1957#include "clang/Basic/OpenMPKinds.def"
1958};
1959
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001960void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1961 Visitor->AddStmt(C->getCondition());
1962}
1963
Alexey Bataev3778b602014-07-17 07:32:53 +00001964void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1965 Visitor->AddStmt(C->getCondition());
1966}
1967
Alexey Bataev568a8332014-03-06 06:15:19 +00001968void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1969 Visitor->AddStmt(C->getNumThreads());
1970}
1971
Alexey Bataev62c87d22014-03-21 04:51:18 +00001972void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1973 Visitor->AddStmt(C->getSafelen());
1974}
1975
Alexander Musman8bd31e62014-05-27 15:12:19 +00001976void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1977 Visitor->AddStmt(C->getNumForLoops());
1978}
1979
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001980void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001981
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001982void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1983
Alexey Bataev56dafe82014-06-20 07:16:17 +00001984void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1985 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00001986 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00001987}
1988
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001989void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1990
Alexey Bataev236070f2014-06-20 11:19:47 +00001991void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1992
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001993void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1994
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001995void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1996
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001997void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1998
Alexey Bataevdea47612014-07-23 07:46:59 +00001999void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2000
Alexey Bataev67a4f222014-07-23 10:25:33 +00002001void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2002
Alexey Bataev459dec02014-07-24 06:46:57 +00002003void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2004
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002005void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2006
Alexey Bataev756c1962013-09-24 03:17:45 +00002007template<typename T>
2008void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002009 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002010 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002011 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002012}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002013
2014void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002015 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002016 for (const auto *E : C->private_copies()) {
2017 Visitor->AddStmt(E);
2018 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002019}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002020void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2021 const OMPFirstprivateClause *C) {
2022 VisitOMPClauseList(C);
2023}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002024void OMPClauseEnqueue::VisitOMPLastprivateClause(
2025 const OMPLastprivateClause *C) {
2026 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002027 for (auto *E : C->private_copies()) {
2028 Visitor->AddStmt(E);
2029 }
2030 for (auto *E : C->source_exprs()) {
2031 Visitor->AddStmt(E);
2032 }
2033 for (auto *E : C->destination_exprs()) {
2034 Visitor->AddStmt(E);
2035 }
2036 for (auto *E : C->assignment_ops()) {
2037 Visitor->AddStmt(E);
2038 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002039}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002040void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002041 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002042}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002043void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2044 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002045 for (auto *E : C->lhs_exprs()) {
2046 Visitor->AddStmt(E);
2047 }
2048 for (auto *E : C->rhs_exprs()) {
2049 Visitor->AddStmt(E);
2050 }
2051 for (auto *E : C->reduction_ops()) {
2052 Visitor->AddStmt(E);
2053 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002054}
Alexander Musman8dba6642014-04-22 13:09:42 +00002055void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2056 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002057 for (const auto *E : C->inits()) {
2058 Visitor->AddStmt(E);
2059 }
2060 for (const auto *E : C->updates()) {
2061 Visitor->AddStmt(E);
2062 }
2063 for (const auto *E : C->finals()) {
2064 Visitor->AddStmt(E);
2065 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002066 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002067 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002068}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002069void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2070 VisitOMPClauseList(C);
2071 Visitor->AddStmt(C->getAlignment());
2072}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002073void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2074 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002075 for (auto *E : C->source_exprs()) {
2076 Visitor->AddStmt(E);
2077 }
2078 for (auto *E : C->destination_exprs()) {
2079 Visitor->AddStmt(E);
2080 }
2081 for (auto *E : C->assignment_ops()) {
2082 Visitor->AddStmt(E);
2083 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002084}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002085void
2086OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2087 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002088 for (auto *E : C->source_exprs()) {
2089 Visitor->AddStmt(E);
2090 }
2091 for (auto *E : C->destination_exprs()) {
2092 Visitor->AddStmt(E);
2093 }
2094 for (auto *E : C->assignment_ops()) {
2095 Visitor->AddStmt(E);
2096 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002097}
Alexey Bataev6125da92014-07-21 11:26:11 +00002098void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2099 VisitOMPClauseList(C);
2100}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002101void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2102 VisitOMPClauseList(C);
2103}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002104}
Alexey Bataev756c1962013-09-24 03:17:45 +00002105
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002106void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2107 unsigned size = WL.size();
2108 OMPClauseEnqueue Visitor(this);
2109 Visitor.Visit(S);
2110 if (size == WL.size())
2111 return;
2112 // Now reverse the entries we just added. This will match the DFS
2113 // ordering performed by the worklist.
2114 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2115 std::reverse(I, E);
2116}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002117void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 AddDecl(B->getBlockDecl());
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 EnqueueChildren(E);
2125 AddTypeLoc(E->getTypeSourceInfo());
2126}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002127void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2128 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002129 E = S->body_rend(); I != E; ++I) {
2130 AddStmt(*I);
2131 }
2132}
2133void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002134VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 AddStmt(S->getSubStmt());
2136 AddDeclarationNameInfo(S);
2137 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2138 AddNestedNameSpecifierLoc(QualifierLoc);
2139}
2140
2141void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2144 AddDeclarationNameInfo(E);
2145 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2146 AddNestedNameSpecifierLoc(QualifierLoc);
2147 if (!E->isImplicitAccess())
2148 AddStmt(E->getBase());
2149}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002150void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002151 // Enqueue the initializer , if any.
2152 AddStmt(E->getInitializer());
2153 // Enqueue the array size, if any.
2154 AddStmt(E->getArraySize());
2155 // Enqueue the allocated type.
2156 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2157 // Enqueue the placement arguments.
2158 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2159 AddStmt(E->getPlacementArg(I-1));
2160}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002162 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2163 AddStmt(CE->getArg(I-1));
2164 AddStmt(CE->getCallee());
2165 AddStmt(CE->getArg(0));
2166}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002167void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2168 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 // Visit the name of the type being destroyed.
2170 AddTypeLoc(E->getDestroyedTypeInfo());
2171 // Visit the scope type that looks disturbingly like the nested-name-specifier
2172 // but isn't.
2173 AddTypeLoc(E->getScopeTypeInfo());
2174 // Visit the nested-name-specifier.
2175 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2176 AddNestedNameSpecifierLoc(QualifierLoc);
2177 // Visit base expression.
2178 AddStmt(E->getBase());
2179}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2181 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 AddTypeLoc(E->getTypeSourceInfo());
2183}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2185 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 EnqueueChildren(E);
2187 AddTypeLoc(E->getTypeSourceInfo());
2188}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 EnqueueChildren(E);
2191 if (E->isTypeOperand())
2192 AddTypeLoc(E->getTypeOperandSourceInfo());
2193}
2194
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2196 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 EnqueueChildren(E);
2198 AddTypeLoc(E->getTypeSourceInfo());
2199}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002200void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002201 EnqueueChildren(E);
2202 if (E->isTypeOperand())
2203 AddTypeLoc(E->getTypeOperandSourceInfo());
2204}
2205
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 EnqueueChildren(S);
2208 AddDecl(S->getExceptionDecl());
2209}
2210
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002211void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002212 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002213 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002214 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002215}
2216
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 if (DR->hasExplicitTemplateArgs()) {
2219 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2220 }
2221 WL.push_back(DeclRefExprParts(DR, Parent));
2222}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002223void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2224 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2226 AddDeclarationNameInfo(E);
2227 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 unsigned size = WL.size();
2231 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002232 for (const auto *D : S->decls()) {
2233 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002234 isFirst = false;
2235 }
2236 if (size == WL.size())
2237 return;
2238 // Now reverse the entries we just added. This will match the DFS
2239 // ordering performed by the worklist.
2240 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2241 std::reverse(I, E);
2242}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002243void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002244 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002246 D = E->designators_rbegin(), DEnd = E->designators_rend();
2247 D != DEnd; ++D) {
2248 if (D->isFieldDesignator()) {
2249 if (FieldDecl *Field = D->getField())
2250 AddMemberRef(Field, D->getFieldLoc());
2251 continue;
2252 }
2253 if (D->isArrayDesignator()) {
2254 AddStmt(E->getArrayIndex(*D));
2255 continue;
2256 }
2257 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2258 AddStmt(E->getArrayRangeEnd(*D));
2259 AddStmt(E->getArrayRangeStart(*D));
2260 }
2261}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 EnqueueChildren(E);
2264 AddTypeLoc(E->getTypeInfoAsWritten());
2265}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002266void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002267 AddStmt(FS->getBody());
2268 AddStmt(FS->getInc());
2269 AddStmt(FS->getCond());
2270 AddDecl(FS->getConditionVariable());
2271 AddStmt(FS->getInit());
2272}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2275}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 AddStmt(If->getElse());
2278 AddStmt(If->getThen());
2279 AddStmt(If->getCond());
2280 AddDecl(If->getConditionVariable());
2281}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002283 // We care about the syntactic form of the initializer list, only.
2284 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2285 IE = Syntactic;
2286 EnqueueChildren(IE);
2287}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 WL.push_back(MemberExprParts(M, Parent));
2290
2291 // If the base of the member access expression is an implicit 'this', don't
2292 // visit it.
2293 // FIXME: If we ever want to show these implicit accesses, this will be
2294 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002295 if (M->isImplicitAccess())
2296 return;
2297
2298 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2299 // real field that that we are interested in.
2300 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2301 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2302 if (FD->isAnonymousStructOrUnion()) {
2303 AddStmt(SubME->getBase());
2304 return;
2305 }
2306 }
2307 }
2308
2309 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002310}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002311void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 AddTypeLoc(E->getEncodedTypeSourceInfo());
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 EnqueueChildren(M);
2316 AddTypeLoc(M->getClassReceiverTypeInfo());
2317}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002319 // Visit the components of the offsetof expression.
2320 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2321 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2322 const OffsetOfNode &Node = E->getComponent(I-1);
2323 switch (Node.getKind()) {
2324 case OffsetOfNode::Array:
2325 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2326 break;
2327 case OffsetOfNode::Field:
2328 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2329 break;
2330 case OffsetOfNode::Identifier:
2331 case OffsetOfNode::Base:
2332 continue;
2333 }
2334 }
2335 // Visit the type into which we're computing the offset.
2336 AddTypeLoc(E->getTypeSourceInfo());
2337}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002338void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002339 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2340 WL.push_back(OverloadExprParts(E, Parent));
2341}
2342void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002343 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002344 EnqueueChildren(E);
2345 if (E->isArgumentType())
2346 AddTypeLoc(E->getArgumentTypeInfo());
2347}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002348void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002349 EnqueueChildren(S);
2350}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002351void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002352 AddStmt(S->getBody());
2353 AddStmt(S->getCond());
2354 AddDecl(S->getConditionVariable());
2355}
2356
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002357void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002358 AddStmt(W->getBody());
2359 AddStmt(W->getCond());
2360 AddDecl(W->getConditionVariable());
2361}
2362
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002363void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002364 for (unsigned I = E->getNumArgs(); I > 0; --I)
2365 AddTypeLoc(E->getArg(I-1));
2366}
2367
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002369 AddTypeLoc(E->getQueriedTypeSourceInfo());
2370}
2371
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002372void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 EnqueueChildren(E);
2374}
2375
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002376void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 VisitOverloadExpr(U);
2378 if (!U->isImplicitAccess())
2379 AddStmt(U->getBase());
2380}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002381void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002382 AddStmt(E->getSubExpr());
2383 AddTypeLoc(E->getWrittenTypeInfo());
2384}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002385void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002386 WL.push_back(SizeOfPackExprParts(E, Parent));
2387}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002388void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002389 // If the opaque value has a source expression, just transparently
2390 // visit that. This is useful for (e.g.) pseudo-object expressions.
2391 if (Expr *SourceExpr = E->getSourceExpr())
2392 return Visit(SourceExpr);
2393}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 AddStmt(E->getBody());
2396 WL.push_back(LambdaExprParts(E, Parent));
2397}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002398void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002399 // Treat the expression like its syntactic form.
2400 Visit(E->getSyntacticForm());
2401}
2402
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002403void EnqueueVisitor::VisitOMPExecutableDirective(
2404 const OMPExecutableDirective *D) {
2405 EnqueueChildren(D);
2406 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2407 E = D->clauses().end();
2408 I != E; ++I)
2409 EnqueueChildren(*I);
2410}
2411
Alexander Musman3aaab662014-08-19 11:27:13 +00002412void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2413 VisitOMPExecutableDirective(D);
2414}
2415
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002416void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2417 VisitOMPExecutableDirective(D);
2418}
2419
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002420void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002421 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002422}
2423
Alexey Bataevf29276e2014-06-18 04:14:57 +00002424void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002425 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002426}
2427
Alexander Musmanf82886e2014-09-18 05:12:34 +00002428void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2429 VisitOMPLoopDirective(D);
2430}
2431
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002432void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2433 VisitOMPExecutableDirective(D);
2434}
2435
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002436void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2437 VisitOMPExecutableDirective(D);
2438}
2439
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002440void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2441 VisitOMPExecutableDirective(D);
2442}
2443
Alexander Musman80c22892014-07-17 08:54:58 +00002444void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2445 VisitOMPExecutableDirective(D);
2446}
2447
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002448void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2449 VisitOMPExecutableDirective(D);
2450 AddDeclarationNameInfo(D);
2451}
2452
Alexey Bataev4acb8592014-07-07 13:01:15 +00002453void
2454EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002455 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002456}
2457
Alexander Musmane4e893b2014-09-23 09:33:00 +00002458void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2459 const OMPParallelForSimdDirective *D) {
2460 VisitOMPLoopDirective(D);
2461}
2462
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002463void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2464 const OMPParallelSectionsDirective *D) {
2465 VisitOMPExecutableDirective(D);
2466}
2467
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002468void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2469 VisitOMPExecutableDirective(D);
2470}
2471
Alexey Bataev68446b72014-07-18 07:47:19 +00002472void
2473EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2474 VisitOMPExecutableDirective(D);
2475}
2476
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002477void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2478 VisitOMPExecutableDirective(D);
2479}
2480
Alexey Bataev2df347a2014-07-18 10:17:07 +00002481void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2482 VisitOMPExecutableDirective(D);
2483}
2484
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002485void EnqueueVisitor::VisitOMPTaskgroupDirective(
2486 const OMPTaskgroupDirective *D) {
2487 VisitOMPExecutableDirective(D);
2488}
2489
Alexey Bataev6125da92014-07-21 11:26:11 +00002490void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2491 VisitOMPExecutableDirective(D);
2492}
2493
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002494void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2495 VisitOMPExecutableDirective(D);
2496}
2497
Alexey Bataev0162e452014-07-22 10:10:35 +00002498void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2499 VisitOMPExecutableDirective(D);
2500}
2501
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002502void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2503 VisitOMPExecutableDirective(D);
2504}
2505
Alexey Bataev13314bf2014-10-09 04:18:56 +00002506void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2507 VisitOMPExecutableDirective(D);
2508}
2509
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002510void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002511 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2512}
2513
2514bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2515 if (RegionOfInterest.isValid()) {
2516 SourceRange Range = getRawCursorExtent(C);
2517 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2518 return false;
2519 }
2520 return true;
2521}
2522
2523bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2524 while (!WL.empty()) {
2525 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002526 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002527
2528 // Set the Parent field, then back to its old value once we're done.
2529 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2530
2531 switch (LI.getKind()) {
2532 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002533 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002534 if (!D)
2535 continue;
2536
2537 // For now, perform default visitation for Decls.
2538 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2539 cast<DeclVisit>(&LI)->isFirst())))
2540 return true;
2541
2542 continue;
2543 }
2544 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2545 const ASTTemplateArgumentListInfo *ArgList =
2546 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2547 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2548 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2549 Arg != ArgEnd; ++Arg) {
2550 if (VisitTemplateArgumentLoc(*Arg))
2551 return true;
2552 }
2553 continue;
2554 }
2555 case VisitorJob::TypeLocVisitKind: {
2556 // Perform default visitation for TypeLocs.
2557 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2558 return true;
2559 continue;
2560 }
2561 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002562 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002563 if (LabelStmt *stmt = LS->getStmt()) {
2564 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2565 TU))) {
2566 return true;
2567 }
2568 }
2569 continue;
2570 }
2571
2572 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2573 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2574 if (VisitNestedNameSpecifierLoc(V->get()))
2575 return true;
2576 continue;
2577 }
2578
2579 case VisitorJob::DeclarationNameInfoVisitKind: {
2580 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2581 ->get()))
2582 return true;
2583 continue;
2584 }
2585 case VisitorJob::MemberRefVisitKind: {
2586 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2587 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2588 return true;
2589 continue;
2590 }
2591 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002592 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002593 if (!S)
2594 continue;
2595
2596 // Update the current cursor.
2597 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2598 if (!IsInRegionOfInterest(Cursor))
2599 continue;
2600 switch (Visitor(Cursor, Parent, ClientData)) {
2601 case CXChildVisit_Break: return true;
2602 case CXChildVisit_Continue: break;
2603 case CXChildVisit_Recurse:
2604 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002605 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002606 EnqueueWorkList(WL, S);
2607 break;
2608 }
2609 continue;
2610 }
2611 case VisitorJob::MemberExprPartsKind: {
2612 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002613 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002614
2615 // Visit the nested-name-specifier
2616 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2617 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2618 return true;
2619
2620 // Visit the declaration name.
2621 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2622 return true;
2623
2624 // Visit the explicitly-specified template arguments, if any.
2625 if (M->hasExplicitTemplateArgs()) {
2626 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2627 *ArgEnd = Arg + M->getNumTemplateArgs();
2628 Arg != ArgEnd; ++Arg) {
2629 if (VisitTemplateArgumentLoc(*Arg))
2630 return true;
2631 }
2632 }
2633 continue;
2634 }
2635 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002636 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002637 // Visit nested-name-specifier, if present.
2638 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2639 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2640 return true;
2641 // Visit declaration name.
2642 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2643 return true;
2644 continue;
2645 }
2646 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002647 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002648 // Visit the nested-name-specifier.
2649 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2650 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2651 return true;
2652 // Visit the declaration name.
2653 if (VisitDeclarationNameInfo(O->getNameInfo()))
2654 return true;
2655 // Visit the overloaded declaration reference.
2656 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2657 return true;
2658 continue;
2659 }
2660 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002661 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002662 NamedDecl *Pack = E->getPack();
2663 if (isa<TemplateTypeParmDecl>(Pack)) {
2664 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2665 E->getPackLoc(), TU)))
2666 return true;
2667
2668 continue;
2669 }
2670
2671 if (isa<TemplateTemplateParmDecl>(Pack)) {
2672 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2673 E->getPackLoc(), TU)))
2674 return true;
2675
2676 continue;
2677 }
2678
2679 // Non-type template parameter packs and function parameter packs are
2680 // treated like DeclRefExpr cursors.
2681 continue;
2682 }
2683
2684 case VisitorJob::LambdaExprPartsKind: {
2685 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002686 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002687 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2688 CEnd = E->explicit_capture_end();
2689 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002690 // FIXME: Lambda init-captures.
2691 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002692 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002693
Guy Benyei11169dd2012-12-18 14:30:41 +00002694 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2695 C->getLocation(),
2696 TU)))
2697 return true;
2698 }
2699
2700 // Visit parameters and return type, if present.
2701 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2702 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2703 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2704 // Visit the whole type.
2705 if (Visit(TL))
2706 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002707 } else if (FunctionProtoTypeLoc Proto =
2708 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002709 if (E->hasExplicitParameters()) {
2710 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002711 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2712 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002713 return true;
2714 } else {
2715 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002716 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002717 return true;
2718 }
2719 }
2720 }
2721 break;
2722 }
2723
2724 case VisitorJob::PostChildrenVisitKind:
2725 if (PostChildrenVisitor(Parent, ClientData))
2726 return true;
2727 break;
2728 }
2729 }
2730 return false;
2731}
2732
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002733bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002734 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002735 if (!WorkListFreeList.empty()) {
2736 WL = WorkListFreeList.back();
2737 WL->clear();
2738 WorkListFreeList.pop_back();
2739 }
2740 else {
2741 WL = new VisitorWorkList();
2742 WorkListCache.push_back(WL);
2743 }
2744 EnqueueWorkList(*WL, S);
2745 bool result = RunVisitorWorkList(*WL);
2746 WorkListFreeList.push_back(WL);
2747 return result;
2748}
2749
2750namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002751typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002752RefNamePieces
2753buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2754 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2755 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002756 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2757 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2758 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2759
2760 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2761
2762 RefNamePieces Pieces;
2763
2764 if (WantQualifier && QLoc.isValid())
2765 Pieces.push_back(QLoc);
2766
2767 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2768 Pieces.push_back(NI.getLoc());
2769
2770 if (WantTemplateArgs && TemplateArgs)
2771 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2772 TemplateArgs->RAngleLoc));
2773
2774 if (Kind == DeclarationName::CXXOperatorName) {
2775 Pieces.push_back(SourceLocation::getFromRawEncoding(
2776 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2777 Pieces.push_back(SourceLocation::getFromRawEncoding(
2778 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2779 }
2780
2781 if (WantSinglePiece) {
2782 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2783 Pieces.clear();
2784 Pieces.push_back(R);
2785 }
2786
2787 return Pieces;
2788}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002789}
Guy Benyei11169dd2012-12-18 14:30:41 +00002790
2791//===----------------------------------------------------------------------===//
2792// Misc. API hooks.
2793//===----------------------------------------------------------------------===//
2794
Chad Rosier05c71aa2013-03-27 18:28:23 +00002795static void fatal_error_handler(void *user_data, const std::string& reason,
2796 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002797 // Write the result out to stderr avoiding errs() because raw_ostreams can
2798 // call report_fatal_error.
2799 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2800 ::abort();
2801}
2802
Chandler Carruth66660742014-06-27 16:37:27 +00002803namespace {
2804struct RegisterFatalErrorHandler {
2805 RegisterFatalErrorHandler() {
2806 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2807 }
2808};
2809}
2810
2811static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2812
Guy Benyei11169dd2012-12-18 14:30:41 +00002813extern "C" {
2814CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2815 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002816 // We use crash recovery to make some of our APIs more reliable, implicitly
2817 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002818 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2819 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002820
Chandler Carruth66660742014-06-27 16:37:27 +00002821 // Look through the managed static to trigger construction of the managed
2822 // static which registers our fatal error handler. This ensures it is only
2823 // registered once.
2824 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002825
2826 CIndexer *CIdxr = new CIndexer();
2827 if (excludeDeclarationsFromPCH)
2828 CIdxr->setOnlyLocalDecls();
2829 if (displayDiagnostics)
2830 CIdxr->setDisplayDiagnostics();
2831
2832 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2833 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2834 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2835 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2836 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2837 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2838
2839 return CIdxr;
2840}
2841
2842void clang_disposeIndex(CXIndex CIdx) {
2843 if (CIdx)
2844 delete static_cast<CIndexer *>(CIdx);
2845}
2846
2847void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2848 if (CIdx)
2849 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2850}
2851
2852unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2853 if (CIdx)
2854 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2855 return 0;
2856}
2857
2858void clang_toggleCrashRecovery(unsigned isEnabled) {
2859 if (isEnabled)
2860 llvm::CrashRecoveryContext::Enable();
2861 else
2862 llvm::CrashRecoveryContext::Disable();
2863}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002864
Guy Benyei11169dd2012-12-18 14:30:41 +00002865CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2866 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002867 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002868 enum CXErrorCode Result =
2869 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002870 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002871 assert((TU && Result == CXError_Success) ||
2872 (!TU && Result != CXError_Success));
2873 return TU;
2874}
2875
2876enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2877 const char *ast_filename,
2878 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002879 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002880 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002881
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002882 if (!CIdx || !ast_filename || !out_TU)
2883 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002884
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002885 LOG_FUNC_SECTION {
2886 *Log << ast_filename;
2887 }
2888
Guy Benyei11169dd2012-12-18 14:30:41 +00002889 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2890 FileSystemOptions FileSystemOpts;
2891
Justin Bognerd512c1e2014-10-15 00:33:06 +00002892 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2893 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002894 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00002895 ast_filename, CXXIdx->getPCHContainerOperations(), Diags, FileSystemOpts,
2896 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002897 /*CaptureDiagnostics=*/true,
2898 /*AllowPCHWithCompilerErrors=*/true,
2899 /*UserFilesAreVolatile=*/true);
2900 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002901 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002902}
2903
2904unsigned clang_defaultEditingTranslationUnitOptions() {
2905 return CXTranslationUnit_PrecompiledPreamble |
2906 CXTranslationUnit_CacheCompletionResults;
2907}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002908
Guy Benyei11169dd2012-12-18 14:30:41 +00002909CXTranslationUnit
2910clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2911 const char *source_filename,
2912 int num_command_line_args,
2913 const char * const *command_line_args,
2914 unsigned num_unsaved_files,
2915 struct CXUnsavedFile *unsaved_files) {
2916 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2917 return clang_parseTranslationUnit(CIdx, source_filename,
2918 command_line_args, num_command_line_args,
2919 unsaved_files, num_unsaved_files,
2920 Options);
2921}
2922
2923struct ParseTranslationUnitInfo {
2924 CXIndex CIdx;
2925 const char *source_filename;
2926 const char *const *command_line_args;
2927 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002928 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002929 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002930 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002931 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002932};
2933static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002934 const ParseTranslationUnitInfo *PTUI =
2935 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002936 CXIndex CIdx = PTUI->CIdx;
2937 const char *source_filename = PTUI->source_filename;
2938 const char * const *command_line_args = PTUI->command_line_args;
2939 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002940 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002941 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002942
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002943 // Set up the initial return values.
2944 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002945 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002946
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002947 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002948 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002949 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002950 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002951 }
2952
Guy Benyei11169dd2012-12-18 14:30:41 +00002953 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2954
2955 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2956 setThreadBackgroundPriority();
2957
2958 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2959 // FIXME: Add a flag for modules.
2960 TranslationUnitKind TUKind
2961 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002962 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002963 = options & CXTranslationUnit_CacheCompletionResults;
2964 bool IncludeBriefCommentsInCodeCompletion
2965 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2966 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2967 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2968
2969 // Configure the diagnostics.
2970 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002971 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002972
2973 // Recover resources if we crash before exiting this function.
2974 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2975 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002976 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002977
Ahmed Charlesb8984322014-03-07 20:03:18 +00002978 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2979 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002980
2981 // Recover resources if we crash before exiting this function.
2982 llvm::CrashRecoveryContextCleanupRegistrar<
2983 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2984
Alp Toker9d85b182014-07-07 01:23:14 +00002985 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002986 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002987 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002988 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002989 }
2990
Ahmed Charlesb8984322014-03-07 20:03:18 +00002991 std::unique_ptr<std::vector<const char *>> Args(
2992 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002993
2994 // Recover resources if we crash before exiting this method.
2995 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2996 ArgsCleanup(Args.get());
2997
2998 // Since the Clang C library is primarily used by batch tools dealing with
2999 // (often very broken) source code, where spell-checking can have a
3000 // significant negative impact on performance (particularly when
3001 // precompiled headers are involved), we disable it by default.
3002 // Only do this if we haven't found a spell-checking-related argument.
3003 bool FoundSpellCheckingArgument = false;
3004 for (int I = 0; I != num_command_line_args; ++I) {
3005 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3006 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3007 FoundSpellCheckingArgument = true;
3008 break;
3009 }
3010 }
3011 if (!FoundSpellCheckingArgument)
3012 Args->push_back("-fno-spell-checking");
3013
3014 Args->insert(Args->end(), command_line_args,
3015 command_line_args + num_command_line_args);
3016
3017 // The 'source_filename' argument is optional. If the caller does not
3018 // specify it then it is assumed that the source file is specified
3019 // in the actual argument list.
3020 // Put the source file after command_line_args otherwise if '-x' flag is
3021 // present it will be unused.
3022 if (source_filename)
3023 Args->push_back(source_filename);
3024
3025 // Do we need the detailed preprocessing record?
3026 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3027 Args->push_back("-Xclang");
3028 Args->push_back("-detailed-preprocessing-record");
3029 }
3030
3031 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003032 std::unique_ptr<ASTUnit> ErrUnit;
3033 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003034 Args->data(), Args->data() + Args->size(),
3035 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003036 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3037 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3038 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3039 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3040 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3041 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003042
3043 if (NumErrors != Diags->getClient()->getNumErrors()) {
3044 // Make sure to check that 'Unit' is non-NULL.
3045 if (CXXIdx->getDisplayDiagnostics())
3046 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3047 }
3048
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003049 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3050 PTUI->result = CXError_ASTReadError;
3051 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003052 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003053 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3054 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003055}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003056
3057CXTranslationUnit
3058clang_parseTranslationUnit(CXIndex CIdx,
3059 const char *source_filename,
3060 const char *const *command_line_args,
3061 int num_command_line_args,
3062 struct CXUnsavedFile *unsaved_files,
3063 unsigned num_unsaved_files,
3064 unsigned options) {
3065 CXTranslationUnit TU;
3066 enum CXErrorCode Result = clang_parseTranslationUnit2(
3067 CIdx, source_filename, command_line_args, num_command_line_args,
3068 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003069 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003070 assert((TU && Result == CXError_Success) ||
3071 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003072 return TU;
3073}
3074
3075enum CXErrorCode clang_parseTranslationUnit2(
3076 CXIndex CIdx,
3077 const char *source_filename,
3078 const char *const *command_line_args,
3079 int num_command_line_args,
3080 struct CXUnsavedFile *unsaved_files,
3081 unsigned num_unsaved_files,
3082 unsigned options,
3083 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003084 LOG_FUNC_SECTION {
3085 *Log << source_filename << ": ";
3086 for (int i = 0; i != num_command_line_args; ++i)
3087 *Log << command_line_args[i] << " ";
3088 }
3089
Alp Toker9d85b182014-07-07 01:23:14 +00003090 if (num_unsaved_files && !unsaved_files)
3091 return CXError_InvalidArguments;
3092
Alp Toker5c532982014-07-07 22:42:03 +00003093 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003094 ParseTranslationUnitInfo PTUI = {
3095 CIdx,
3096 source_filename,
3097 command_line_args,
3098 num_command_line_args,
3099 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3100 options,
3101 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003102 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 llvm::CrashRecoveryContext CRC;
3104
3105 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3106 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3107 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3108 fprintf(stderr, " 'command_line_args' : [");
3109 for (int i = 0; i != num_command_line_args; ++i) {
3110 if (i)
3111 fprintf(stderr, ", ");
3112 fprintf(stderr, "'%s'", command_line_args[i]);
3113 }
3114 fprintf(stderr, "],\n");
3115 fprintf(stderr, " 'unsaved_files' : [");
3116 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3117 if (i)
3118 fprintf(stderr, ", ");
3119 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3120 unsaved_files[i].Length);
3121 }
3122 fprintf(stderr, "],\n");
3123 fprintf(stderr, " 'options' : %d,\n", options);
3124 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003125
3126 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003127 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003128 if (CXTranslationUnit *TU = PTUI.out_TU)
3129 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 }
Alp Toker5c532982014-07-07 22:42:03 +00003131
3132 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003133}
3134
3135unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3136 return CXSaveTranslationUnit_None;
3137}
3138
3139namespace {
3140
3141struct SaveTranslationUnitInfo {
3142 CXTranslationUnit TU;
3143 const char *FileName;
3144 unsigned options;
3145 CXSaveError result;
3146};
3147
3148}
3149
3150static void clang_saveTranslationUnit_Impl(void *UserData) {
3151 SaveTranslationUnitInfo *STUI =
3152 static_cast<SaveTranslationUnitInfo*>(UserData);
3153
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003154 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003155 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3156 setThreadBackgroundPriority();
3157
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003158 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3160}
3161
3162int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3163 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003164 LOG_FUNC_SECTION {
3165 *Log << TU << ' ' << FileName;
3166 }
3167
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003168 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003169 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003170 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003171 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003172
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003173 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003174 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3175 if (!CXXUnit->hasSema())
3176 return CXSaveError_InvalidTU;
3177
3178 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3179
3180 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3181 getenv("LIBCLANG_NOTHREADS")) {
3182 clang_saveTranslationUnit_Impl(&STUI);
3183
3184 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3185 PrintLibclangResourceUsage(TU);
3186
3187 return STUI.result;
3188 }
3189
3190 // We have an AST that has invalid nodes due to compiler errors.
3191 // Use a crash recovery thread for protection.
3192
3193 llvm::CrashRecoveryContext CRC;
3194
3195 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3196 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3197 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3198 fprintf(stderr, " 'options' : %d,\n", options);
3199 fprintf(stderr, "}\n");
3200
3201 return CXSaveError_Unknown;
3202
3203 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3204 PrintLibclangResourceUsage(TU);
3205 }
3206
3207 return STUI.result;
3208}
3209
3210void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3211 if (CTUnit) {
3212 // If the translation unit has been marked as unsafe to free, just discard
3213 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003214 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3215 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 return;
3217
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003218 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003219 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3221 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003222 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 delete CTUnit;
3224 }
3225}
3226
3227unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3228 return CXReparse_None;
3229}
3230
3231struct ReparseTranslationUnitInfo {
3232 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003233 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003235 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003236};
3237
3238static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003239 const ReparseTranslationUnitInfo *RTUI =
3240 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003242 unsigned options = RTUI->options;
3243 (void) options;
3244
3245 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003246 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003247 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003248 RTUI->result = CXError_InvalidArguments;
3249 return;
3250 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003251
3252 // Reset the associated diagnostics.
3253 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003254 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003255
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003256 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003257 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3258 setThreadBackgroundPriority();
3259
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003260 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003262
3263 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3264 new std::vector<ASTUnit::RemappedFile>());
3265
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 // Recover resources if we crash before exiting this function.
3267 llvm::CrashRecoveryContextCleanupRegistrar<
3268 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003269
3270 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003271 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003272 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003273 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003274 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003275
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003276 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3277 *RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003278 RTUI->result = CXError_Success;
3279 else if (isASTReadError(CXXUnit))
3280 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003281}
3282
3283int clang_reparseTranslationUnit(CXTranslationUnit TU,
3284 unsigned num_unsaved_files,
3285 struct CXUnsavedFile *unsaved_files,
3286 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003287 LOG_FUNC_SECTION {
3288 *Log << TU;
3289 }
3290
Alp Toker9d85b182014-07-07 01:23:14 +00003291 if (num_unsaved_files && !unsaved_files)
3292 return CXError_InvalidArguments;
3293
Alp Toker5c532982014-07-07 22:42:03 +00003294 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003295 ReparseTranslationUnitInfo RTUI = {
3296 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003297 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003298
3299 if (getenv("LIBCLANG_NOTHREADS")) {
3300 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003301 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 }
3303
3304 llvm::CrashRecoveryContext CRC;
3305
3306 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3307 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003308 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003309 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3311 PrintLibclangResourceUsage(TU);
3312
Alp Toker5c532982014-07-07 22:42:03 +00003313 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003314}
3315
3316
3317CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003318 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003319 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003320 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003321 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003322
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003323 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003324 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003325}
3326
3327CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003328 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003329 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003330 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003331 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003332
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003333 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3335}
3336
3337} // end: extern "C"
3338
3339//===----------------------------------------------------------------------===//
3340// CXFile Operations.
3341//===----------------------------------------------------------------------===//
3342
3343extern "C" {
3344CXString clang_getFileName(CXFile SFile) {
3345 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003346 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003347
3348 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003349 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003350}
3351
3352time_t clang_getFileTime(CXFile SFile) {
3353 if (!SFile)
3354 return 0;
3355
3356 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3357 return FEnt->getModificationTime();
3358}
3359
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003360CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003361 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003362 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003363 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003364 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003365
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003366 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003367
3368 FileManager &FMgr = CXXUnit->getFileManager();
3369 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3370}
3371
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003372unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3373 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003374 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003375 LOG_BAD_TU(TU);
3376 return 0;
3377 }
3378
3379 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 return 0;
3381
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003382 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 FileEntry *FEnt = static_cast<FileEntry *>(file);
3384 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3385 .isFileMultipleIncludeGuarded(FEnt);
3386}
3387
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003388int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3389 if (!file || !outID)
3390 return 1;
3391
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003392 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003393 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3394 outID->data[0] = ID.getDevice();
3395 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003396 outID->data[2] = FEnt->getModificationTime();
3397 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003398}
3399
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003400int clang_File_isEqual(CXFile file1, CXFile file2) {
3401 if (file1 == file2)
3402 return true;
3403
3404 if (!file1 || !file2)
3405 return false;
3406
3407 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3408 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3409 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3410}
3411
Guy Benyei11169dd2012-12-18 14:30:41 +00003412} // end: extern "C"
3413
3414//===----------------------------------------------------------------------===//
3415// CXCursor Operations.
3416//===----------------------------------------------------------------------===//
3417
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003418static const Decl *getDeclFromExpr(const Stmt *E) {
3419 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 return getDeclFromExpr(CE->getSubExpr());
3421
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003422 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003424 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003426 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003428 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 if (PRE->isExplicitProperty())
3430 return PRE->getExplicitProperty();
3431 // It could be messaging both getter and setter as in:
3432 // ++myobj.myprop;
3433 // in which case prefer to associate the setter since it is less obvious
3434 // from inspecting the source that the setter is going to get called.
3435 if (PRE->isMessagingSetter())
3436 return PRE->getImplicitPropertySetter();
3437 return PRE->getImplicitPropertyGetter();
3438 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003439 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003441 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 if (Expr *Src = OVE->getSourceExpr())
3443 return getDeclFromExpr(Src);
3444
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003445 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003447 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 if (!CE->isElidable())
3449 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003450 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003451 return OME->getMethodDecl();
3452
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003453 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003455 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3457 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003458 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3460 isa<ParmVarDecl>(SizeOfPack->getPack()))
3461 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003462
3463 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003464}
3465
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003466static SourceLocation getLocationFromExpr(const Expr *E) {
3467 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 return getLocationFromExpr(CE->getSubExpr());
3469
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003470 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003472 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003474 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003476 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003477 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003478 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003480 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 return PropRef->getLocation();
3482
3483 return E->getLocStart();
3484}
3485
3486extern "C" {
3487
3488unsigned clang_visitChildren(CXCursor parent,
3489 CXCursorVisitor visitor,
3490 CXClientData client_data) {
3491 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3492 /*VisitPreprocessorLast=*/false);
3493 return CursorVis.VisitChildren(parent);
3494}
3495
3496#ifndef __has_feature
3497#define __has_feature(x) 0
3498#endif
3499#if __has_feature(blocks)
3500typedef enum CXChildVisitResult
3501 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3502
3503static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3504 CXClientData client_data) {
3505 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3506 return block(cursor, parent);
3507}
3508#else
3509// If we are compiled with a compiler that doesn't have native blocks support,
3510// define and call the block manually, so the
3511typedef struct _CXChildVisitResult
3512{
3513 void *isa;
3514 int flags;
3515 int reserved;
3516 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3517 CXCursor);
3518} *CXCursorVisitorBlock;
3519
3520static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3521 CXClientData client_data) {
3522 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3523 return block->invoke(block, cursor, parent);
3524}
3525#endif
3526
3527
3528unsigned clang_visitChildrenWithBlock(CXCursor parent,
3529 CXCursorVisitorBlock block) {
3530 return clang_visitChildren(parent, visitWithBlock, block);
3531}
3532
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003533static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003535 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003536
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003537 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003539 if (const ObjCPropertyImplDecl *PropImpl =
3540 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003542 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003543
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003544 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003546 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003547
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003548 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 }
3550
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003551 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003552 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003553
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003554 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3556 // and returns different names. NamedDecl returns the class name and
3557 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003558 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003559
3560 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003561 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003562
3563 SmallString<1024> S;
3564 llvm::raw_svector_ostream os(S);
3565 ND->printName(os);
3566
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003567 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003568}
3569
3570CXString clang_getCursorSpelling(CXCursor C) {
3571 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003572 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003573
3574 if (clang_isReference(C.kind)) {
3575 switch (C.kind) {
3576 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003577 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003578 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 }
3580 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003581 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003582 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 }
3584 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003585 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003587 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 }
3589 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003590 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003591 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 }
3593 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003594 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 assert(Type && "Missing type decl");
3596
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003597 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 getAsString());
3599 }
3600 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003601 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 assert(Template && "Missing template decl");
3603
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003604 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 }
3606
3607 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003608 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 assert(NS && "Missing namespace decl");
3610
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003611 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 }
3613
3614 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003615 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 assert(Field && "Missing member decl");
3617
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003618 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 }
3620
3621 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003622 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 assert(Label && "Missing label");
3624
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 }
3627
3628 case CXCursor_OverloadedDeclRef: {
3629 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003630 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3631 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003632 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003633 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003635 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003636 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 OverloadedTemplateStorage *Ovl
3638 = Storage.get<OverloadedTemplateStorage*>();
3639 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003640 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003641 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 }
3643
3644 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003645 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 assert(Var && "Missing variable decl");
3647
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003648 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 }
3650
3651 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 }
3654 }
3655
3656 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003657 const Expr *E = getCursorExpr(C);
3658
3659 if (C.kind == CXCursor_ObjCStringLiteral ||
3660 C.kind == CXCursor_StringLiteral) {
3661 const StringLiteral *SLit;
3662 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3663 SLit = OSL->getString();
3664 } else {
3665 SLit = cast<StringLiteral>(E);
3666 }
3667 SmallString<256> Buf;
3668 llvm::raw_svector_ostream OS(Buf);
3669 SLit->outputString(OS);
3670 return cxstring::createDup(OS.str());
3671 }
3672
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003673 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 if (D)
3675 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003676 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 }
3678
3679 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003680 const Stmt *S = getCursorStmt(C);
3681 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003683
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003684 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 }
3686
3687 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 ->getNameStart());
3690
3691 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 ->getNameStart());
3694
3695 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003696 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003697
3698 if (clang_isDeclaration(C.kind))
3699 return getDeclSpelling(getCursorDecl(C));
3700
3701 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003702 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003703 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 }
3705
3706 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003707 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003708 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 }
3710
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003711 if (C.kind == CXCursor_PackedAttr) {
3712 return cxstring::createRef("packed");
3713 }
3714
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003715 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003716}
3717
3718CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3719 unsigned pieceIndex,
3720 unsigned options) {
3721 if (clang_Cursor_isNull(C))
3722 return clang_getNullRange();
3723
3724 ASTContext &Ctx = getCursorContext(C);
3725
3726 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003727 const Stmt *S = getCursorStmt(C);
3728 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 if (pieceIndex > 0)
3730 return clang_getNullRange();
3731 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3732 }
3733
3734 return clang_getNullRange();
3735 }
3736
3737 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003738 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3740 if (pieceIndex >= ME->getNumSelectorLocs())
3741 return clang_getNullRange();
3742 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3743 }
3744 }
3745
3746 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3747 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003748 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3750 if (pieceIndex >= MD->getNumSelectorLocs())
3751 return clang_getNullRange();
3752 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3753 }
3754 }
3755
3756 if (C.kind == CXCursor_ObjCCategoryDecl ||
3757 C.kind == CXCursor_ObjCCategoryImplDecl) {
3758 if (pieceIndex > 0)
3759 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003760 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3762 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003763 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3765 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3766 }
3767
3768 if (C.kind == CXCursor_ModuleImportDecl) {
3769 if (pieceIndex > 0)
3770 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003771 if (const ImportDecl *ImportD =
3772 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3774 if (!Locs.empty())
3775 return cxloc::translateSourceRange(Ctx,
3776 SourceRange(Locs.front(), Locs.back()));
3777 }
3778 return clang_getNullRange();
3779 }
3780
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003781 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3782 C.kind == CXCursor_ConversionFunction) {
3783 if (pieceIndex > 0)
3784 return clang_getNullRange();
3785 if (const FunctionDecl *FD =
3786 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3787 DeclarationNameInfo FunctionName = FD->getNameInfo();
3788 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3789 }
3790 return clang_getNullRange();
3791 }
3792
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 // FIXME: A CXCursor_InclusionDirective should give the location of the
3794 // filename, but we don't keep track of this.
3795
3796 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3797 // but we don't keep track of this.
3798
3799 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3800 // but we don't keep track of this.
3801
3802 // Default handling, give the location of the cursor.
3803
3804 if (pieceIndex > 0)
3805 return clang_getNullRange();
3806
3807 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3808 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3809 return cxloc::translateSourceRange(Ctx, Loc);
3810}
3811
Eli Bendersky44a206f2014-07-31 18:04:56 +00003812CXString clang_Cursor_getMangling(CXCursor C) {
3813 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3814 return cxstring::createEmpty();
3815
Eli Bendersky44a206f2014-07-31 18:04:56 +00003816 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003817 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003818 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3819 return cxstring::createEmpty();
3820
Eli Bendersky79759592014-08-01 15:01:10 +00003821 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003822 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003823 ASTContext &Ctx = ND->getASTContext();
3824 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003825
Eli Bendersky79759592014-08-01 15:01:10 +00003826 std::string FrontendBuf;
3827 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3828 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003829
Eli Bendersky79759592014-08-01 15:01:10 +00003830 // Now apply backend mangling.
3831 std::unique_ptr<llvm::DataLayout> DL(
3832 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
Eli Bendersky79759592014-08-01 15:01:10 +00003833
3834 std::string FinalBuf;
3835 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003836 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3837 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003838
3839 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003840}
3841
Guy Benyei11169dd2012-12-18 14:30:41 +00003842CXString clang_getCursorDisplayName(CXCursor C) {
3843 if (!clang_isDeclaration(C.kind))
3844 return clang_getCursorSpelling(C);
3845
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003846 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003848 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003849
3850 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003851 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 D = FunTmpl->getTemplatedDecl();
3853
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003854 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 SmallString<64> Str;
3856 llvm::raw_svector_ostream OS(Str);
3857 OS << *Function;
3858 if (Function->getPrimaryTemplate())
3859 OS << "<>";
3860 OS << "(";
3861 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3862 if (I)
3863 OS << ", ";
3864 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3865 }
3866
3867 if (Function->isVariadic()) {
3868 if (Function->getNumParams())
3869 OS << ", ";
3870 OS << "...";
3871 }
3872 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003873 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 }
3875
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003876 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 SmallString<64> Str;
3878 llvm::raw_svector_ostream OS(Str);
3879 OS << *ClassTemplate;
3880 OS << "<";
3881 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3882 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3883 if (I)
3884 OS << ", ";
3885
3886 NamedDecl *Param = Params->getParam(I);
3887 if (Param->getIdentifier()) {
3888 OS << Param->getIdentifier()->getName();
3889 continue;
3890 }
3891
3892 // There is no parameter name, which makes this tricky. Try to come up
3893 // with something useful that isn't too long.
3894 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3895 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3896 else if (NonTypeTemplateParmDecl *NTTP
3897 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3898 OS << NTTP->getType().getAsString(Policy);
3899 else
3900 OS << "template<...> class";
3901 }
3902
3903 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003904 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 }
3906
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003907 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3909 // If the type was explicitly written, use that.
3910 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003911 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003912
Benjamin Kramer9170e912013-02-22 15:46:01 +00003913 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 llvm::raw_svector_ostream OS(Str);
3915 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003916 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 ClassSpec->getTemplateArgs().data(),
3918 ClassSpec->getTemplateArgs().size(),
3919 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003920 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 }
3922
3923 return clang_getCursorSpelling(C);
3924}
3925
3926CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3927 switch (Kind) {
3928 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004056 case CXCursor_ObjCSelfExpr:
4057 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004146 case CXCursor_SEHLeaveStmt:
4147 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004176 case CXCursor_PackedAttr:
4177 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004178 case CXCursor_PureAttr:
4179 return cxstring::createRef("attribute(pure)");
4180 case CXCursor_ConstAttr:
4181 return cxstring::createRef("attribute(const)");
4182 case CXCursor_NoDuplicateAttr:
4183 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004184 case CXCursor_CUDAConstantAttr:
4185 return cxstring::createRef("attribute(constant)");
4186 case CXCursor_CUDADeviceAttr:
4187 return cxstring::createRef("attribute(device)");
4188 case CXCursor_CUDAGlobalAttr:
4189 return cxstring::createRef("attribute(global)");
4190 case CXCursor_CUDAHostAttr:
4191 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004192 case CXCursor_CUDASharedAttr:
4193 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004231 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004233 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004235 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004237 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004239 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004241 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004242 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004243 return cxstring::createRef("OMPParallelDirective");
4244 case CXCursor_OMPSimdDirective:
4245 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004246 case CXCursor_OMPForDirective:
4247 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004248 case CXCursor_OMPForSimdDirective:
4249 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004250 case CXCursor_OMPSectionsDirective:
4251 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004252 case CXCursor_OMPSectionDirective:
4253 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004254 case CXCursor_OMPSingleDirective:
4255 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004256 case CXCursor_OMPMasterDirective:
4257 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004258 case CXCursor_OMPCriticalDirective:
4259 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004260 case CXCursor_OMPParallelForDirective:
4261 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004262 case CXCursor_OMPParallelForSimdDirective:
4263 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004264 case CXCursor_OMPParallelSectionsDirective:
4265 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004266 case CXCursor_OMPTaskDirective:
4267 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004268 case CXCursor_OMPTaskyieldDirective:
4269 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004270 case CXCursor_OMPBarrierDirective:
4271 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004272 case CXCursor_OMPTaskwaitDirective:
4273 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004274 case CXCursor_OMPTaskgroupDirective:
4275 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004276 case CXCursor_OMPFlushDirective:
4277 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004278 case CXCursor_OMPOrderedDirective:
4279 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004280 case CXCursor_OMPAtomicDirective:
4281 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004282 case CXCursor_OMPTargetDirective:
4283 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004284 case CXCursor_OMPTeamsDirective:
4285 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004286 case CXCursor_OverloadCandidate:
4287 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 }
4289
4290 llvm_unreachable("Unhandled CXCursorKind");
4291}
4292
4293struct GetCursorData {
4294 SourceLocation TokenBeginLoc;
4295 bool PointsAtMacroArgExpansion;
4296 bool VisitedObjCPropertyImplDecl;
4297 SourceLocation VisitedDeclaratorDeclStartLoc;
4298 CXCursor &BestCursor;
4299
4300 GetCursorData(SourceManager &SM,
4301 SourceLocation tokenBegin, CXCursor &outputCursor)
4302 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4303 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4304 VisitedObjCPropertyImplDecl = false;
4305 }
4306};
4307
4308static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4309 CXCursor parent,
4310 CXClientData client_data) {
4311 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4312 CXCursor *BestCursor = &Data->BestCursor;
4313
4314 // If we point inside a macro argument we should provide info of what the
4315 // token is so use the actual cursor, don't replace it with a macro expansion
4316 // cursor.
4317 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4318 return CXChildVisit_Recurse;
4319
4320 if (clang_isDeclaration(cursor.kind)) {
4321 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004322 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4324 if (MD->isImplicit())
4325 return CXChildVisit_Break;
4326
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004327 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4329 // Check that when we have multiple @class references in the same line,
4330 // that later ones do not override the previous ones.
4331 // If we have:
4332 // @class Foo, Bar;
4333 // source ranges for both start at '@', so 'Bar' will end up overriding
4334 // 'Foo' even though the cursor location was at 'Foo'.
4335 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4336 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004337 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4339 if (PrevID != ID &&
4340 !PrevID->isThisDeclarationADefinition() &&
4341 !ID->isThisDeclarationADefinition())
4342 return CXChildVisit_Break;
4343 }
4344
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004345 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004346 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4347 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4348 // Check that when we have multiple declarators in the same line,
4349 // that later ones do not override the previous ones.
4350 // If we have:
4351 // int Foo, Bar;
4352 // source ranges for both start at 'int', so 'Bar' will end up overriding
4353 // 'Foo' even though the cursor location was at 'Foo'.
4354 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4355 return CXChildVisit_Break;
4356 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4357
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004358 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004359 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4360 (void)PropImp;
4361 // Check that when we have multiple @synthesize in the same line,
4362 // that later ones do not override the previous ones.
4363 // If we have:
4364 // @synthesize Foo, Bar;
4365 // source ranges for both start at '@', so 'Bar' will end up overriding
4366 // 'Foo' even though the cursor location was at 'Foo'.
4367 if (Data->VisitedObjCPropertyImplDecl)
4368 return CXChildVisit_Break;
4369 Data->VisitedObjCPropertyImplDecl = true;
4370 }
4371 }
4372
4373 if (clang_isExpression(cursor.kind) &&
4374 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004375 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 // Avoid having the cursor of an expression replace the declaration cursor
4377 // when the expression source range overlaps the declaration range.
4378 // This can happen for C++ constructor expressions whose range generally
4379 // include the variable declaration, e.g.:
4380 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4381 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4382 D->getLocation() == Data->TokenBeginLoc)
4383 return CXChildVisit_Break;
4384 }
4385 }
4386
4387 // If our current best cursor is the construction of a temporary object,
4388 // don't replace that cursor with a type reference, because we want
4389 // clang_getCursor() to point at the constructor.
4390 if (clang_isExpression(BestCursor->kind) &&
4391 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4392 cursor.kind == CXCursor_TypeRef) {
4393 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4394 // as having the actual point on the type reference.
4395 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4396 return CXChildVisit_Recurse;
4397 }
4398
4399 *BestCursor = cursor;
4400 return CXChildVisit_Recurse;
4401}
4402
4403CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004404 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004405 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004407 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004408
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004409 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4411
4412 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4413 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4414
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004415 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 CXFile SearchFile;
4417 unsigned SearchLine, SearchColumn;
4418 CXFile ResultFile;
4419 unsigned ResultLine, ResultColumn;
4420 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4421 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4422 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004423
4424 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4425 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004426 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004427 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 SearchFileName = clang_getFileName(SearchFile);
4429 ResultFileName = clang_getFileName(ResultFile);
4430 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4431 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004432 *Log << llvm::format("(%s:%d:%d) = %s",
4433 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4434 clang_getCString(KindSpelling))
4435 << llvm::format("(%s:%d:%d):%s%s",
4436 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4437 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 clang_disposeString(SearchFileName);
4439 clang_disposeString(ResultFileName);
4440 clang_disposeString(KindSpelling);
4441 clang_disposeString(USR);
4442
4443 CXCursor Definition = clang_getCursorDefinition(Result);
4444 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4445 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4446 CXString DefinitionKindSpelling
4447 = clang_getCursorKindSpelling(Definition.kind);
4448 CXFile DefinitionFile;
4449 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004450 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004451 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004453 *Log << llvm::format(" -> %s(%s:%d:%d)",
4454 clang_getCString(DefinitionKindSpelling),
4455 clang_getCString(DefinitionFileName),
4456 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 clang_disposeString(DefinitionFileName);
4458 clang_disposeString(DefinitionKindSpelling);
4459 }
4460 }
4461
4462 return Result;
4463}
4464
4465CXCursor clang_getNullCursor(void) {
4466 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4467}
4468
4469unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004470 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4471 // can't set consistently. For example, when visiting a DeclStmt we will set
4472 // it but we don't set it on the result of clang_getCursorDefinition for
4473 // a reference of the same declaration.
4474 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4475 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4476 // to provide that kind of info.
4477 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004478 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004479 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004480 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004481
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 return X == Y;
4483}
4484
4485unsigned clang_hashCursor(CXCursor C) {
4486 unsigned Index = 0;
4487 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4488 Index = 1;
4489
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004490 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 std::make_pair(C.kind, C.data[Index]));
4492}
4493
4494unsigned clang_isInvalid(enum CXCursorKind K) {
4495 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4496}
4497
4498unsigned clang_isDeclaration(enum CXCursorKind K) {
4499 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4500 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4501}
4502
4503unsigned clang_isReference(enum CXCursorKind K) {
4504 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4505}
4506
4507unsigned clang_isExpression(enum CXCursorKind K) {
4508 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4509}
4510
4511unsigned clang_isStatement(enum CXCursorKind K) {
4512 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4513}
4514
4515unsigned clang_isAttribute(enum CXCursorKind K) {
4516 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4517}
4518
4519unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4520 return K == CXCursor_TranslationUnit;
4521}
4522
4523unsigned clang_isPreprocessing(enum CXCursorKind K) {
4524 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4525}
4526
4527unsigned clang_isUnexposed(enum CXCursorKind K) {
4528 switch (K) {
4529 case CXCursor_UnexposedDecl:
4530 case CXCursor_UnexposedExpr:
4531 case CXCursor_UnexposedStmt:
4532 case CXCursor_UnexposedAttr:
4533 return true;
4534 default:
4535 return false;
4536 }
4537}
4538
4539CXCursorKind clang_getCursorKind(CXCursor C) {
4540 return C.kind;
4541}
4542
4543CXSourceLocation clang_getCursorLocation(CXCursor C) {
4544 if (clang_isReference(C.kind)) {
4545 switch (C.kind) {
4546 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004547 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 = getCursorObjCSuperClassRef(C);
4549 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4550 }
4551
4552 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004553 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 = getCursorObjCProtocolRef(C);
4555 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4556 }
4557
4558 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004559 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 = getCursorObjCClassRef(C);
4561 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4562 }
4563
4564 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004565 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4567 }
4568
4569 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004570 std::pair<const TemplateDecl *, SourceLocation> P =
4571 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4573 }
4574
4575 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004576 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4578 }
4579
4580 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004581 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4583 }
4584
4585 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004586 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4588 }
4589
4590 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004591 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 if (!BaseSpec)
4593 return clang_getNullLocation();
4594
4595 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4596 return cxloc::translateSourceLocation(getCursorContext(C),
4597 TSInfo->getTypeLoc().getBeginLoc());
4598
4599 return cxloc::translateSourceLocation(getCursorContext(C),
4600 BaseSpec->getLocStart());
4601 }
4602
4603 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004604 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4606 }
4607
4608 case CXCursor_OverloadedDeclRef:
4609 return cxloc::translateSourceLocation(getCursorContext(C),
4610 getCursorOverloadedDeclRef(C).second);
4611
4612 default:
4613 // FIXME: Need a way to enumerate all non-reference cases.
4614 llvm_unreachable("Missed a reference kind");
4615 }
4616 }
4617
4618 if (clang_isExpression(C.kind))
4619 return cxloc::translateSourceLocation(getCursorContext(C),
4620 getLocationFromExpr(getCursorExpr(C)));
4621
4622 if (clang_isStatement(C.kind))
4623 return cxloc::translateSourceLocation(getCursorContext(C),
4624 getCursorStmt(C)->getLocStart());
4625
4626 if (C.kind == CXCursor_PreprocessingDirective) {
4627 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4628 return cxloc::translateSourceLocation(getCursorContext(C), L);
4629 }
4630
4631 if (C.kind == CXCursor_MacroExpansion) {
4632 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004633 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 return cxloc::translateSourceLocation(getCursorContext(C), L);
4635 }
4636
4637 if (C.kind == CXCursor_MacroDefinition) {
4638 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4639 return cxloc::translateSourceLocation(getCursorContext(C), L);
4640 }
4641
4642 if (C.kind == CXCursor_InclusionDirective) {
4643 SourceLocation L
4644 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4645 return cxloc::translateSourceLocation(getCursorContext(C), L);
4646 }
4647
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004648 if (clang_isAttribute(C.kind)) {
4649 SourceLocation L
4650 = cxcursor::getCursorAttr(C)->getLocation();
4651 return cxloc::translateSourceLocation(getCursorContext(C), L);
4652 }
4653
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 if (!clang_isDeclaration(C.kind))
4655 return clang_getNullLocation();
4656
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004657 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 if (!D)
4659 return clang_getNullLocation();
4660
4661 SourceLocation Loc = D->getLocation();
4662 // FIXME: Multiple variables declared in a single declaration
4663 // currently lack the information needed to correctly determine their
4664 // ranges when accounting for the type-specifier. We use context
4665 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4666 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004667 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 if (!cxcursor::isFirstInDeclGroup(C))
4669 Loc = VD->getLocation();
4670 }
4671
4672 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004673 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004674 Loc = MD->getSelectorStartLoc();
4675
4676 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4677}
4678
4679} // end extern "C"
4680
4681CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4682 assert(TU);
4683
4684 // Guard against an invalid SourceLocation, or we may assert in one
4685 // of the following calls.
4686 if (SLoc.isInvalid())
4687 return clang_getNullCursor();
4688
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004689 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004690
4691 // Translate the given source location to make it point at the beginning of
4692 // the token under the cursor.
4693 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4694 CXXUnit->getASTContext().getLangOpts());
4695
4696 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4697 if (SLoc.isValid()) {
4698 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4699 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4700 /*VisitPreprocessorLast=*/true,
4701 /*VisitIncludedEntities=*/false,
4702 SourceLocation(SLoc));
4703 CursorVis.visitFileRegion();
4704 }
4705
4706 return Result;
4707}
4708
4709static SourceRange getRawCursorExtent(CXCursor C) {
4710 if (clang_isReference(C.kind)) {
4711 switch (C.kind) {
4712 case CXCursor_ObjCSuperClassRef:
4713 return getCursorObjCSuperClassRef(C).second;
4714
4715 case CXCursor_ObjCProtocolRef:
4716 return getCursorObjCProtocolRef(C).second;
4717
4718 case CXCursor_ObjCClassRef:
4719 return getCursorObjCClassRef(C).second;
4720
4721 case CXCursor_TypeRef:
4722 return getCursorTypeRef(C).second;
4723
4724 case CXCursor_TemplateRef:
4725 return getCursorTemplateRef(C).second;
4726
4727 case CXCursor_NamespaceRef:
4728 return getCursorNamespaceRef(C).second;
4729
4730 case CXCursor_MemberRef:
4731 return getCursorMemberRef(C).second;
4732
4733 case CXCursor_CXXBaseSpecifier:
4734 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4735
4736 case CXCursor_LabelRef:
4737 return getCursorLabelRef(C).second;
4738
4739 case CXCursor_OverloadedDeclRef:
4740 return getCursorOverloadedDeclRef(C).second;
4741
4742 case CXCursor_VariableRef:
4743 return getCursorVariableRef(C).second;
4744
4745 default:
4746 // FIXME: Need a way to enumerate all non-reference cases.
4747 llvm_unreachable("Missed a reference kind");
4748 }
4749 }
4750
4751 if (clang_isExpression(C.kind))
4752 return getCursorExpr(C)->getSourceRange();
4753
4754 if (clang_isStatement(C.kind))
4755 return getCursorStmt(C)->getSourceRange();
4756
4757 if (clang_isAttribute(C.kind))
4758 return getCursorAttr(C)->getRange();
4759
4760 if (C.kind == CXCursor_PreprocessingDirective)
4761 return cxcursor::getCursorPreprocessingDirective(C);
4762
4763 if (C.kind == CXCursor_MacroExpansion) {
4764 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004765 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 return TU->mapRangeFromPreamble(Range);
4767 }
4768
4769 if (C.kind == CXCursor_MacroDefinition) {
4770 ASTUnit *TU = getCursorASTUnit(C);
4771 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4772 return TU->mapRangeFromPreamble(Range);
4773 }
4774
4775 if (C.kind == CXCursor_InclusionDirective) {
4776 ASTUnit *TU = getCursorASTUnit(C);
4777 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4778 return TU->mapRangeFromPreamble(Range);
4779 }
4780
4781 if (C.kind == CXCursor_TranslationUnit) {
4782 ASTUnit *TU = getCursorASTUnit(C);
4783 FileID MainID = TU->getSourceManager().getMainFileID();
4784 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4785 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4786 return SourceRange(Start, End);
4787 }
4788
4789 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004790 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 if (!D)
4792 return SourceRange();
4793
4794 SourceRange R = D->getSourceRange();
4795 // FIXME: Multiple variables declared in a single declaration
4796 // currently lack the information needed to correctly determine their
4797 // ranges when accounting for the type-specifier. We use context
4798 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4799 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004800 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 if (!cxcursor::isFirstInDeclGroup(C))
4802 R.setBegin(VD->getLocation());
4803 }
4804 return R;
4805 }
4806 return SourceRange();
4807}
4808
4809/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4810/// the decl-specifier-seq for declarations.
4811static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4812 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004813 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 if (!D)
4815 return SourceRange();
4816
4817 SourceRange R = D->getSourceRange();
4818
4819 // Adjust the start of the location for declarations preceded by
4820 // declaration specifiers.
4821 SourceLocation StartLoc;
4822 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4823 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4824 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004825 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004826 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4827 StartLoc = TI->getTypeLoc().getLocStart();
4828 }
4829
4830 if (StartLoc.isValid() && R.getBegin().isValid() &&
4831 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4832 R.setBegin(StartLoc);
4833
4834 // FIXME: Multiple variables declared in a single declaration
4835 // currently lack the information needed to correctly determine their
4836 // ranges when accounting for the type-specifier. We use context
4837 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4838 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004839 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004840 if (!cxcursor::isFirstInDeclGroup(C))
4841 R.setBegin(VD->getLocation());
4842 }
4843
4844 return R;
4845 }
4846
4847 return getRawCursorExtent(C);
4848}
4849
4850extern "C" {
4851
4852CXSourceRange clang_getCursorExtent(CXCursor C) {
4853 SourceRange R = getRawCursorExtent(C);
4854 if (R.isInvalid())
4855 return clang_getNullRange();
4856
4857 return cxloc::translateSourceRange(getCursorContext(C), R);
4858}
4859
4860CXCursor clang_getCursorReferenced(CXCursor C) {
4861 if (clang_isInvalid(C.kind))
4862 return clang_getNullCursor();
4863
4864 CXTranslationUnit tu = getCursorTU(C);
4865 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004866 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004867 if (!D)
4868 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004869 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004870 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004871 if (const ObjCPropertyImplDecl *PropImpl =
4872 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4874 return MakeCXCursor(Property, tu);
4875
4876 return C;
4877 }
4878
4879 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004880 const Expr *E = getCursorExpr(C);
4881 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004882 if (D) {
4883 CXCursor declCursor = MakeCXCursor(D, tu);
4884 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4885 declCursor);
4886 return declCursor;
4887 }
4888
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004889 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004890 return MakeCursorOverloadedDeclRef(Ovl, tu);
4891
4892 return clang_getNullCursor();
4893 }
4894
4895 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004896 const Stmt *S = getCursorStmt(C);
4897 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004898 if (LabelDecl *label = Goto->getLabel())
4899 if (LabelStmt *labelS = label->getStmt())
4900 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4901
4902 return clang_getNullCursor();
4903 }
Richard Smith66a81862015-05-04 02:25:31 +00004904
Guy Benyei11169dd2012-12-18 14:30:41 +00004905 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004906 if (const MacroDefinitionRecord *Def =
4907 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004908 return MakeMacroDefinitionCursor(Def, tu);
4909 }
4910
4911 if (!clang_isReference(C.kind))
4912 return clang_getNullCursor();
4913
4914 switch (C.kind) {
4915 case CXCursor_ObjCSuperClassRef:
4916 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4917
4918 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004919 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4920 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 return MakeCXCursor(Def, tu);
4922
4923 return MakeCXCursor(Prot, tu);
4924 }
4925
4926 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004927 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4928 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004929 return MakeCXCursor(Def, tu);
4930
4931 return MakeCXCursor(Class, tu);
4932 }
4933
4934 case CXCursor_TypeRef:
4935 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4936
4937 case CXCursor_TemplateRef:
4938 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4939
4940 case CXCursor_NamespaceRef:
4941 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4942
4943 case CXCursor_MemberRef:
4944 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4945
4946 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004947 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4949 tu ));
4950 }
4951
4952 case CXCursor_LabelRef:
4953 // FIXME: We end up faking the "parent" declaration here because we
4954 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004955 return MakeCXCursor(getCursorLabelRef(C).first,
4956 cxtu::getASTUnit(tu)->getASTContext()
4957 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004958 tu);
4959
4960 case CXCursor_OverloadedDeclRef:
4961 return C;
4962
4963 case CXCursor_VariableRef:
4964 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4965
4966 default:
4967 // We would prefer to enumerate all non-reference cursor kinds here.
4968 llvm_unreachable("Unhandled reference cursor kind");
4969 }
4970}
4971
4972CXCursor clang_getCursorDefinition(CXCursor C) {
4973 if (clang_isInvalid(C.kind))
4974 return clang_getNullCursor();
4975
4976 CXTranslationUnit TU = getCursorTU(C);
4977
4978 bool WasReference = false;
4979 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4980 C = clang_getCursorReferenced(C);
4981 WasReference = true;
4982 }
4983
4984 if (C.kind == CXCursor_MacroExpansion)
4985 return clang_getCursorReferenced(C);
4986
4987 if (!clang_isDeclaration(C.kind))
4988 return clang_getNullCursor();
4989
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004990 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 if (!D)
4992 return clang_getNullCursor();
4993
4994 switch (D->getKind()) {
4995 // Declaration kinds that don't really separate the notions of
4996 // declaration and definition.
4997 case Decl::Namespace:
4998 case Decl::Typedef:
4999 case Decl::TypeAlias:
5000 case Decl::TypeAliasTemplate:
5001 case Decl::TemplateTypeParm:
5002 case Decl::EnumConstant:
5003 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005004 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 case Decl::IndirectField:
5006 case Decl::ObjCIvar:
5007 case Decl::ObjCAtDefsField:
5008 case Decl::ImplicitParam:
5009 case Decl::ParmVar:
5010 case Decl::NonTypeTemplateParm:
5011 case Decl::TemplateTemplateParm:
5012 case Decl::ObjCCategoryImpl:
5013 case Decl::ObjCImplementation:
5014 case Decl::AccessSpec:
5015 case Decl::LinkageSpec:
5016 case Decl::ObjCPropertyImpl:
5017 case Decl::FileScopeAsm:
5018 case Decl::StaticAssert:
5019 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005020 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005021 case Decl::Label: // FIXME: Is this right??
5022 case Decl::ClassScopeFunctionSpecialization:
5023 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005024 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005025 return C;
5026
5027 // Declaration kinds that don't make any sense here, but are
5028 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005029 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005030 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005031 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005032 break;
5033
5034 // Declaration kinds for which the definition is not resolvable.
5035 case Decl::UnresolvedUsingTypename:
5036 case Decl::UnresolvedUsingValue:
5037 break;
5038
5039 case Decl::UsingDirective:
5040 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5041 TU);
5042
5043 case Decl::NamespaceAlias:
5044 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5045
5046 case Decl::Enum:
5047 case Decl::Record:
5048 case Decl::CXXRecord:
5049 case Decl::ClassTemplateSpecialization:
5050 case Decl::ClassTemplatePartialSpecialization:
5051 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5052 return MakeCXCursor(Def, TU);
5053 return clang_getNullCursor();
5054
5055 case Decl::Function:
5056 case Decl::CXXMethod:
5057 case Decl::CXXConstructor:
5058 case Decl::CXXDestructor:
5059 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005060 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005061 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005062 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005063 return clang_getNullCursor();
5064 }
5065
Larisse Voufo39a1e502013-08-06 01:03:05 +00005066 case Decl::Var:
5067 case Decl::VarTemplateSpecialization:
5068 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005070 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005071 return MakeCXCursor(Def, TU);
5072 return clang_getNullCursor();
5073 }
5074
5075 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005076 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005077 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5078 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5079 return clang_getNullCursor();
5080 }
5081
5082 case Decl::ClassTemplate: {
5083 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5084 ->getDefinition())
5085 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5086 TU);
5087 return clang_getNullCursor();
5088 }
5089
Larisse Voufo39a1e502013-08-06 01:03:05 +00005090 case Decl::VarTemplate: {
5091 if (VarDecl *Def =
5092 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5093 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5094 return clang_getNullCursor();
5095 }
5096
Guy Benyei11169dd2012-12-18 14:30:41 +00005097 case Decl::Using:
5098 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5099 D->getLocation(), TU);
5100
5101 case Decl::UsingShadow:
5102 return clang_getCursorDefinition(
5103 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5104 TU));
5105
5106 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005107 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 if (Method->isThisDeclarationADefinition())
5109 return C;
5110
5111 // Dig out the method definition in the associated
5112 // @implementation, if we have it.
5113 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005114 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005115 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5116 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5117 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5118 Method->isInstanceMethod()))
5119 if (Def->isThisDeclarationADefinition())
5120 return MakeCXCursor(Def, TU);
5121
5122 return clang_getNullCursor();
5123 }
5124
5125 case Decl::ObjCCategory:
5126 if (ObjCCategoryImplDecl *Impl
5127 = cast<ObjCCategoryDecl>(D)->getImplementation())
5128 return MakeCXCursor(Impl, TU);
5129 return clang_getNullCursor();
5130
5131 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005132 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005133 return MakeCXCursor(Def, TU);
5134 return clang_getNullCursor();
5135
5136 case Decl::ObjCInterface: {
5137 // There are two notions of a "definition" for an Objective-C
5138 // class: the interface and its implementation. When we resolved a
5139 // reference to an Objective-C class, produce the @interface as
5140 // the definition; when we were provided with the interface,
5141 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005142 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005144 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 return MakeCXCursor(Def, TU);
5146 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5147 return MakeCXCursor(Impl, TU);
5148 return clang_getNullCursor();
5149 }
5150
5151 case Decl::ObjCProperty:
5152 // FIXME: We don't really know where to find the
5153 // ObjCPropertyImplDecls that implement this property.
5154 return clang_getNullCursor();
5155
5156 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005157 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005159 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 return MakeCXCursor(Def, TU);
5161
5162 return clang_getNullCursor();
5163
5164 case Decl::Friend:
5165 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5166 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5167 return clang_getNullCursor();
5168
5169 case Decl::FriendTemplate:
5170 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5171 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5172 return clang_getNullCursor();
5173 }
5174
5175 return clang_getNullCursor();
5176}
5177
5178unsigned clang_isCursorDefinition(CXCursor C) {
5179 if (!clang_isDeclaration(C.kind))
5180 return 0;
5181
5182 return clang_getCursorDefinition(C) == C;
5183}
5184
5185CXCursor clang_getCanonicalCursor(CXCursor C) {
5186 if (!clang_isDeclaration(C.kind))
5187 return C;
5188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005189 if (const Decl *D = getCursorDecl(C)) {
5190 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005191 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5192 return MakeCXCursor(CatD, getCursorTU(C));
5193
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005194 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5195 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 return MakeCXCursor(IFD, getCursorTU(C));
5197
5198 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5199 }
5200
5201 return C;
5202}
5203
5204int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5205 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5206}
5207
5208unsigned clang_getNumOverloadedDecls(CXCursor C) {
5209 if (C.kind != CXCursor_OverloadedDeclRef)
5210 return 0;
5211
5212 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005213 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 return E->getNumDecls();
5215
5216 if (OverloadedTemplateStorage *S
5217 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5218 return S->size();
5219
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005220 const Decl *D = Storage.get<const Decl *>();
5221 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 return Using->shadow_size();
5223
5224 return 0;
5225}
5226
5227CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5228 if (cursor.kind != CXCursor_OverloadedDeclRef)
5229 return clang_getNullCursor();
5230
5231 if (index >= clang_getNumOverloadedDecls(cursor))
5232 return clang_getNullCursor();
5233
5234 CXTranslationUnit TU = getCursorTU(cursor);
5235 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005236 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005237 return MakeCXCursor(E->decls_begin()[index], TU);
5238
5239 if (OverloadedTemplateStorage *S
5240 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5241 return MakeCXCursor(S->begin()[index], TU);
5242
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005243 const Decl *D = Storage.get<const Decl *>();
5244 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005245 // FIXME: This is, unfortunately, linear time.
5246 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5247 std::advance(Pos, index);
5248 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5249 }
5250
5251 return clang_getNullCursor();
5252}
5253
5254void clang_getDefinitionSpellingAndExtent(CXCursor C,
5255 const char **startBuf,
5256 const char **endBuf,
5257 unsigned *startLine,
5258 unsigned *startColumn,
5259 unsigned *endLine,
5260 unsigned *endColumn) {
5261 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005262 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005263 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5264
5265 SourceManager &SM = FD->getASTContext().getSourceManager();
5266 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5267 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5268 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5269 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5270 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5271 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5272}
5273
5274
5275CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5276 unsigned PieceIndex) {
5277 RefNamePieces Pieces;
5278
5279 switch (C.kind) {
5280 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005281 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5283 E->getQualifierLoc().getSourceRange());
5284 break;
5285
5286 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005287 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5289 E->getQualifierLoc().getSourceRange(),
5290 E->getOptionalExplicitTemplateArgs());
5291 break;
5292
5293 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005294 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005295 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005296 const Expr *Callee = OCE->getCallee();
5297 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 Callee = ICE->getSubExpr();
5299
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005300 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005301 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5302 DRE->getQualifierLoc().getSourceRange());
5303 }
5304 break;
5305
5306 default:
5307 break;
5308 }
5309
5310 if (Pieces.empty()) {
5311 if (PieceIndex == 0)
5312 return clang_getCursorExtent(C);
5313 } else if (PieceIndex < Pieces.size()) {
5314 SourceRange R = Pieces[PieceIndex];
5315 if (R.isValid())
5316 return cxloc::translateSourceRange(getCursorContext(C), R);
5317 }
5318
5319 return clang_getNullRange();
5320}
5321
5322void clang_enableStackTraces(void) {
5323 llvm::sys::PrintStackTraceOnErrorSignal();
5324}
5325
5326void clang_executeOnThread(void (*fn)(void*), void *user_data,
5327 unsigned stack_size) {
5328 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5329}
5330
5331} // end: extern "C"
5332
5333//===----------------------------------------------------------------------===//
5334// Token-based Operations.
5335//===----------------------------------------------------------------------===//
5336
5337/* CXToken layout:
5338 * int_data[0]: a CXTokenKind
5339 * int_data[1]: starting token location
5340 * int_data[2]: token length
5341 * int_data[3]: reserved
5342 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5343 * otherwise unused.
5344 */
5345extern "C" {
5346
5347CXTokenKind clang_getTokenKind(CXToken CXTok) {
5348 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5349}
5350
5351CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5352 switch (clang_getTokenKind(CXTok)) {
5353 case CXToken_Identifier:
5354 case CXToken_Keyword:
5355 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005356 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 ->getNameStart());
5358
5359 case CXToken_Literal: {
5360 // We have stashed the starting pointer in the ptr_data field. Use it.
5361 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005362 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005363 }
5364
5365 case CXToken_Punctuation:
5366 case CXToken_Comment:
5367 break;
5368 }
5369
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005370 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005371 LOG_BAD_TU(TU);
5372 return cxstring::createEmpty();
5373 }
5374
Guy Benyei11169dd2012-12-18 14:30:41 +00005375 // We have to find the starting buffer pointer the hard way, by
5376 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005377 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005379 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005380
5381 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5382 std::pair<FileID, unsigned> LocInfo
5383 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5384 bool Invalid = false;
5385 StringRef Buffer
5386 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5387 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005388 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005389
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005390 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005391}
5392
5393CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005394 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005395 LOG_BAD_TU(TU);
5396 return clang_getNullLocation();
5397 }
5398
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005399 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005400 if (!CXXUnit)
5401 return clang_getNullLocation();
5402
5403 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5404 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5405}
5406
5407CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005408 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005409 LOG_BAD_TU(TU);
5410 return clang_getNullRange();
5411 }
5412
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005413 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005414 if (!CXXUnit)
5415 return clang_getNullRange();
5416
5417 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5418 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5419}
5420
5421static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5422 SmallVectorImpl<CXToken> &CXTokens) {
5423 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5424 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005425 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005427 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005428
5429 // Cannot tokenize across files.
5430 if (BeginLocInfo.first != EndLocInfo.first)
5431 return;
5432
5433 // Create a lexer
5434 bool Invalid = false;
5435 StringRef Buffer
5436 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5437 if (Invalid)
5438 return;
5439
5440 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5441 CXXUnit->getASTContext().getLangOpts(),
5442 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5443 Lex.SetCommentRetentionState(true);
5444
5445 // Lex tokens until we hit the end of the range.
5446 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5447 Token Tok;
5448 bool previousWasAt = false;
5449 do {
5450 // Lex the next token
5451 Lex.LexFromRawLexer(Tok);
5452 if (Tok.is(tok::eof))
5453 break;
5454
5455 // Initialize the CXToken.
5456 CXToken CXTok;
5457
5458 // - Common fields
5459 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5460 CXTok.int_data[2] = Tok.getLength();
5461 CXTok.int_data[3] = 0;
5462
5463 // - Kind-specific fields
5464 if (Tok.isLiteral()) {
5465 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005466 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 } else if (Tok.is(tok::raw_identifier)) {
5468 // Lookup the identifier to determine whether we have a keyword.
5469 IdentifierInfo *II
5470 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5471
5472 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5473 CXTok.int_data[0] = CXToken_Keyword;
5474 }
5475 else {
5476 CXTok.int_data[0] = Tok.is(tok::identifier)
5477 ? CXToken_Identifier
5478 : CXToken_Keyword;
5479 }
5480 CXTok.ptr_data = II;
5481 } else if (Tok.is(tok::comment)) {
5482 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005483 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 } else {
5485 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005486 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 }
5488 CXTokens.push_back(CXTok);
5489 previousWasAt = Tok.is(tok::at);
5490 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5491}
5492
5493void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5494 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005495 LOG_FUNC_SECTION {
5496 *Log << TU << ' ' << Range;
5497 }
5498
Guy Benyei11169dd2012-12-18 14:30:41 +00005499 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005500 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005501 if (NumTokens)
5502 *NumTokens = 0;
5503
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005504 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005505 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005506 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005507 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005508
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005509 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005510 if (!CXXUnit || !Tokens || !NumTokens)
5511 return;
5512
5513 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5514
5515 SourceRange R = cxloc::translateCXSourceRange(Range);
5516 if (R.isInvalid())
5517 return;
5518
5519 SmallVector<CXToken, 32> CXTokens;
5520 getTokens(CXXUnit, R, CXTokens);
5521
5522 if (CXTokens.empty())
5523 return;
5524
5525 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5526 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5527 *NumTokens = CXTokens.size();
5528}
5529
5530void clang_disposeTokens(CXTranslationUnit TU,
5531 CXToken *Tokens, unsigned NumTokens) {
5532 free(Tokens);
5533}
5534
5535} // end: extern "C"
5536
5537//===----------------------------------------------------------------------===//
5538// Token annotation APIs.
5539//===----------------------------------------------------------------------===//
5540
Guy Benyei11169dd2012-12-18 14:30:41 +00005541static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5542 CXCursor parent,
5543 CXClientData client_data);
5544static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5545 CXClientData client_data);
5546
5547namespace {
5548class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005549 CXToken *Tokens;
5550 CXCursor *Cursors;
5551 unsigned NumTokens;
5552 unsigned TokIdx;
5553 unsigned PreprocessingTokIdx;
5554 CursorVisitor AnnotateVis;
5555 SourceManager &SrcMgr;
5556 bool HasContextSensitiveKeywords;
5557
5558 struct PostChildrenInfo {
5559 CXCursor Cursor;
5560 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005561 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005562 unsigned BeforeChildrenTokenIdx;
5563 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005564 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005565
5566 CXToken &getTok(unsigned Idx) {
5567 assert(Idx < NumTokens);
5568 return Tokens[Idx];
5569 }
5570 const CXToken &getTok(unsigned Idx) const {
5571 assert(Idx < NumTokens);
5572 return Tokens[Idx];
5573 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005574 bool MoreTokens() const { return TokIdx < NumTokens; }
5575 unsigned NextToken() const { return TokIdx; }
5576 void AdvanceToken() { ++TokIdx; }
5577 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005578 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005579 }
5580 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005581 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005582 }
5583 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005584 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005585 }
5586
5587 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005588 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005589 SourceRange);
5590
5591public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005592 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005593 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005594 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005596 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005597 AnnotateTokensVisitor, this,
5598 /*VisitPreprocessorLast=*/true,
5599 /*VisitIncludedEntities=*/false,
5600 RegionOfInterest,
5601 /*VisitDeclsOnly=*/false,
5602 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005603 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005604 HasContextSensitiveKeywords(false) { }
5605
5606 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5607 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5608 bool postVisitChildren(CXCursor cursor);
5609 void AnnotateTokens();
5610
5611 /// \brief Determine whether the annotator saw any cursors that have
5612 /// context-sensitive keywords.
5613 bool hasContextSensitiveKeywords() const {
5614 return HasContextSensitiveKeywords;
5615 }
5616
5617 ~AnnotateTokensWorker() {
5618 assert(PostChildrenInfos.empty());
5619 }
5620};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005621}
Guy Benyei11169dd2012-12-18 14:30:41 +00005622
5623void AnnotateTokensWorker::AnnotateTokens() {
5624 // Walk the AST within the region of interest, annotating tokens
5625 // along the way.
5626 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005627}
Guy Benyei11169dd2012-12-18 14:30:41 +00005628
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005629static inline void updateCursorAnnotation(CXCursor &Cursor,
5630 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005631 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005632 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005633 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005634}
5635
5636/// \brief It annotates and advances tokens with a cursor until the comparison
5637//// between the cursor location and the source range is the same as
5638/// \arg compResult.
5639///
5640/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5641/// Pass RangeOverlap to annotate tokens inside a range.
5642void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5643 RangeComparisonResult compResult,
5644 SourceRange range) {
5645 while (MoreTokens()) {
5646 const unsigned I = NextToken();
5647 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005648 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5649 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005650
5651 SourceLocation TokLoc = GetTokenLoc(I);
5652 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005653 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005654 AdvanceToken();
5655 continue;
5656 }
5657 break;
5658 }
5659}
5660
5661/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005662/// \returns true if it advanced beyond all macro tokens, false otherwise.
5663bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005664 CXCursor updateC,
5665 RangeComparisonResult compResult,
5666 SourceRange range) {
5667 assert(MoreTokens());
5668 assert(isFunctionMacroToken(NextToken()) &&
5669 "Should be called only for macro arg tokens");
5670
5671 // This works differently than annotateAndAdvanceTokens; because expanded
5672 // macro arguments can have arbitrary translation-unit source order, we do not
5673 // advance the token index one by one until a token fails the range test.
5674 // We only advance once past all of the macro arg tokens if all of them
5675 // pass the range test. If one of them fails we keep the token index pointing
5676 // at the start of the macro arg tokens so that the failing token will be
5677 // annotated by a subsequent annotation try.
5678
5679 bool atLeastOneCompFail = false;
5680
5681 unsigned I = NextToken();
5682 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5683 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5684 if (TokLoc.isFileID())
5685 continue; // not macro arg token, it's parens or comma.
5686 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5687 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5688 Cursors[I] = updateC;
5689 } else
5690 atLeastOneCompFail = true;
5691 }
5692
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005693 if (atLeastOneCompFail)
5694 return false;
5695
5696 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5697 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005698}
5699
5700enum CXChildVisitResult
5701AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005702 SourceRange cursorRange = getRawCursorExtent(cursor);
5703 if (cursorRange.isInvalid())
5704 return CXChildVisit_Recurse;
5705
5706 if (!HasContextSensitiveKeywords) {
5707 // Objective-C properties can have context-sensitive keywords.
5708 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005709 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005710 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5711 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5712 }
5713 // Objective-C methods can have context-sensitive keywords.
5714 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5715 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005716 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005717 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5718 if (Method->getObjCDeclQualifier())
5719 HasContextSensitiveKeywords = true;
5720 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005721 for (const auto *P : Method->params()) {
5722 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005723 HasContextSensitiveKeywords = true;
5724 break;
5725 }
5726 }
5727 }
5728 }
5729 }
5730 // C++ methods can have context-sensitive keywords.
5731 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005732 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005733 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5734 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5735 HasContextSensitiveKeywords = true;
5736 }
5737 }
5738 // C++ classes can have context-sensitive keywords.
5739 else if (cursor.kind == CXCursor_StructDecl ||
5740 cursor.kind == CXCursor_ClassDecl ||
5741 cursor.kind == CXCursor_ClassTemplate ||
5742 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005743 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005744 if (D->hasAttr<FinalAttr>())
5745 HasContextSensitiveKeywords = true;
5746 }
5747 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005748
5749 // Don't override a property annotation with its getter/setter method.
5750 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5751 parent.kind == CXCursor_ObjCPropertyDecl)
5752 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005753
5754 if (clang_isPreprocessing(cursor.kind)) {
5755 // Items in the preprocessing record are kept separate from items in
5756 // declarations, so we keep a separate token index.
5757 unsigned SavedTokIdx = TokIdx;
5758 TokIdx = PreprocessingTokIdx;
5759
5760 // Skip tokens up until we catch up to the beginning of the preprocessing
5761 // entry.
5762 while (MoreTokens()) {
5763 const unsigned I = NextToken();
5764 SourceLocation TokLoc = GetTokenLoc(I);
5765 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5766 case RangeBefore:
5767 AdvanceToken();
5768 continue;
5769 case RangeAfter:
5770 case RangeOverlap:
5771 break;
5772 }
5773 break;
5774 }
5775
5776 // Look at all of the tokens within this range.
5777 while (MoreTokens()) {
5778 const unsigned I = NextToken();
5779 SourceLocation TokLoc = GetTokenLoc(I);
5780 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5781 case RangeBefore:
5782 llvm_unreachable("Infeasible");
5783 case RangeAfter:
5784 break;
5785 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005786 // For macro expansions, just note where the beginning of the macro
5787 // expansion occurs.
5788 if (cursor.kind == CXCursor_MacroExpansion) {
5789 if (TokLoc == cursorRange.getBegin())
5790 Cursors[I] = cursor;
5791 AdvanceToken();
5792 break;
5793 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005794 // We may have already annotated macro names inside macro definitions.
5795 if (Cursors[I].kind != CXCursor_MacroExpansion)
5796 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005797 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005798 continue;
5799 }
5800 break;
5801 }
5802
5803 // Save the preprocessing token index; restore the non-preprocessing
5804 // token index.
5805 PreprocessingTokIdx = TokIdx;
5806 TokIdx = SavedTokIdx;
5807 return CXChildVisit_Recurse;
5808 }
5809
5810 if (cursorRange.isInvalid())
5811 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005812
5813 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005814 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005815 const enum CXCursorKind K = clang_getCursorKind(parent);
5816 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005817 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5818 // Attributes are annotated out-of-order, skip tokens until we reach it.
5819 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005820 ? clang_getNullCursor() : parent;
5821
5822 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5823
5824 // Avoid having the cursor of an expression "overwrite" the annotation of the
5825 // variable declaration that it belongs to.
5826 // This can happen for C++ constructor expressions whose range generally
5827 // include the variable declaration, e.g.:
5828 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005829 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005830 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005831 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005832 const unsigned I = NextToken();
5833 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5834 E->getLocStart() == D->getLocation() &&
5835 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005836 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005837 AdvanceToken();
5838 }
5839 }
5840 }
5841
5842 // Before recursing into the children keep some state that we are going
5843 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5844 // extra work after the child nodes are visited.
5845 // Note that we don't call VisitChildren here to avoid traversing statements
5846 // code-recursively which can blow the stack.
5847
5848 PostChildrenInfo Info;
5849 Info.Cursor = cursor;
5850 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005851 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005852 Info.BeforeChildrenTokenIdx = NextToken();
5853 PostChildrenInfos.push_back(Info);
5854
5855 return CXChildVisit_Recurse;
5856}
5857
5858bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5859 if (PostChildrenInfos.empty())
5860 return false;
5861 const PostChildrenInfo &Info = PostChildrenInfos.back();
5862 if (!clang_equalCursors(Info.Cursor, cursor))
5863 return false;
5864
5865 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5866 const unsigned AfterChildren = NextToken();
5867 SourceRange cursorRange = Info.CursorRange;
5868
5869 // Scan the tokens that are at the end of the cursor, but are not captured
5870 // but the child cursors.
5871 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5872
5873 // Scan the tokens that are at the beginning of the cursor, but are not
5874 // capture by the child cursors.
5875 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5876 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5877 break;
5878
5879 Cursors[I] = cursor;
5880 }
5881
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005882 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5883 // encountered the attribute cursor.
5884 if (clang_isAttribute(cursor.kind))
5885 TokIdx = Info.BeforeReachingCursorIdx;
5886
Guy Benyei11169dd2012-12-18 14:30:41 +00005887 PostChildrenInfos.pop_back();
5888 return false;
5889}
5890
5891static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5892 CXCursor parent,
5893 CXClientData client_data) {
5894 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5895}
5896
5897static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5898 CXClientData client_data) {
5899 return static_cast<AnnotateTokensWorker*>(client_data)->
5900 postVisitChildren(cursor);
5901}
5902
5903namespace {
5904
5905/// \brief Uses the macro expansions in the preprocessing record to find
5906/// and mark tokens that are macro arguments. This info is used by the
5907/// AnnotateTokensWorker.
5908class MarkMacroArgTokensVisitor {
5909 SourceManager &SM;
5910 CXToken *Tokens;
5911 unsigned NumTokens;
5912 unsigned CurIdx;
5913
5914public:
5915 MarkMacroArgTokensVisitor(SourceManager &SM,
5916 CXToken *tokens, unsigned numTokens)
5917 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5918
5919 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5920 if (cursor.kind != CXCursor_MacroExpansion)
5921 return CXChildVisit_Continue;
5922
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005923 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 if (macroRange.getBegin() == macroRange.getEnd())
5925 return CXChildVisit_Continue; // it's not a function macro.
5926
5927 for (; CurIdx < NumTokens; ++CurIdx) {
5928 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5929 macroRange.getBegin()))
5930 break;
5931 }
5932
5933 if (CurIdx == NumTokens)
5934 return CXChildVisit_Break;
5935
5936 for (; CurIdx < NumTokens; ++CurIdx) {
5937 SourceLocation tokLoc = getTokenLoc(CurIdx);
5938 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5939 break;
5940
5941 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5942 }
5943
5944 if (CurIdx == NumTokens)
5945 return CXChildVisit_Break;
5946
5947 return CXChildVisit_Continue;
5948 }
5949
5950private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005951 CXToken &getTok(unsigned Idx) {
5952 assert(Idx < NumTokens);
5953 return Tokens[Idx];
5954 }
5955 const CXToken &getTok(unsigned Idx) const {
5956 assert(Idx < NumTokens);
5957 return Tokens[Idx];
5958 }
5959
Guy Benyei11169dd2012-12-18 14:30:41 +00005960 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005961 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005962 }
5963
5964 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5965 // The third field is reserved and currently not used. Use it here
5966 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005967 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005968 }
5969};
5970
5971} // end anonymous namespace
5972
5973static CXChildVisitResult
5974MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5975 CXClientData client_data) {
5976 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5977 parent);
5978}
5979
5980namespace {
5981 struct clang_annotateTokens_Data {
5982 CXTranslationUnit TU;
5983 ASTUnit *CXXUnit;
5984 CXToken *Tokens;
5985 unsigned NumTokens;
5986 CXCursor *Cursors;
5987 };
5988}
5989
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005990/// \brief Used by \c annotatePreprocessorTokens.
5991/// \returns true if lexing was finished, false otherwise.
5992static bool lexNext(Lexer &Lex, Token &Tok,
5993 unsigned &NextIdx, unsigned NumTokens) {
5994 if (NextIdx >= NumTokens)
5995 return true;
5996
5997 ++NextIdx;
5998 Lex.LexFromRawLexer(Tok);
5999 if (Tok.is(tok::eof))
6000 return true;
6001
6002 return false;
6003}
6004
Guy Benyei11169dd2012-12-18 14:30:41 +00006005static void annotatePreprocessorTokens(CXTranslationUnit TU,
6006 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006007 CXCursor *Cursors,
6008 CXToken *Tokens,
6009 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006010 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006011
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006012 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006013 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6014 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006015 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006017 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006018
6019 if (BeginLocInfo.first != EndLocInfo.first)
6020 return;
6021
6022 StringRef Buffer;
6023 bool Invalid = false;
6024 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6025 if (Buffer.empty() || Invalid)
6026 return;
6027
6028 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6029 CXXUnit->getASTContext().getLangOpts(),
6030 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6031 Buffer.end());
6032 Lex.SetCommentRetentionState(true);
6033
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006034 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006035 // Lex tokens in raw mode until we hit the end of the range, to avoid
6036 // entering #includes or expanding macros.
6037 while (true) {
6038 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006039 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6040 break;
6041 unsigned TokIdx = NextIdx-1;
6042 assert(Tok.getLocation() ==
6043 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006044
6045 reprocess:
6046 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006047 // We have found a preprocessing directive. Annotate the tokens
6048 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006049 //
6050 // FIXME: Some simple tests here could identify macro definitions and
6051 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006052
6053 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006054 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6055 break;
6056
Craig Topper69186e72014-06-08 08:38:04 +00006057 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006058 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006059 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6060 break;
6061
6062 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006063 IdentifierInfo &II =
6064 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006065 SourceLocation MappedTokLoc =
6066 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6067 MI = getMacroInfo(II, MappedTokLoc, TU);
6068 }
6069 }
6070
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006071 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006072 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006073 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6074 finished = true;
6075 break;
6076 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006077 // If we are in a macro definition, check if the token was ever a
6078 // macro name and annotate it if that's the case.
6079 if (MI) {
6080 SourceLocation SaveLoc = Tok.getLocation();
6081 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006082 MacroDefinitionRecord *MacroDef =
6083 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006084 Tok.setLocation(SaveLoc);
6085 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006086 Cursors[NextIdx - 1] =
6087 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006088 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006089 } while (!Tok.isAtStartOfLine());
6090
6091 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6092 assert(TokIdx <= LastIdx);
6093 SourceLocation EndLoc =
6094 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6095 CXCursor Cursor =
6096 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6097
6098 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006099 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006100
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006101 if (finished)
6102 break;
6103 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006104 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006105 }
6106}
6107
6108// This gets run a separate thread to avoid stack blowout.
6109static void clang_annotateTokensImpl(void *UserData) {
6110 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6111 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6112 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6113 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6114 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6115
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006116 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006117 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6118 setThreadBackgroundPriority();
6119
6120 // Determine the region of interest, which contains all of the tokens.
6121 SourceRange RegionOfInterest;
6122 RegionOfInterest.setBegin(
6123 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6124 RegionOfInterest.setEnd(
6125 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6126 Tokens[NumTokens-1])));
6127
Guy Benyei11169dd2012-12-18 14:30:41 +00006128 // Relex the tokens within the source range to look for preprocessing
6129 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006130 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006131
6132 // If begin location points inside a macro argument, set it to the expansion
6133 // location so we can have the full context when annotating semantically.
6134 {
6135 SourceManager &SM = CXXUnit->getSourceManager();
6136 SourceLocation Loc =
6137 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6138 if (Loc.isMacroID())
6139 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6140 }
6141
Guy Benyei11169dd2012-12-18 14:30:41 +00006142 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6143 // Search and mark tokens that are macro argument expansions.
6144 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6145 Tokens, NumTokens);
6146 CursorVisitor MacroArgMarker(TU,
6147 MarkMacroArgTokensVisitorDelegate, &Visitor,
6148 /*VisitPreprocessorLast=*/true,
6149 /*VisitIncludedEntities=*/false,
6150 RegionOfInterest);
6151 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6152 }
6153
6154 // Annotate all of the source locations in the region of interest that map to
6155 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006156 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006157
6158 // FIXME: We use a ridiculous stack size here because the data-recursion
6159 // algorithm uses a large stack frame than the non-data recursive version,
6160 // and AnnotationTokensWorker currently transforms the data-recursion
6161 // algorithm back into a traditional recursion by explicitly calling
6162 // VisitChildren(). We will need to remove this explicit recursive call.
6163 W.AnnotateTokens();
6164
6165 // If we ran into any entities that involve context-sensitive keywords,
6166 // take another pass through the tokens to mark them as such.
6167 if (W.hasContextSensitiveKeywords()) {
6168 for (unsigned I = 0; I != NumTokens; ++I) {
6169 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6170 continue;
6171
6172 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6173 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006174 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006175 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6176 if (Property->getPropertyAttributesAsWritten() != 0 &&
6177 llvm::StringSwitch<bool>(II->getName())
6178 .Case("readonly", true)
6179 .Case("assign", true)
6180 .Case("unsafe_unretained", true)
6181 .Case("readwrite", true)
6182 .Case("retain", true)
6183 .Case("copy", true)
6184 .Case("nonatomic", true)
6185 .Case("atomic", true)
6186 .Case("getter", true)
6187 .Case("setter", true)
6188 .Case("strong", true)
6189 .Case("weak", true)
6190 .Default(false))
6191 Tokens[I].int_data[0] = CXToken_Keyword;
6192 }
6193 continue;
6194 }
6195
6196 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6197 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6198 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6199 if (llvm::StringSwitch<bool>(II->getName())
6200 .Case("in", true)
6201 .Case("out", true)
6202 .Case("inout", true)
6203 .Case("oneway", true)
6204 .Case("bycopy", true)
6205 .Case("byref", true)
6206 .Default(false))
6207 Tokens[I].int_data[0] = CXToken_Keyword;
6208 continue;
6209 }
6210
6211 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6212 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6213 Tokens[I].int_data[0] = CXToken_Keyword;
6214 continue;
6215 }
6216 }
6217 }
6218}
6219
6220extern "C" {
6221
6222void clang_annotateTokens(CXTranslationUnit TU,
6223 CXToken *Tokens, unsigned NumTokens,
6224 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006225 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006226 LOG_BAD_TU(TU);
6227 return;
6228 }
6229 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006230 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006231 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006232 }
6233
6234 LOG_FUNC_SECTION {
6235 *Log << TU << ' ';
6236 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6237 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6238 *Log << clang_getRange(bloc, eloc);
6239 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006240
6241 // Any token we don't specifically annotate will have a NULL cursor.
6242 CXCursor C = clang_getNullCursor();
6243 for (unsigned I = 0; I != NumTokens; ++I)
6244 Cursors[I] = C;
6245
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006246 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006247 if (!CXXUnit)
6248 return;
6249
6250 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6251
6252 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6253 llvm::CrashRecoveryContext CRC;
6254 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6255 GetSafetyThreadStackSize() * 2)) {
6256 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6257 }
6258}
6259
6260} // end: extern "C"
6261
6262//===----------------------------------------------------------------------===//
6263// Operations for querying linkage of a cursor.
6264//===----------------------------------------------------------------------===//
6265
6266extern "C" {
6267CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6268 if (!clang_isDeclaration(cursor.kind))
6269 return CXLinkage_Invalid;
6270
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006271 const Decl *D = cxcursor::getCursorDecl(cursor);
6272 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006273 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006274 case NoLinkage:
6275 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006276 case InternalLinkage: return CXLinkage_Internal;
6277 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6278 case ExternalLinkage: return CXLinkage_External;
6279 };
6280
6281 return CXLinkage_Invalid;
6282}
6283} // end: extern "C"
6284
6285//===----------------------------------------------------------------------===//
6286// Operations for querying language of a cursor.
6287//===----------------------------------------------------------------------===//
6288
6289static CXLanguageKind getDeclLanguage(const Decl *D) {
6290 if (!D)
6291 return CXLanguage_C;
6292
6293 switch (D->getKind()) {
6294 default:
6295 break;
6296 case Decl::ImplicitParam:
6297 case Decl::ObjCAtDefsField:
6298 case Decl::ObjCCategory:
6299 case Decl::ObjCCategoryImpl:
6300 case Decl::ObjCCompatibleAlias:
6301 case Decl::ObjCImplementation:
6302 case Decl::ObjCInterface:
6303 case Decl::ObjCIvar:
6304 case Decl::ObjCMethod:
6305 case Decl::ObjCProperty:
6306 case Decl::ObjCPropertyImpl:
6307 case Decl::ObjCProtocol:
6308 return CXLanguage_ObjC;
6309 case Decl::CXXConstructor:
6310 case Decl::CXXConversion:
6311 case Decl::CXXDestructor:
6312 case Decl::CXXMethod:
6313 case Decl::CXXRecord:
6314 case Decl::ClassTemplate:
6315 case Decl::ClassTemplatePartialSpecialization:
6316 case Decl::ClassTemplateSpecialization:
6317 case Decl::Friend:
6318 case Decl::FriendTemplate:
6319 case Decl::FunctionTemplate:
6320 case Decl::LinkageSpec:
6321 case Decl::Namespace:
6322 case Decl::NamespaceAlias:
6323 case Decl::NonTypeTemplateParm:
6324 case Decl::StaticAssert:
6325 case Decl::TemplateTemplateParm:
6326 case Decl::TemplateTypeParm:
6327 case Decl::UnresolvedUsingTypename:
6328 case Decl::UnresolvedUsingValue:
6329 case Decl::Using:
6330 case Decl::UsingDirective:
6331 case Decl::UsingShadow:
6332 return CXLanguage_CPlusPlus;
6333 }
6334
6335 return CXLanguage_C;
6336}
6337
6338extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006339
6340static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6341 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6342 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006343
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006344 switch (D->getAvailability()) {
6345 case AR_Available:
6346 case AR_NotYetIntroduced:
6347 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006348 return getCursorAvailabilityForDecl(
6349 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006350 return CXAvailability_Available;
6351
6352 case AR_Deprecated:
6353 return CXAvailability_Deprecated;
6354
6355 case AR_Unavailable:
6356 return CXAvailability_NotAvailable;
6357 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006358
6359 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006360}
6361
Guy Benyei11169dd2012-12-18 14:30:41 +00006362enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6363 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006364 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6365 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006366
6367 return CXAvailability_Available;
6368}
6369
6370static CXVersion convertVersion(VersionTuple In) {
6371 CXVersion Out = { -1, -1, -1 };
6372 if (In.empty())
6373 return Out;
6374
6375 Out.Major = In.getMajor();
6376
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006377 Optional<unsigned> Minor = In.getMinor();
6378 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006379 Out.Minor = *Minor;
6380 else
6381 return Out;
6382
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006383 Optional<unsigned> Subminor = In.getSubminor();
6384 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006385 Out.Subminor = *Subminor;
6386
6387 return Out;
6388}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006389
6390static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6391 int *always_deprecated,
6392 CXString *deprecated_message,
6393 int *always_unavailable,
6394 CXString *unavailable_message,
6395 CXPlatformAvailability *availability,
6396 int availability_size) {
6397 bool HadAvailAttr = false;
6398 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006399 for (auto A : D->attrs()) {
6400 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006401 HadAvailAttr = true;
6402 if (always_deprecated)
6403 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006404 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006405 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006406 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006407 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006408 continue;
6409 }
6410
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006411 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006412 HadAvailAttr = true;
6413 if (always_unavailable)
6414 *always_unavailable = 1;
6415 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006416 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006417 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6418 }
6419 continue;
6420 }
6421
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006422 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006423 HadAvailAttr = true;
6424 if (N < availability_size) {
6425 availability[N].Platform
6426 = cxstring::createDup(Avail->getPlatform()->getName());
6427 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6428 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6429 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6430 availability[N].Unavailable = Avail->getUnavailable();
6431 availability[N].Message = cxstring::createDup(Avail->getMessage());
6432 }
6433 ++N;
6434 }
6435 }
6436
6437 if (!HadAvailAttr)
6438 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6439 return getCursorPlatformAvailabilityForDecl(
6440 cast<Decl>(EnumConst->getDeclContext()),
6441 always_deprecated,
6442 deprecated_message,
6443 always_unavailable,
6444 unavailable_message,
6445 availability,
6446 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006447
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006448 return N;
6449}
6450
Guy Benyei11169dd2012-12-18 14:30:41 +00006451int clang_getCursorPlatformAvailability(CXCursor cursor,
6452 int *always_deprecated,
6453 CXString *deprecated_message,
6454 int *always_unavailable,
6455 CXString *unavailable_message,
6456 CXPlatformAvailability *availability,
6457 int availability_size) {
6458 if (always_deprecated)
6459 *always_deprecated = 0;
6460 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006461 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006462 if (always_unavailable)
6463 *always_unavailable = 0;
6464 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006465 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006466
Guy Benyei11169dd2012-12-18 14:30:41 +00006467 if (!clang_isDeclaration(cursor.kind))
6468 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006469
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006470 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006471 if (!D)
6472 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006473
6474 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6475 deprecated_message,
6476 always_unavailable,
6477 unavailable_message,
6478 availability,
6479 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006480}
6481
6482void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6483 clang_disposeString(availability->Platform);
6484 clang_disposeString(availability->Message);
6485}
6486
6487CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6488 if (clang_isDeclaration(cursor.kind))
6489 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6490
6491 return CXLanguage_Invalid;
6492}
6493
6494 /// \brief If the given cursor is the "templated" declaration
6495 /// descibing a class or function template, return the class or
6496 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006497static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006498 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006499 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006500
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006501 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006502 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6503 return FunTmpl;
6504
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006505 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006506 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6507 return ClassTmpl;
6508
6509 return D;
6510}
6511
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006512
6513enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6514 StorageClass sc = SC_None;
6515 const Decl *D = getCursorDecl(C);
6516 if (D) {
6517 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6518 sc = FD->getStorageClass();
6519 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6520 sc = VD->getStorageClass();
6521 } else {
6522 return CX_SC_Invalid;
6523 }
6524 } else {
6525 return CX_SC_Invalid;
6526 }
6527 switch (sc) {
6528 case SC_None:
6529 return CX_SC_None;
6530 case SC_Extern:
6531 return CX_SC_Extern;
6532 case SC_Static:
6533 return CX_SC_Static;
6534 case SC_PrivateExtern:
6535 return CX_SC_PrivateExtern;
6536 case SC_OpenCLWorkGroupLocal:
6537 return CX_SC_OpenCLWorkGroupLocal;
6538 case SC_Auto:
6539 return CX_SC_Auto;
6540 case SC_Register:
6541 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006542 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006543 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006544}
6545
Guy Benyei11169dd2012-12-18 14:30:41 +00006546CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6547 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006548 if (const Decl *D = getCursorDecl(cursor)) {
6549 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006550 if (!DC)
6551 return clang_getNullCursor();
6552
6553 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6554 getCursorTU(cursor));
6555 }
6556 }
6557
6558 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006559 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006560 return MakeCXCursor(D, getCursorTU(cursor));
6561 }
6562
6563 return clang_getNullCursor();
6564}
6565
6566CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6567 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006568 if (const Decl *D = getCursorDecl(cursor)) {
6569 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006570 if (!DC)
6571 return clang_getNullCursor();
6572
6573 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6574 getCursorTU(cursor));
6575 }
6576 }
6577
6578 // FIXME: Note that we can't easily compute the lexical context of a
6579 // statement or expression, so we return nothing.
6580 return clang_getNullCursor();
6581}
6582
6583CXFile clang_getIncludedFile(CXCursor cursor) {
6584 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006585 return nullptr;
6586
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006587 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006588 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006589}
6590
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006591unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6592 if (C.kind != CXCursor_ObjCPropertyDecl)
6593 return CXObjCPropertyAttr_noattr;
6594
6595 unsigned Result = CXObjCPropertyAttr_noattr;
6596 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6597 ObjCPropertyDecl::PropertyAttributeKind Attr =
6598 PD->getPropertyAttributesAsWritten();
6599
6600#define SET_CXOBJCPROP_ATTR(A) \
6601 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6602 Result |= CXObjCPropertyAttr_##A
6603 SET_CXOBJCPROP_ATTR(readonly);
6604 SET_CXOBJCPROP_ATTR(getter);
6605 SET_CXOBJCPROP_ATTR(assign);
6606 SET_CXOBJCPROP_ATTR(readwrite);
6607 SET_CXOBJCPROP_ATTR(retain);
6608 SET_CXOBJCPROP_ATTR(copy);
6609 SET_CXOBJCPROP_ATTR(nonatomic);
6610 SET_CXOBJCPROP_ATTR(setter);
6611 SET_CXOBJCPROP_ATTR(atomic);
6612 SET_CXOBJCPROP_ATTR(weak);
6613 SET_CXOBJCPROP_ATTR(strong);
6614 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6615#undef SET_CXOBJCPROP_ATTR
6616
6617 return Result;
6618}
6619
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006620unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6621 if (!clang_isDeclaration(C.kind))
6622 return CXObjCDeclQualifier_None;
6623
6624 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6625 const Decl *D = getCursorDecl(C);
6626 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6627 QT = MD->getObjCDeclQualifier();
6628 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6629 QT = PD->getObjCDeclQualifier();
6630 if (QT == Decl::OBJC_TQ_None)
6631 return CXObjCDeclQualifier_None;
6632
6633 unsigned Result = CXObjCDeclQualifier_None;
6634 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6635 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6636 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6637 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6638 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6639 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6640
6641 return Result;
6642}
6643
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006644unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6645 if (!clang_isDeclaration(C.kind))
6646 return 0;
6647
6648 const Decl *D = getCursorDecl(C);
6649 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6650 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6651 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6652 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6653
6654 return 0;
6655}
6656
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006657unsigned clang_Cursor_isVariadic(CXCursor C) {
6658 if (!clang_isDeclaration(C.kind))
6659 return 0;
6660
6661 const Decl *D = getCursorDecl(C);
6662 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6663 return FD->isVariadic();
6664 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6665 return MD->isVariadic();
6666
6667 return 0;
6668}
6669
Guy Benyei11169dd2012-12-18 14:30:41 +00006670CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6671 if (!clang_isDeclaration(C.kind))
6672 return clang_getNullRange();
6673
6674 const Decl *D = getCursorDecl(C);
6675 ASTContext &Context = getCursorContext(C);
6676 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6677 if (!RC)
6678 return clang_getNullRange();
6679
6680 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6681}
6682
6683CXString clang_Cursor_getRawCommentText(CXCursor C) {
6684 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006685 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006686
6687 const Decl *D = getCursorDecl(C);
6688 ASTContext &Context = getCursorContext(C);
6689 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6690 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6691 StringRef();
6692
6693 // Don't duplicate the string because RawText points directly into source
6694 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006695 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006696}
6697
6698CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6699 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006700 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006701
6702 const Decl *D = getCursorDecl(C);
6703 const ASTContext &Context = getCursorContext(C);
6704 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6705
6706 if (RC) {
6707 StringRef BriefText = RC->getBriefText(Context);
6708
6709 // Don't duplicate the string because RawComment ensures that this memory
6710 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006711 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006712 }
6713
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006714 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006715}
6716
Guy Benyei11169dd2012-12-18 14:30:41 +00006717CXModule clang_Cursor_getModule(CXCursor C) {
6718 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006719 if (const ImportDecl *ImportD =
6720 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006721 return ImportD->getImportedModule();
6722 }
6723
Craig Topper69186e72014-06-08 08:38:04 +00006724 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006725}
6726
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006727CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6728 if (isNotUsableTU(TU)) {
6729 LOG_BAD_TU(TU);
6730 return nullptr;
6731 }
6732 if (!File)
6733 return nullptr;
6734 FileEntry *FE = static_cast<FileEntry *>(File);
6735
6736 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6737 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6738 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6739
Richard Smithfeb54b62014-10-23 02:01:19 +00006740 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006741}
6742
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006743CXFile clang_Module_getASTFile(CXModule CXMod) {
6744 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006745 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006746 Module *Mod = static_cast<Module*>(CXMod);
6747 return const_cast<FileEntry *>(Mod->getASTFile());
6748}
6749
Guy Benyei11169dd2012-12-18 14:30:41 +00006750CXModule clang_Module_getParent(CXModule CXMod) {
6751 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006752 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006753 Module *Mod = static_cast<Module*>(CXMod);
6754 return Mod->Parent;
6755}
6756
6757CXString clang_Module_getName(CXModule CXMod) {
6758 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006759 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006760 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006761 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006762}
6763
6764CXString clang_Module_getFullName(CXModule CXMod) {
6765 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006766 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006767 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006768 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006769}
6770
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006771int clang_Module_isSystem(CXModule CXMod) {
6772 if (!CXMod)
6773 return 0;
6774 Module *Mod = static_cast<Module*>(CXMod);
6775 return Mod->IsSystem;
6776}
6777
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006778unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6779 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006780 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006781 LOG_BAD_TU(TU);
6782 return 0;
6783 }
6784 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006785 return 0;
6786 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006787 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6788 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6789 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006790}
6791
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006792CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6793 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006794 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006795 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006796 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006797 }
6798 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006799 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006800 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006801 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006802
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006803 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6804 if (Index < TopHeaders.size())
6805 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006806
Craig Topper69186e72014-06-08 08:38:04 +00006807 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006808}
6809
6810} // end: extern "C"
6811
6812//===----------------------------------------------------------------------===//
6813// C++ AST instrospection.
6814//===----------------------------------------------------------------------===//
6815
6816extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006817unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6818 if (!clang_isDeclaration(C.kind))
6819 return 0;
6820
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006821 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006822 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006823 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006824 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6825}
6826
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006827unsigned clang_CXXMethod_isConst(CXCursor C) {
6828 if (!clang_isDeclaration(C.kind))
6829 return 0;
6830
6831 const Decl *D = cxcursor::getCursorDecl(C);
6832 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006833 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006834 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6835}
6836
Guy Benyei11169dd2012-12-18 14:30:41 +00006837unsigned clang_CXXMethod_isStatic(CXCursor C) {
6838 if (!clang_isDeclaration(C.kind))
6839 return 0;
6840
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006841 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006842 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006843 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006844 return (Method && Method->isStatic()) ? 1 : 0;
6845}
6846
6847unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6848 if (!clang_isDeclaration(C.kind))
6849 return 0;
6850
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006851 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006852 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006853 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006854 return (Method && Method->isVirtual()) ? 1 : 0;
6855}
6856} // end: extern "C"
6857
6858//===----------------------------------------------------------------------===//
6859// Attribute introspection.
6860//===----------------------------------------------------------------------===//
6861
6862extern "C" {
6863CXType clang_getIBOutletCollectionType(CXCursor C) {
6864 if (C.kind != CXCursor_IBOutletCollectionAttr)
6865 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6866
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006867 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006868 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6869
6870 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6871}
6872} // end: extern "C"
6873
6874//===----------------------------------------------------------------------===//
6875// Inspecting memory usage.
6876//===----------------------------------------------------------------------===//
6877
6878typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6879
6880static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6881 enum CXTUResourceUsageKind k,
6882 unsigned long amount) {
6883 CXTUResourceUsageEntry entry = { k, amount };
6884 entries.push_back(entry);
6885}
6886
6887extern "C" {
6888
6889const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6890 const char *str = "";
6891 switch (kind) {
6892 case CXTUResourceUsage_AST:
6893 str = "ASTContext: expressions, declarations, and types";
6894 break;
6895 case CXTUResourceUsage_Identifiers:
6896 str = "ASTContext: identifiers";
6897 break;
6898 case CXTUResourceUsage_Selectors:
6899 str = "ASTContext: selectors";
6900 break;
6901 case CXTUResourceUsage_GlobalCompletionResults:
6902 str = "Code completion: cached global results";
6903 break;
6904 case CXTUResourceUsage_SourceManagerContentCache:
6905 str = "SourceManager: content cache allocator";
6906 break;
6907 case CXTUResourceUsage_AST_SideTables:
6908 str = "ASTContext: side tables";
6909 break;
6910 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6911 str = "SourceManager: malloc'ed memory buffers";
6912 break;
6913 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6914 str = "SourceManager: mmap'ed memory buffers";
6915 break;
6916 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6917 str = "ExternalASTSource: malloc'ed memory buffers";
6918 break;
6919 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6920 str = "ExternalASTSource: mmap'ed memory buffers";
6921 break;
6922 case CXTUResourceUsage_Preprocessor:
6923 str = "Preprocessor: malloc'ed memory";
6924 break;
6925 case CXTUResourceUsage_PreprocessingRecord:
6926 str = "Preprocessor: PreprocessingRecord";
6927 break;
6928 case CXTUResourceUsage_SourceManager_DataStructures:
6929 str = "SourceManager: data structures and tables";
6930 break;
6931 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6932 str = "Preprocessor: header search tables";
6933 break;
6934 }
6935 return str;
6936}
6937
6938CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006939 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006940 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006941 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006942 return usage;
6943 }
6944
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006945 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006946 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006947 ASTContext &astContext = astUnit->getASTContext();
6948
6949 // How much memory is used by AST nodes and types?
6950 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6951 (unsigned long) astContext.getASTAllocatedMemory());
6952
6953 // How much memory is used by identifiers?
6954 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6955 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6956
6957 // How much memory is used for selectors?
6958 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6959 (unsigned long) astContext.Selectors.getTotalMemory());
6960
6961 // How much memory is used by ASTContext's side tables?
6962 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6963 (unsigned long) astContext.getSideTableAllocatedMemory());
6964
6965 // How much memory is used for caching global code completion results?
6966 unsigned long completionBytes = 0;
6967 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006968 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006969 completionBytes = completionAllocator->getTotalMemory();
6970 }
6971 createCXTUResourceUsageEntry(*entries,
6972 CXTUResourceUsage_GlobalCompletionResults,
6973 completionBytes);
6974
6975 // How much memory is being used by SourceManager's content cache?
6976 createCXTUResourceUsageEntry(*entries,
6977 CXTUResourceUsage_SourceManagerContentCache,
6978 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6979
6980 // How much memory is being used by the MemoryBuffer's in SourceManager?
6981 const SourceManager::MemoryBufferSizes &srcBufs =
6982 astUnit->getSourceManager().getMemoryBufferSizes();
6983
6984 createCXTUResourceUsageEntry(*entries,
6985 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6986 (unsigned long) srcBufs.malloc_bytes);
6987 createCXTUResourceUsageEntry(*entries,
6988 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6989 (unsigned long) srcBufs.mmap_bytes);
6990 createCXTUResourceUsageEntry(*entries,
6991 CXTUResourceUsage_SourceManager_DataStructures,
6992 (unsigned long) astContext.getSourceManager()
6993 .getDataStructureSizes());
6994
6995 // How much memory is being used by the ExternalASTSource?
6996 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6997 const ExternalASTSource::MemoryBufferSizes &sizes =
6998 esrc->getMemoryBufferSizes();
6999
7000 createCXTUResourceUsageEntry(*entries,
7001 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7002 (unsigned long) sizes.malloc_bytes);
7003 createCXTUResourceUsageEntry(*entries,
7004 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7005 (unsigned long) sizes.mmap_bytes);
7006 }
7007
7008 // How much memory is being used by the Preprocessor?
7009 Preprocessor &pp = astUnit->getPreprocessor();
7010 createCXTUResourceUsageEntry(*entries,
7011 CXTUResourceUsage_Preprocessor,
7012 pp.getTotalMemory());
7013
7014 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7015 createCXTUResourceUsageEntry(*entries,
7016 CXTUResourceUsage_PreprocessingRecord,
7017 pRec->getTotalMemory());
7018 }
7019
7020 createCXTUResourceUsageEntry(*entries,
7021 CXTUResourceUsage_Preprocessor_HeaderSearch,
7022 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007023
Guy Benyei11169dd2012-12-18 14:30:41 +00007024 CXTUResourceUsage usage = { (void*) entries.get(),
7025 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007026 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007027 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007028 return usage;
7029}
7030
7031void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7032 if (usage.data)
7033 delete (MemUsageEntries*) usage.data;
7034}
7035
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007036CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7037 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007038 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007039 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007040
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007041 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007042 LOG_BAD_TU(TU);
7043 return skipped;
7044 }
7045
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007046 if (!file)
7047 return skipped;
7048
7049 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7050 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7051 if (!ppRec)
7052 return skipped;
7053
7054 ASTContext &Ctx = astUnit->getASTContext();
7055 SourceManager &sm = Ctx.getSourceManager();
7056 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7057 FileID wantedFileID = sm.translateFile(fileEntry);
7058
7059 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7060 std::vector<SourceRange> wantedRanges;
7061 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7062 i != ei; ++i) {
7063 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7064 wantedRanges.push_back(*i);
7065 }
7066
7067 skipped->count = wantedRanges.size();
7068 skipped->ranges = new CXSourceRange[skipped->count];
7069 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7070 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7071
7072 return skipped;
7073}
7074
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007075void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7076 if (ranges) {
7077 delete[] ranges->ranges;
7078 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007079 }
7080}
7081
Guy Benyei11169dd2012-12-18 14:30:41 +00007082} // end extern "C"
7083
7084void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7085 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7086 for (unsigned I = 0; I != Usage.numEntries; ++I)
7087 fprintf(stderr, " %s: %lu\n",
7088 clang_getTUResourceUsageName(Usage.entries[I].kind),
7089 Usage.entries[I].amount);
7090
7091 clang_disposeCXTUResourceUsage(Usage);
7092}
7093
7094//===----------------------------------------------------------------------===//
7095// Misc. utility functions.
7096//===----------------------------------------------------------------------===//
7097
7098/// Default to using an 8 MB stack size on "safety" threads.
7099static unsigned SafetyStackThreadSize = 8 << 20;
7100
7101namespace clang {
7102
7103bool RunSafely(llvm::CrashRecoveryContext &CRC,
7104 void (*Fn)(void*), void *UserData,
7105 unsigned Size) {
7106 if (!Size)
7107 Size = GetSafetyThreadStackSize();
7108 if (Size)
7109 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7110 return CRC.RunSafely(Fn, UserData);
7111}
7112
7113unsigned GetSafetyThreadStackSize() {
7114 return SafetyStackThreadSize;
7115}
7116
7117void SetSafetyThreadStackSize(unsigned Value) {
7118 SafetyStackThreadSize = Value;
7119}
7120
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007121}
Guy Benyei11169dd2012-12-18 14:30:41 +00007122
7123void clang::setThreadBackgroundPriority() {
7124 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7125 return;
7126
Alp Toker1a86ad22014-07-06 06:24:00 +00007127#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007128 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7129#endif
7130}
7131
7132void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7133 if (!Unit)
7134 return;
7135
7136 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7137 DEnd = Unit->stored_diag_end();
7138 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007139 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007140 CXString Msg = clang_formatDiagnostic(&Diag,
7141 clang_defaultDiagnosticDisplayOptions());
7142 fprintf(stderr, "%s\n", clang_getCString(Msg));
7143 clang_disposeString(Msg);
7144 }
7145#ifdef LLVM_ON_WIN32
7146 // On Windows, force a flush, since there may be multiple copies of
7147 // stderr and stdout in the file system, all with different buffers
7148 // but writing to the same device.
7149 fflush(stderr);
7150#endif
7151}
7152
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007153MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7154 SourceLocation MacroDefLoc,
7155 CXTranslationUnit TU){
7156 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007157 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007158 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007159 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007160
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007161 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007162 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007163 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007164 if (MD) {
7165 for (MacroDirective::DefInfo
7166 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7167 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7168 return Def.getMacroInfo();
7169 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007170 }
7171
Craig Topper69186e72014-06-08 08:38:04 +00007172 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007173}
7174
Richard Smith66a81862015-05-04 02:25:31 +00007175const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007176 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007177 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007178 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007179 const IdentifierInfo *II = MacroDef->getName();
7180 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007181 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007182
7183 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7184}
7185
Richard Smith66a81862015-05-04 02:25:31 +00007186MacroDefinitionRecord *
7187cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7188 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007189 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007190 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007191 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007192 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007193
7194 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007195 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007196 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7197 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007198 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007199
7200 // Check that the token is inside the definition and not its argument list.
7201 SourceManager &SM = Unit->getSourceManager();
7202 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007203 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007204 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007205 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007206
7207 Preprocessor &PP = Unit->getPreprocessor();
7208 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7209 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007210 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007211
Alp Toker2d57cea2014-05-17 04:53:25 +00007212 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007213 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007214 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007215
7216 // Check that the identifier is not one of the macro arguments.
7217 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007218 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007219
Richard Smith20e883e2015-04-29 23:20:19 +00007220 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007221 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007222 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007223
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007224 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007225}
7226
Richard Smith66a81862015-05-04 02:25:31 +00007227MacroDefinitionRecord *
7228cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7229 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007230 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007231 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007232
7233 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007234 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007235 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007236 Preprocessor &PP = Unit->getPreprocessor();
7237 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007238 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007239 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7240 Token Tok;
7241 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007242 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007243
7244 return checkForMacroInMacroDefinition(MI, Tok, TU);
7245}
7246
Guy Benyei11169dd2012-12-18 14:30:41 +00007247extern "C" {
7248
7249CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007250 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007251}
7252
7253} // end: extern "C"
7254
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007255Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7256 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007257 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007258 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007259 if (Unit->isMainFileAST())
7260 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007261 return *this;
7262 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007263 } else {
7264 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007265 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007266 return *this;
7267}
7268
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007269Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7270 *this << FE->getName();
7271 return *this;
7272}
7273
7274Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7275 CXString cursorName = clang_getCursorDisplayName(cursor);
7276 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7277 clang_disposeString(cursorName);
7278 return *this;
7279}
7280
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007281Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7282 CXFile File;
7283 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007284 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007285 CXString FileName = clang_getFileName(File);
7286 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7287 clang_disposeString(FileName);
7288 return *this;
7289}
7290
7291Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7292 CXSourceLocation BLoc = clang_getRangeStart(range);
7293 CXSourceLocation ELoc = clang_getRangeEnd(range);
7294
7295 CXFile BFile;
7296 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007297 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007298
7299 CXFile EFile;
7300 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007301 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007302
7303 CXString BFileName = clang_getFileName(BFile);
7304 if (BFile == EFile) {
7305 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7306 BLine, BColumn, ELine, EColumn);
7307 } else {
7308 CXString EFileName = clang_getFileName(EFile);
7309 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7310 BLine, BColumn)
7311 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7312 ELine, EColumn);
7313 clang_disposeString(EFileName);
7314 }
7315 clang_disposeString(BFileName);
7316 return *this;
7317}
7318
7319Logger &cxindex::Logger::operator<<(CXString Str) {
7320 *this << clang_getCString(Str);
7321 return *this;
7322}
7323
7324Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7325 LogOS << Fmt;
7326 return *this;
7327}
7328
Chandler Carruth37ad2582014-06-27 15:14:39 +00007329static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7330
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007331cxindex::Logger::~Logger() {
7332 LogOS.flush();
7333
Chandler Carruth37ad2582014-06-27 15:14:39 +00007334 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007335
7336 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7337
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007338 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007339 OS << "[libclang:" << Name << ':';
7340
Alp Toker1a86ad22014-07-06 06:24:00 +00007341#ifdef USE_DARWIN_THREADS
7342 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007343 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7344 OS << tid << ':';
7345#endif
7346
7347 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7348 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007349 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007350
7351 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007352 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007353 OS << "--------------------------------------------------\n";
7354 }
7355}