blob: 05287bd856e8278a29011be0d0400f7f36dd758f [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 Bataev6125da92014-07-21 11:26:11 +00001882 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001883 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001884 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001885 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001886 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887
Guy Benyei11169dd2012-12-18 14:30:41 +00001888private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1891 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1893 void AddStmt(const Stmt *S);
1894 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001897 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001898};
1899} // end anonyous namespace
1900
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 // 'S' should always be non-null, since it comes from the
1903 // statement we are visiting.
1904 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1905}
1906
1907void
1908EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1909 if (Qualifier)
1910 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1911}
1912
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 if (S)
1915 WL.push_back(StmtVisit(S, Parent));
1916}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001918 if (D)
1919 WL.push_back(DeclVisit(D, Parent, isFirst));
1920}
1921void EnqueueVisitor::
1922 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1923 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001924 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001925}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001926void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001927 if (D)
1928 WL.push_back(MemberRefVisit(D, L, Parent));
1929}
1930void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1931 if (TI)
1932 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1933 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001934void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001935 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001936 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 AddStmt(*Child);
1938 }
1939 if (size == WL.size())
1940 return;
1941 // Now reverse the entries we just added. This will match the DFS
1942 // ordering performed by the worklist.
1943 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1944 std::reverse(I, E);
1945}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946namespace {
1947class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1948 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001949 /// \brief Process clauses with list of variables.
1950 template <typename T>
1951 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001952public:
1953 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1954#define OPENMP_CLAUSE(Name, Class) \
1955 void Visit##Class(const Class *C);
1956#include "clang/Basic/OpenMPKinds.def"
1957};
1958
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001959void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1960 Visitor->AddStmt(C->getCondition());
1961}
1962
Alexey Bataev3778b602014-07-17 07:32:53 +00001963void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1964 Visitor->AddStmt(C->getCondition());
1965}
1966
Alexey Bataev568a8332014-03-06 06:15:19 +00001967void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1968 Visitor->AddStmt(C->getNumThreads());
1969}
1970
Alexey Bataev62c87d22014-03-21 04:51:18 +00001971void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1972 Visitor->AddStmt(C->getSafelen());
1973}
1974
Alexander Musman8bd31e62014-05-27 15:12:19 +00001975void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1976 Visitor->AddStmt(C->getNumForLoops());
1977}
1978
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001979void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001980
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001981void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1982
Alexey Bataev56dafe82014-06-20 07:16:17 +00001983void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1984 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00001985 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00001986}
1987
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001988void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1989
Alexey Bataev236070f2014-06-20 11:19:47 +00001990void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1991
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001992void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1993
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001994void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1995
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001996void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1997
Alexey Bataevdea47612014-07-23 07:46:59 +00001998void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1999
Alexey Bataev67a4f222014-07-23 10:25:33 +00002000void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2001
Alexey Bataev459dec02014-07-24 06:46:57 +00002002void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2003
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002004void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2005
Alexey Bataev756c1962013-09-24 03:17:45 +00002006template<typename T>
2007void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002008 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002009 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002010 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002011}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002012
2013void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002014 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002015 for (const auto *E : C->private_copies()) {
2016 Visitor->AddStmt(E);
2017 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002018}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002019void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2020 const OMPFirstprivateClause *C) {
2021 VisitOMPClauseList(C);
2022}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002023void OMPClauseEnqueue::VisitOMPLastprivateClause(
2024 const OMPLastprivateClause *C) {
2025 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002026 for (auto *E : C->private_copies()) {
2027 Visitor->AddStmt(E);
2028 }
2029 for (auto *E : C->source_exprs()) {
2030 Visitor->AddStmt(E);
2031 }
2032 for (auto *E : C->destination_exprs()) {
2033 Visitor->AddStmt(E);
2034 }
2035 for (auto *E : C->assignment_ops()) {
2036 Visitor->AddStmt(E);
2037 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002038}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002039void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002040 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002041}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002042void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2043 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002044 for (auto *E : C->lhs_exprs()) {
2045 Visitor->AddStmt(E);
2046 }
2047 for (auto *E : C->rhs_exprs()) {
2048 Visitor->AddStmt(E);
2049 }
2050 for (auto *E : C->reduction_ops()) {
2051 Visitor->AddStmt(E);
2052 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002053}
Alexander Musman8dba6642014-04-22 13:09:42 +00002054void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2055 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002056 for (const auto *E : C->inits()) {
2057 Visitor->AddStmt(E);
2058 }
2059 for (const auto *E : C->updates()) {
2060 Visitor->AddStmt(E);
2061 }
2062 for (const auto *E : C->finals()) {
2063 Visitor->AddStmt(E);
2064 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002065 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002066 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002067}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002068void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2069 VisitOMPClauseList(C);
2070 Visitor->AddStmt(C->getAlignment());
2071}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002072void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2073 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002074 for (auto *E : C->source_exprs()) {
2075 Visitor->AddStmt(E);
2076 }
2077 for (auto *E : C->destination_exprs()) {
2078 Visitor->AddStmt(E);
2079 }
2080 for (auto *E : C->assignment_ops()) {
2081 Visitor->AddStmt(E);
2082 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002083}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002084void
2085OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2086 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002087 for (auto *E : C->source_exprs()) {
2088 Visitor->AddStmt(E);
2089 }
2090 for (auto *E : C->destination_exprs()) {
2091 Visitor->AddStmt(E);
2092 }
2093 for (auto *E : C->assignment_ops()) {
2094 Visitor->AddStmt(E);
2095 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002096}
Alexey Bataev6125da92014-07-21 11:26:11 +00002097void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2098 VisitOMPClauseList(C);
2099}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002100}
Alexey Bataev756c1962013-09-24 03:17:45 +00002101
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002102void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2103 unsigned size = WL.size();
2104 OMPClauseEnqueue Visitor(this);
2105 Visitor.Visit(S);
2106 if (size == WL.size())
2107 return;
2108 // Now reverse the entries we just added. This will match the DFS
2109 // ordering performed by the worklist.
2110 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2111 std::reverse(I, E);
2112}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002113void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002114 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 AddDecl(B->getBlockDecl());
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 EnqueueChildren(E);
2121 AddTypeLoc(E->getTypeSourceInfo());
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2124 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 E = S->body_rend(); I != E; ++I) {
2126 AddStmt(*I);
2127 }
2128}
2129void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 AddStmt(S->getSubStmt());
2132 AddDeclarationNameInfo(S);
2133 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2134 AddNestedNameSpecifierLoc(QualifierLoc);
2135}
2136
2137void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2140 AddDeclarationNameInfo(E);
2141 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2142 AddNestedNameSpecifierLoc(QualifierLoc);
2143 if (!E->isImplicitAccess())
2144 AddStmt(E->getBase());
2145}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 // Enqueue the initializer , if any.
2148 AddStmt(E->getInitializer());
2149 // Enqueue the array size, if any.
2150 AddStmt(E->getArraySize());
2151 // Enqueue the allocated type.
2152 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2153 // Enqueue the placement arguments.
2154 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2155 AddStmt(E->getPlacementArg(I-1));
2156}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002157void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002158 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2159 AddStmt(CE->getArg(I-1));
2160 AddStmt(CE->getCallee());
2161 AddStmt(CE->getArg(0));
2162}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2164 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 // Visit the name of the type being destroyed.
2166 AddTypeLoc(E->getDestroyedTypeInfo());
2167 // Visit the scope type that looks disturbingly like the nested-name-specifier
2168 // but isn't.
2169 AddTypeLoc(E->getScopeTypeInfo());
2170 // Visit the nested-name-specifier.
2171 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2172 AddNestedNameSpecifierLoc(QualifierLoc);
2173 // Visit base expression.
2174 AddStmt(E->getBase());
2175}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002176void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2177 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002178 AddTypeLoc(E->getTypeSourceInfo());
2179}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2181 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 EnqueueChildren(E);
2183 AddTypeLoc(E->getTypeSourceInfo());
2184}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 EnqueueChildren(E);
2187 if (E->isTypeOperand())
2188 AddTypeLoc(E->getTypeOperandSourceInfo());
2189}
2190
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2192 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 EnqueueChildren(E);
2194 AddTypeLoc(E->getTypeSourceInfo());
2195}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002196void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 EnqueueChildren(E);
2198 if (E->isTypeOperand())
2199 AddTypeLoc(E->getTypeOperandSourceInfo());
2200}
2201
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 EnqueueChildren(S);
2204 AddDecl(S->getExceptionDecl());
2205}
2206
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002207void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002208 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002209 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002210 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002211}
2212
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 if (DR->hasExplicitTemplateArgs()) {
2215 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2216 }
2217 WL.push_back(DeclRefExprParts(DR, Parent));
2218}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2220 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2222 AddDeclarationNameInfo(E);
2223 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 unsigned size = WL.size();
2227 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002228 for (const auto *D : S->decls()) {
2229 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 isFirst = false;
2231 }
2232 if (size == WL.size())
2233 return;
2234 // Now reverse the entries we just added. This will match the DFS
2235 // ordering performed by the worklist.
2236 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2237 std::reverse(I, E);
2238}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002242 D = E->designators_rbegin(), DEnd = E->designators_rend();
2243 D != DEnd; ++D) {
2244 if (D->isFieldDesignator()) {
2245 if (FieldDecl *Field = D->getField())
2246 AddMemberRef(Field, D->getFieldLoc());
2247 continue;
2248 }
2249 if (D->isArrayDesignator()) {
2250 AddStmt(E->getArrayIndex(*D));
2251 continue;
2252 }
2253 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2254 AddStmt(E->getArrayRangeEnd(*D));
2255 AddStmt(E->getArrayRangeStart(*D));
2256 }
2257}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002258void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002259 EnqueueChildren(E);
2260 AddTypeLoc(E->getTypeInfoAsWritten());
2261}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 AddStmt(FS->getBody());
2264 AddStmt(FS->getInc());
2265 AddStmt(FS->getCond());
2266 AddDecl(FS->getConditionVariable());
2267 AddStmt(FS->getInit());
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2271}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002272void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002273 AddStmt(If->getElse());
2274 AddStmt(If->getThen());
2275 AddStmt(If->getCond());
2276 AddDecl(If->getConditionVariable());
2277}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002278void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002279 // We care about the syntactic form of the initializer list, only.
2280 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2281 IE = Syntactic;
2282 EnqueueChildren(IE);
2283}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 WL.push_back(MemberExprParts(M, Parent));
2286
2287 // If the base of the member access expression is an implicit 'this', don't
2288 // visit it.
2289 // FIXME: If we ever want to show these implicit accesses, this will be
2290 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002291 if (M->isImplicitAccess())
2292 return;
2293
2294 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2295 // real field that that we are interested in.
2296 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2297 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2298 if (FD->isAnonymousStructOrUnion()) {
2299 AddStmt(SubME->getBase());
2300 return;
2301 }
2302 }
2303 }
2304
2305 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002306}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002307void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002308 AddTypeLoc(E->getEncodedTypeSourceInfo());
2309}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 EnqueueChildren(M);
2312 AddTypeLoc(M->getClassReceiverTypeInfo());
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 // Visit the components of the offsetof expression.
2316 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2317 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2318 const OffsetOfNode &Node = E->getComponent(I-1);
2319 switch (Node.getKind()) {
2320 case OffsetOfNode::Array:
2321 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2322 break;
2323 case OffsetOfNode::Field:
2324 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2325 break;
2326 case OffsetOfNode::Identifier:
2327 case OffsetOfNode::Base:
2328 continue;
2329 }
2330 }
2331 // Visit the type into which we're computing the offset.
2332 AddTypeLoc(E->getTypeSourceInfo());
2333}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002334void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002335 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2336 WL.push_back(OverloadExprParts(E, Parent));
2337}
2338void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002339 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002340 EnqueueChildren(E);
2341 if (E->isArgumentType())
2342 AddTypeLoc(E->getArgumentTypeInfo());
2343}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002344void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002345 EnqueueChildren(S);
2346}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002347void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002348 AddStmt(S->getBody());
2349 AddStmt(S->getCond());
2350 AddDecl(S->getConditionVariable());
2351}
2352
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002353void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002354 AddStmt(W->getBody());
2355 AddStmt(W->getCond());
2356 AddDecl(W->getConditionVariable());
2357}
2358
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002359void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002360 for (unsigned I = E->getNumArgs(); I > 0; --I)
2361 AddTypeLoc(E->getArg(I-1));
2362}
2363
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002364void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002365 AddTypeLoc(E->getQueriedTypeSourceInfo());
2366}
2367
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002369 EnqueueChildren(E);
2370}
2371
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002372void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 VisitOverloadExpr(U);
2374 if (!U->isImplicitAccess())
2375 AddStmt(U->getBase());
2376}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002377void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002378 AddStmt(E->getSubExpr());
2379 AddTypeLoc(E->getWrittenTypeInfo());
2380}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002381void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002382 WL.push_back(SizeOfPackExprParts(E, Parent));
2383}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002384void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002385 // If the opaque value has a source expression, just transparently
2386 // visit that. This is useful for (e.g.) pseudo-object expressions.
2387 if (Expr *SourceExpr = E->getSourceExpr())
2388 return Visit(SourceExpr);
2389}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002390void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002391 AddStmt(E->getBody());
2392 WL.push_back(LambdaExprParts(E, Parent));
2393}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 // Treat the expression like its syntactic form.
2396 Visit(E->getSyntacticForm());
2397}
2398
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002399void EnqueueVisitor::VisitOMPExecutableDirective(
2400 const OMPExecutableDirective *D) {
2401 EnqueueChildren(D);
2402 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2403 E = D->clauses().end();
2404 I != E; ++I)
2405 EnqueueChildren(*I);
2406}
2407
Alexander Musman3aaab662014-08-19 11:27:13 +00002408void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2409 VisitOMPExecutableDirective(D);
2410}
2411
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002412void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2413 VisitOMPExecutableDirective(D);
2414}
2415
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002416void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002417 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002418}
2419
Alexey Bataevf29276e2014-06-18 04:14:57 +00002420void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002421 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002422}
2423
Alexander Musmanf82886e2014-09-18 05:12:34 +00002424void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2425 VisitOMPLoopDirective(D);
2426}
2427
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002428void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2429 VisitOMPExecutableDirective(D);
2430}
2431
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002432void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2433 VisitOMPExecutableDirective(D);
2434}
2435
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002436void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2437 VisitOMPExecutableDirective(D);
2438}
2439
Alexander Musman80c22892014-07-17 08:54:58 +00002440void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2441 VisitOMPExecutableDirective(D);
2442}
2443
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002444void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2445 VisitOMPExecutableDirective(D);
2446 AddDeclarationNameInfo(D);
2447}
2448
Alexey Bataev4acb8592014-07-07 13:01:15 +00002449void
2450EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002451 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002452}
2453
Alexander Musmane4e893b2014-09-23 09:33:00 +00002454void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2455 const OMPParallelForSimdDirective *D) {
2456 VisitOMPLoopDirective(D);
2457}
2458
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002459void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2460 const OMPParallelSectionsDirective *D) {
2461 VisitOMPExecutableDirective(D);
2462}
2463
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002464void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2465 VisitOMPExecutableDirective(D);
2466}
2467
Alexey Bataev68446b72014-07-18 07:47:19 +00002468void
2469EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2470 VisitOMPExecutableDirective(D);
2471}
2472
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002473void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2474 VisitOMPExecutableDirective(D);
2475}
2476
Alexey Bataev2df347a2014-07-18 10:17:07 +00002477void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2478 VisitOMPExecutableDirective(D);
2479}
2480
Alexey Bataev6125da92014-07-21 11:26:11 +00002481void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2482 VisitOMPExecutableDirective(D);
2483}
2484
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002485void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2486 VisitOMPExecutableDirective(D);
2487}
2488
Alexey Bataev0162e452014-07-22 10:10:35 +00002489void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2490 VisitOMPExecutableDirective(D);
2491}
2492
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002493void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2494 VisitOMPExecutableDirective(D);
2495}
2496
Alexey Bataev13314bf2014-10-09 04:18:56 +00002497void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2498 VisitOMPExecutableDirective(D);
2499}
2500
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002501void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002502 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2503}
2504
2505bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2506 if (RegionOfInterest.isValid()) {
2507 SourceRange Range = getRawCursorExtent(C);
2508 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2509 return false;
2510 }
2511 return true;
2512}
2513
2514bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2515 while (!WL.empty()) {
2516 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002517 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002518
2519 // Set the Parent field, then back to its old value once we're done.
2520 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2521
2522 switch (LI.getKind()) {
2523 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002524 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002525 if (!D)
2526 continue;
2527
2528 // For now, perform default visitation for Decls.
2529 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2530 cast<DeclVisit>(&LI)->isFirst())))
2531 return true;
2532
2533 continue;
2534 }
2535 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2536 const ASTTemplateArgumentListInfo *ArgList =
2537 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2538 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2539 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2540 Arg != ArgEnd; ++Arg) {
2541 if (VisitTemplateArgumentLoc(*Arg))
2542 return true;
2543 }
2544 continue;
2545 }
2546 case VisitorJob::TypeLocVisitKind: {
2547 // Perform default visitation for TypeLocs.
2548 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2549 return true;
2550 continue;
2551 }
2552 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002553 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002554 if (LabelStmt *stmt = LS->getStmt()) {
2555 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2556 TU))) {
2557 return true;
2558 }
2559 }
2560 continue;
2561 }
2562
2563 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2564 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2565 if (VisitNestedNameSpecifierLoc(V->get()))
2566 return true;
2567 continue;
2568 }
2569
2570 case VisitorJob::DeclarationNameInfoVisitKind: {
2571 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2572 ->get()))
2573 return true;
2574 continue;
2575 }
2576 case VisitorJob::MemberRefVisitKind: {
2577 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2578 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2579 return true;
2580 continue;
2581 }
2582 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002583 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002584 if (!S)
2585 continue;
2586
2587 // Update the current cursor.
2588 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2589 if (!IsInRegionOfInterest(Cursor))
2590 continue;
2591 switch (Visitor(Cursor, Parent, ClientData)) {
2592 case CXChildVisit_Break: return true;
2593 case CXChildVisit_Continue: break;
2594 case CXChildVisit_Recurse:
2595 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002596 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002597 EnqueueWorkList(WL, S);
2598 break;
2599 }
2600 continue;
2601 }
2602 case VisitorJob::MemberExprPartsKind: {
2603 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002604 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002605
2606 // Visit the nested-name-specifier
2607 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2608 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2609 return true;
2610
2611 // Visit the declaration name.
2612 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2613 return true;
2614
2615 // Visit the explicitly-specified template arguments, if any.
2616 if (M->hasExplicitTemplateArgs()) {
2617 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2618 *ArgEnd = Arg + M->getNumTemplateArgs();
2619 Arg != ArgEnd; ++Arg) {
2620 if (VisitTemplateArgumentLoc(*Arg))
2621 return true;
2622 }
2623 }
2624 continue;
2625 }
2626 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002627 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002628 // Visit nested-name-specifier, if present.
2629 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2630 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2631 return true;
2632 // Visit declaration name.
2633 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2634 return true;
2635 continue;
2636 }
2637 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002638 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002639 // Visit the nested-name-specifier.
2640 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2641 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2642 return true;
2643 // Visit the declaration name.
2644 if (VisitDeclarationNameInfo(O->getNameInfo()))
2645 return true;
2646 // Visit the overloaded declaration reference.
2647 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2648 return true;
2649 continue;
2650 }
2651 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002652 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002653 NamedDecl *Pack = E->getPack();
2654 if (isa<TemplateTypeParmDecl>(Pack)) {
2655 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2656 E->getPackLoc(), TU)))
2657 return true;
2658
2659 continue;
2660 }
2661
2662 if (isa<TemplateTemplateParmDecl>(Pack)) {
2663 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2664 E->getPackLoc(), TU)))
2665 return true;
2666
2667 continue;
2668 }
2669
2670 // Non-type template parameter packs and function parameter packs are
2671 // treated like DeclRefExpr cursors.
2672 continue;
2673 }
2674
2675 case VisitorJob::LambdaExprPartsKind: {
2676 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002677 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002678 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2679 CEnd = E->explicit_capture_end();
2680 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002681 // FIXME: Lambda init-captures.
2682 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002683 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002684
Guy Benyei11169dd2012-12-18 14:30:41 +00002685 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2686 C->getLocation(),
2687 TU)))
2688 return true;
2689 }
2690
2691 // Visit parameters and return type, if present.
2692 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2693 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2694 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2695 // Visit the whole type.
2696 if (Visit(TL))
2697 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002698 } else if (FunctionProtoTypeLoc Proto =
2699 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002700 if (E->hasExplicitParameters()) {
2701 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002702 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2703 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002704 return true;
2705 } else {
2706 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002707 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002708 return true;
2709 }
2710 }
2711 }
2712 break;
2713 }
2714
2715 case VisitorJob::PostChildrenVisitKind:
2716 if (PostChildrenVisitor(Parent, ClientData))
2717 return true;
2718 break;
2719 }
2720 }
2721 return false;
2722}
2723
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002724bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002725 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002726 if (!WorkListFreeList.empty()) {
2727 WL = WorkListFreeList.back();
2728 WL->clear();
2729 WorkListFreeList.pop_back();
2730 }
2731 else {
2732 WL = new VisitorWorkList();
2733 WorkListCache.push_back(WL);
2734 }
2735 EnqueueWorkList(*WL, S);
2736 bool result = RunVisitorWorkList(*WL);
2737 WorkListFreeList.push_back(WL);
2738 return result;
2739}
2740
2741namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002742typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002743RefNamePieces
2744buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2745 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2746 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002747 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2748 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2749 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2750
2751 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2752
2753 RefNamePieces Pieces;
2754
2755 if (WantQualifier && QLoc.isValid())
2756 Pieces.push_back(QLoc);
2757
2758 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2759 Pieces.push_back(NI.getLoc());
2760
2761 if (WantTemplateArgs && TemplateArgs)
2762 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2763 TemplateArgs->RAngleLoc));
2764
2765 if (Kind == DeclarationName::CXXOperatorName) {
2766 Pieces.push_back(SourceLocation::getFromRawEncoding(
2767 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2768 Pieces.push_back(SourceLocation::getFromRawEncoding(
2769 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2770 }
2771
2772 if (WantSinglePiece) {
2773 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2774 Pieces.clear();
2775 Pieces.push_back(R);
2776 }
2777
2778 return Pieces;
2779}
2780}
2781
2782//===----------------------------------------------------------------------===//
2783// Misc. API hooks.
2784//===----------------------------------------------------------------------===//
2785
Chad Rosier05c71aa2013-03-27 18:28:23 +00002786static void fatal_error_handler(void *user_data, const std::string& reason,
2787 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 // Write the result out to stderr avoiding errs() because raw_ostreams can
2789 // call report_fatal_error.
2790 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2791 ::abort();
2792}
2793
Chandler Carruth66660742014-06-27 16:37:27 +00002794namespace {
2795struct RegisterFatalErrorHandler {
2796 RegisterFatalErrorHandler() {
2797 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2798 }
2799};
2800}
2801
2802static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2803
Guy Benyei11169dd2012-12-18 14:30:41 +00002804extern "C" {
2805CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2806 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002807 // We use crash recovery to make some of our APIs more reliable, implicitly
2808 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002809 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2810 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002811
Chandler Carruth66660742014-06-27 16:37:27 +00002812 // Look through the managed static to trigger construction of the managed
2813 // static which registers our fatal error handler. This ensures it is only
2814 // registered once.
2815 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002816
2817 CIndexer *CIdxr = new CIndexer();
2818 if (excludeDeclarationsFromPCH)
2819 CIdxr->setOnlyLocalDecls();
2820 if (displayDiagnostics)
2821 CIdxr->setDisplayDiagnostics();
2822
2823 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2824 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2825 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2826 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2827 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2828 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2829
2830 return CIdxr;
2831}
2832
2833void clang_disposeIndex(CXIndex CIdx) {
2834 if (CIdx)
2835 delete static_cast<CIndexer *>(CIdx);
2836}
2837
2838void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2839 if (CIdx)
2840 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2841}
2842
2843unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2844 if (CIdx)
2845 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2846 return 0;
2847}
2848
2849void clang_toggleCrashRecovery(unsigned isEnabled) {
2850 if (isEnabled)
2851 llvm::CrashRecoveryContext::Enable();
2852 else
2853 llvm::CrashRecoveryContext::Disable();
2854}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002855
Guy Benyei11169dd2012-12-18 14:30:41 +00002856CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2857 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002858 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002859 enum CXErrorCode Result =
2860 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002861 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002862 assert((TU && Result == CXError_Success) ||
2863 (!TU && Result != CXError_Success));
2864 return TU;
2865}
2866
2867enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2868 const char *ast_filename,
2869 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002870 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002871 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002872
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002873 if (!CIdx || !ast_filename || !out_TU)
2874 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002875
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002876 LOG_FUNC_SECTION {
2877 *Log << ast_filename;
2878 }
2879
Guy Benyei11169dd2012-12-18 14:30:41 +00002880 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2881 FileSystemOptions FileSystemOpts;
2882
Justin Bognerd512c1e2014-10-15 00:33:06 +00002883 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2884 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002885 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2886 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2887 /*CaptureDiagnostics=*/true,
2888 /*AllowPCHWithCompilerErrors=*/true,
2889 /*UserFilesAreVolatile=*/true);
2890 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002891 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002892}
2893
2894unsigned clang_defaultEditingTranslationUnitOptions() {
2895 return CXTranslationUnit_PrecompiledPreamble |
2896 CXTranslationUnit_CacheCompletionResults;
2897}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002898
Guy Benyei11169dd2012-12-18 14:30:41 +00002899CXTranslationUnit
2900clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2901 const char *source_filename,
2902 int num_command_line_args,
2903 const char * const *command_line_args,
2904 unsigned num_unsaved_files,
2905 struct CXUnsavedFile *unsaved_files) {
2906 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2907 return clang_parseTranslationUnit(CIdx, source_filename,
2908 command_line_args, num_command_line_args,
2909 unsaved_files, num_unsaved_files,
2910 Options);
2911}
2912
2913struct ParseTranslationUnitInfo {
2914 CXIndex CIdx;
2915 const char *source_filename;
2916 const char *const *command_line_args;
2917 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002918 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002919 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002920 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002921 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002922};
2923static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002924 const ParseTranslationUnitInfo *PTUI =
2925 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002926 CXIndex CIdx = PTUI->CIdx;
2927 const char *source_filename = PTUI->source_filename;
2928 const char * const *command_line_args = PTUI->command_line_args;
2929 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002930 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002931 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002932
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002933 // Set up the initial return values.
2934 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002935 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002936
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002937 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002938 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002939 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002940 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002941 }
2942
Guy Benyei11169dd2012-12-18 14:30:41 +00002943 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2944
2945 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2946 setThreadBackgroundPriority();
2947
2948 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2949 // FIXME: Add a flag for modules.
2950 TranslationUnitKind TUKind
2951 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002952 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002953 = options & CXTranslationUnit_CacheCompletionResults;
2954 bool IncludeBriefCommentsInCodeCompletion
2955 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2956 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2957 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2958
2959 // Configure the diagnostics.
2960 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002961 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002962
2963 // Recover resources if we crash before exiting this function.
2964 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2965 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002966 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002967
Ahmed Charlesb8984322014-03-07 20:03:18 +00002968 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2969 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002970
2971 // Recover resources if we crash before exiting this function.
2972 llvm::CrashRecoveryContextCleanupRegistrar<
2973 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2974
Alp Toker9d85b182014-07-07 01:23:14 +00002975 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002976 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002977 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002978 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002979 }
2980
Ahmed Charlesb8984322014-03-07 20:03:18 +00002981 std::unique_ptr<std::vector<const char *>> Args(
2982 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002983
2984 // Recover resources if we crash before exiting this method.
2985 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2986 ArgsCleanup(Args.get());
2987
2988 // Since the Clang C library is primarily used by batch tools dealing with
2989 // (often very broken) source code, where spell-checking can have a
2990 // significant negative impact on performance (particularly when
2991 // precompiled headers are involved), we disable it by default.
2992 // Only do this if we haven't found a spell-checking-related argument.
2993 bool FoundSpellCheckingArgument = false;
2994 for (int I = 0; I != num_command_line_args; ++I) {
2995 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2996 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2997 FoundSpellCheckingArgument = true;
2998 break;
2999 }
3000 }
3001 if (!FoundSpellCheckingArgument)
3002 Args->push_back("-fno-spell-checking");
3003
3004 Args->insert(Args->end(), command_line_args,
3005 command_line_args + num_command_line_args);
3006
3007 // The 'source_filename' argument is optional. If the caller does not
3008 // specify it then it is assumed that the source file is specified
3009 // in the actual argument list.
3010 // Put the source file after command_line_args otherwise if '-x' flag is
3011 // present it will be unused.
3012 if (source_filename)
3013 Args->push_back(source_filename);
3014
3015 // Do we need the detailed preprocessing record?
3016 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3017 Args->push_back("-Xclang");
3018 Args->push_back("-detailed-preprocessing-record");
3019 }
3020
3021 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003022 std::unique_ptr<ASTUnit> ErrUnit;
3023 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00003024 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003025 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3026 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3027 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3028 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3029 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3030 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003031
3032 if (NumErrors != Diags->getClient()->getNumErrors()) {
3033 // Make sure to check that 'Unit' is non-NULL.
3034 if (CXXIdx->getDisplayDiagnostics())
3035 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3036 }
3037
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003038 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3039 PTUI->result = CXError_ASTReadError;
3040 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003041 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003042 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3043 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003044}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003045
3046CXTranslationUnit
3047clang_parseTranslationUnit(CXIndex CIdx,
3048 const char *source_filename,
3049 const char *const *command_line_args,
3050 int num_command_line_args,
3051 struct CXUnsavedFile *unsaved_files,
3052 unsigned num_unsaved_files,
3053 unsigned options) {
3054 CXTranslationUnit TU;
3055 enum CXErrorCode Result = clang_parseTranslationUnit2(
3056 CIdx, source_filename, command_line_args, num_command_line_args,
3057 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003058 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003059 assert((TU && Result == CXError_Success) ||
3060 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003061 return TU;
3062}
3063
3064enum CXErrorCode clang_parseTranslationUnit2(
3065 CXIndex CIdx,
3066 const char *source_filename,
3067 const char *const *command_line_args,
3068 int num_command_line_args,
3069 struct CXUnsavedFile *unsaved_files,
3070 unsigned num_unsaved_files,
3071 unsigned options,
3072 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003073 LOG_FUNC_SECTION {
3074 *Log << source_filename << ": ";
3075 for (int i = 0; i != num_command_line_args; ++i)
3076 *Log << command_line_args[i] << " ";
3077 }
3078
Alp Toker9d85b182014-07-07 01:23:14 +00003079 if (num_unsaved_files && !unsaved_files)
3080 return CXError_InvalidArguments;
3081
Alp Toker5c532982014-07-07 22:42:03 +00003082 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003083 ParseTranslationUnitInfo PTUI = {
3084 CIdx,
3085 source_filename,
3086 command_line_args,
3087 num_command_line_args,
3088 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3089 options,
3090 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003091 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003092 llvm::CrashRecoveryContext CRC;
3093
3094 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3095 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3096 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3097 fprintf(stderr, " 'command_line_args' : [");
3098 for (int i = 0; i != num_command_line_args; ++i) {
3099 if (i)
3100 fprintf(stderr, ", ");
3101 fprintf(stderr, "'%s'", command_line_args[i]);
3102 }
3103 fprintf(stderr, "],\n");
3104 fprintf(stderr, " 'unsaved_files' : [");
3105 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3106 if (i)
3107 fprintf(stderr, ", ");
3108 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3109 unsaved_files[i].Length);
3110 }
3111 fprintf(stderr, "],\n");
3112 fprintf(stderr, " 'options' : %d,\n", options);
3113 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003114
3115 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003116 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003117 if (CXTranslationUnit *TU = PTUI.out_TU)
3118 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003119 }
Alp Toker5c532982014-07-07 22:42:03 +00003120
3121 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003122}
3123
3124unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3125 return CXSaveTranslationUnit_None;
3126}
3127
3128namespace {
3129
3130struct SaveTranslationUnitInfo {
3131 CXTranslationUnit TU;
3132 const char *FileName;
3133 unsigned options;
3134 CXSaveError result;
3135};
3136
3137}
3138
3139static void clang_saveTranslationUnit_Impl(void *UserData) {
3140 SaveTranslationUnitInfo *STUI =
3141 static_cast<SaveTranslationUnitInfo*>(UserData);
3142
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003143 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003144 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3145 setThreadBackgroundPriority();
3146
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003147 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003148 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3149}
3150
3151int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3152 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003153 LOG_FUNC_SECTION {
3154 *Log << TU << ' ' << FileName;
3155 }
3156
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003157 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003158 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003160 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003161
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003162 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3164 if (!CXXUnit->hasSema())
3165 return CXSaveError_InvalidTU;
3166
3167 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3168
3169 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3170 getenv("LIBCLANG_NOTHREADS")) {
3171 clang_saveTranslationUnit_Impl(&STUI);
3172
3173 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3174 PrintLibclangResourceUsage(TU);
3175
3176 return STUI.result;
3177 }
3178
3179 // We have an AST that has invalid nodes due to compiler errors.
3180 // Use a crash recovery thread for protection.
3181
3182 llvm::CrashRecoveryContext CRC;
3183
3184 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3185 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3186 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3187 fprintf(stderr, " 'options' : %d,\n", options);
3188 fprintf(stderr, "}\n");
3189
3190 return CXSaveError_Unknown;
3191
3192 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3193 PrintLibclangResourceUsage(TU);
3194 }
3195
3196 return STUI.result;
3197}
3198
3199void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3200 if (CTUnit) {
3201 // If the translation unit has been marked as unsafe to free, just discard
3202 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003203 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3204 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 return;
3206
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003207 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003208 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3210 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003211 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 delete CTUnit;
3213 }
3214}
3215
3216unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3217 return CXReparse_None;
3218}
3219
3220struct ReparseTranslationUnitInfo {
3221 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003222 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003224 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003225};
3226
3227static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003228 const ReparseTranslationUnitInfo *RTUI =
3229 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003230 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003231 unsigned options = RTUI->options;
3232 (void) options;
3233
3234 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003235 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003236 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003237 RTUI->result = CXError_InvalidArguments;
3238 return;
3239 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003240
3241 // Reset the associated diagnostics.
3242 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003243 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003244
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003245 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003246 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3247 setThreadBackgroundPriority();
3248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003249 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003250 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003251
3252 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3253 new std::vector<ASTUnit::RemappedFile>());
3254
Guy Benyei11169dd2012-12-18 14:30:41 +00003255 // Recover resources if we crash before exiting this function.
3256 llvm::CrashRecoveryContextCleanupRegistrar<
3257 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003258
3259 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003260 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003261 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003262 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003264
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003265 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003266 RTUI->result = CXError_Success;
3267 else if (isASTReadError(CXXUnit))
3268 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003269}
3270
3271int clang_reparseTranslationUnit(CXTranslationUnit TU,
3272 unsigned num_unsaved_files,
3273 struct CXUnsavedFile *unsaved_files,
3274 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003275 LOG_FUNC_SECTION {
3276 *Log << TU;
3277 }
3278
Alp Toker9d85b182014-07-07 01:23:14 +00003279 if (num_unsaved_files && !unsaved_files)
3280 return CXError_InvalidArguments;
3281
Alp Toker5c532982014-07-07 22:42:03 +00003282 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003283 ReparseTranslationUnitInfo RTUI = {
3284 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003285 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003286
3287 if (getenv("LIBCLANG_NOTHREADS")) {
3288 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003289 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 }
3291
3292 llvm::CrashRecoveryContext CRC;
3293
3294 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3295 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003296 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003297 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3299 PrintLibclangResourceUsage(TU);
3300
Alp Toker5c532982014-07-07 22:42:03 +00003301 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003302}
3303
3304
3305CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003306 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003307 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003308 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003309 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003310
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003311 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003312 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003313}
3314
3315CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003316 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003317 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003318 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003319 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003320
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003321 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3323}
3324
3325} // end: extern "C"
3326
3327//===----------------------------------------------------------------------===//
3328// CXFile Operations.
3329//===----------------------------------------------------------------------===//
3330
3331extern "C" {
3332CXString clang_getFileName(CXFile SFile) {
3333 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003334 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003335
3336 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003337 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003338}
3339
3340time_t clang_getFileTime(CXFile SFile) {
3341 if (!SFile)
3342 return 0;
3343
3344 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3345 return FEnt->getModificationTime();
3346}
3347
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003348CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003349 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003350 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003351 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003352 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003353
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003354 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003355
3356 FileManager &FMgr = CXXUnit->getFileManager();
3357 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3358}
3359
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003360unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3361 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003362 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003363 LOG_BAD_TU(TU);
3364 return 0;
3365 }
3366
3367 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 return 0;
3369
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003370 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 FileEntry *FEnt = static_cast<FileEntry *>(file);
3372 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3373 .isFileMultipleIncludeGuarded(FEnt);
3374}
3375
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003376int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3377 if (!file || !outID)
3378 return 1;
3379
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003380 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003381 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3382 outID->data[0] = ID.getDevice();
3383 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003384 outID->data[2] = FEnt->getModificationTime();
3385 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003386}
3387
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003388int clang_File_isEqual(CXFile file1, CXFile file2) {
3389 if (file1 == file2)
3390 return true;
3391
3392 if (!file1 || !file2)
3393 return false;
3394
3395 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3396 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3397 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3398}
3399
Guy Benyei11169dd2012-12-18 14:30:41 +00003400} // end: extern "C"
3401
3402//===----------------------------------------------------------------------===//
3403// CXCursor Operations.
3404//===----------------------------------------------------------------------===//
3405
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003406static const Decl *getDeclFromExpr(const Stmt *E) {
3407 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 return getDeclFromExpr(CE->getSubExpr());
3409
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003410 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003412 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003414 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003416 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 if (PRE->isExplicitProperty())
3418 return PRE->getExplicitProperty();
3419 // It could be messaging both getter and setter as in:
3420 // ++myobj.myprop;
3421 // in which case prefer to associate the setter since it is less obvious
3422 // from inspecting the source that the setter is going to get called.
3423 if (PRE->isMessagingSetter())
3424 return PRE->getImplicitPropertySetter();
3425 return PRE->getImplicitPropertyGetter();
3426 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003427 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003428 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003429 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003430 if (Expr *Src = OVE->getSourceExpr())
3431 return getDeclFromExpr(Src);
3432
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003433 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003435 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 if (!CE->isElidable())
3437 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003438 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 return OME->getMethodDecl();
3440
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003441 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003443 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003444 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3445 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003446 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003447 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3448 isa<ParmVarDecl>(SizeOfPack->getPack()))
3449 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003450
3451 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003452}
3453
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003454static SourceLocation getLocationFromExpr(const Expr *E) {
3455 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 return getLocationFromExpr(CE->getSubExpr());
3457
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003458 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003460 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003461 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003462 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003464 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003466 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003467 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003468 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 return PropRef->getLocation();
3470
3471 return E->getLocStart();
3472}
3473
3474extern "C" {
3475
3476unsigned clang_visitChildren(CXCursor parent,
3477 CXCursorVisitor visitor,
3478 CXClientData client_data) {
3479 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3480 /*VisitPreprocessorLast=*/false);
3481 return CursorVis.VisitChildren(parent);
3482}
3483
3484#ifndef __has_feature
3485#define __has_feature(x) 0
3486#endif
3487#if __has_feature(blocks)
3488typedef enum CXChildVisitResult
3489 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3490
3491static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3492 CXClientData client_data) {
3493 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3494 return block(cursor, parent);
3495}
3496#else
3497// If we are compiled with a compiler that doesn't have native blocks support,
3498// define and call the block manually, so the
3499typedef struct _CXChildVisitResult
3500{
3501 void *isa;
3502 int flags;
3503 int reserved;
3504 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3505 CXCursor);
3506} *CXCursorVisitorBlock;
3507
3508static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3509 CXClientData client_data) {
3510 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3511 return block->invoke(block, cursor, parent);
3512}
3513#endif
3514
3515
3516unsigned clang_visitChildrenWithBlock(CXCursor parent,
3517 CXCursorVisitorBlock block) {
3518 return clang_visitChildren(parent, visitWithBlock, block);
3519}
3520
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003521static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003523 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003524
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003525 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003527 if (const ObjCPropertyImplDecl *PropImpl =
3528 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003530 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003531
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003532 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003534 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003535
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003536 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 }
3538
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003539 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003540 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003541
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003542 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3544 // and returns different names. NamedDecl returns the class name and
3545 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003546 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003547
3548 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003549 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003550
3551 SmallString<1024> S;
3552 llvm::raw_svector_ostream os(S);
3553 ND->printName(os);
3554
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003555 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003556}
3557
3558CXString clang_getCursorSpelling(CXCursor C) {
3559 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003560 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003561
3562 if (clang_isReference(C.kind)) {
3563 switch (C.kind) {
3564 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003565 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003566 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 }
3568 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003569 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003570 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 }
3572 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003573 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003575 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 }
3577 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003578 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003579 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 }
3581 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003582 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 assert(Type && "Missing type decl");
3584
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003585 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 getAsString());
3587 }
3588 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003589 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 assert(Template && "Missing template decl");
3591
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003592 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 }
3594
3595 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003596 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 assert(NS && "Missing namespace decl");
3598
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003599 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 }
3601
3602 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003603 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 assert(Field && "Missing member decl");
3605
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003606 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 }
3608
3609 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003610 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 assert(Label && "Missing label");
3612
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003613 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 }
3615
3616 case CXCursor_OverloadedDeclRef: {
3617 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003618 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3619 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003620 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003621 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003623 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003624 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 OverloadedTemplateStorage *Ovl
3626 = Storage.get<OverloadedTemplateStorage*>();
3627 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003628 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003629 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 }
3631
3632 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003633 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 assert(Var && "Missing variable decl");
3635
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003636 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 }
3638
3639 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 }
3642 }
3643
3644 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003645 const Expr *E = getCursorExpr(C);
3646
3647 if (C.kind == CXCursor_ObjCStringLiteral ||
3648 C.kind == CXCursor_StringLiteral) {
3649 const StringLiteral *SLit;
3650 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3651 SLit = OSL->getString();
3652 } else {
3653 SLit = cast<StringLiteral>(E);
3654 }
3655 SmallString<256> Buf;
3656 llvm::raw_svector_ostream OS(Buf);
3657 SLit->outputString(OS);
3658 return cxstring::createDup(OS.str());
3659 }
3660
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003661 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 if (D)
3663 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003664 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 }
3666
3667 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003668 const Stmt *S = getCursorStmt(C);
3669 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003671
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003672 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 }
3674
3675 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 ->getNameStart());
3678
3679 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 ->getNameStart());
3682
3683 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003684 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003685
3686 if (clang_isDeclaration(C.kind))
3687 return getDeclSpelling(getCursorDecl(C));
3688
3689 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003690 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003691 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 }
3693
3694 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003695 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003696 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 }
3698
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003699 if (C.kind == CXCursor_PackedAttr) {
3700 return cxstring::createRef("packed");
3701 }
3702
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003703 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003704}
3705
3706CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3707 unsigned pieceIndex,
3708 unsigned options) {
3709 if (clang_Cursor_isNull(C))
3710 return clang_getNullRange();
3711
3712 ASTContext &Ctx = getCursorContext(C);
3713
3714 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003715 const Stmt *S = getCursorStmt(C);
3716 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 if (pieceIndex > 0)
3718 return clang_getNullRange();
3719 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3720 }
3721
3722 return clang_getNullRange();
3723 }
3724
3725 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003726 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3728 if (pieceIndex >= ME->getNumSelectorLocs())
3729 return clang_getNullRange();
3730 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3731 }
3732 }
3733
3734 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3735 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003736 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3738 if (pieceIndex >= MD->getNumSelectorLocs())
3739 return clang_getNullRange();
3740 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3741 }
3742 }
3743
3744 if (C.kind == CXCursor_ObjCCategoryDecl ||
3745 C.kind == CXCursor_ObjCCategoryImplDecl) {
3746 if (pieceIndex > 0)
3747 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003748 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3750 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003751 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3753 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3754 }
3755
3756 if (C.kind == CXCursor_ModuleImportDecl) {
3757 if (pieceIndex > 0)
3758 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003759 if (const ImportDecl *ImportD =
3760 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3762 if (!Locs.empty())
3763 return cxloc::translateSourceRange(Ctx,
3764 SourceRange(Locs.front(), Locs.back()));
3765 }
3766 return clang_getNullRange();
3767 }
3768
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003769 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3770 C.kind == CXCursor_ConversionFunction) {
3771 if (pieceIndex > 0)
3772 return clang_getNullRange();
3773 if (const FunctionDecl *FD =
3774 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3775 DeclarationNameInfo FunctionName = FD->getNameInfo();
3776 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3777 }
3778 return clang_getNullRange();
3779 }
3780
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 // FIXME: A CXCursor_InclusionDirective should give the location of the
3782 // filename, but we don't keep track of this.
3783
3784 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3785 // but we don't keep track of this.
3786
3787 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3788 // but we don't keep track of this.
3789
3790 // Default handling, give the location of the cursor.
3791
3792 if (pieceIndex > 0)
3793 return clang_getNullRange();
3794
3795 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3796 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3797 return cxloc::translateSourceRange(Ctx, Loc);
3798}
3799
Eli Bendersky44a206f2014-07-31 18:04:56 +00003800CXString clang_Cursor_getMangling(CXCursor C) {
3801 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3802 return cxstring::createEmpty();
3803
Eli Bendersky44a206f2014-07-31 18:04:56 +00003804 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003805 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003806 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3807 return cxstring::createEmpty();
3808
Eli Bendersky79759592014-08-01 15:01:10 +00003809 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003810 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003811 ASTContext &Ctx = ND->getASTContext();
3812 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003813
Eli Bendersky79759592014-08-01 15:01:10 +00003814 std::string FrontendBuf;
3815 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3816 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003817
Eli Bendersky79759592014-08-01 15:01:10 +00003818 // Now apply backend mangling.
3819 std::unique_ptr<llvm::DataLayout> DL(
3820 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3821 llvm::Mangler BackendMangler(DL.get());
3822
3823 std::string FinalBuf;
3824 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3825 BackendMangler.getNameWithPrefix(FinalBufOS,
3826 llvm::Twine(FrontendBufOS.str()));
3827
3828 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003829}
3830
Guy Benyei11169dd2012-12-18 14:30:41 +00003831CXString clang_getCursorDisplayName(CXCursor C) {
3832 if (!clang_isDeclaration(C.kind))
3833 return clang_getCursorSpelling(C);
3834
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003835 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003837 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003838
3839 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003840 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 D = FunTmpl->getTemplatedDecl();
3842
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003843 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 SmallString<64> Str;
3845 llvm::raw_svector_ostream OS(Str);
3846 OS << *Function;
3847 if (Function->getPrimaryTemplate())
3848 OS << "<>";
3849 OS << "(";
3850 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3851 if (I)
3852 OS << ", ";
3853 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3854 }
3855
3856 if (Function->isVariadic()) {
3857 if (Function->getNumParams())
3858 OS << ", ";
3859 OS << "...";
3860 }
3861 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003862 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 }
3864
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003865 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 SmallString<64> Str;
3867 llvm::raw_svector_ostream OS(Str);
3868 OS << *ClassTemplate;
3869 OS << "<";
3870 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3871 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3872 if (I)
3873 OS << ", ";
3874
3875 NamedDecl *Param = Params->getParam(I);
3876 if (Param->getIdentifier()) {
3877 OS << Param->getIdentifier()->getName();
3878 continue;
3879 }
3880
3881 // There is no parameter name, which makes this tricky. Try to come up
3882 // with something useful that isn't too long.
3883 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3884 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3885 else if (NonTypeTemplateParmDecl *NTTP
3886 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3887 OS << NTTP->getType().getAsString(Policy);
3888 else
3889 OS << "template<...> class";
3890 }
3891
3892 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003893 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 }
3895
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003896 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3898 // If the type was explicitly written, use that.
3899 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003900 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003901
Benjamin Kramer9170e912013-02-22 15:46:01 +00003902 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 llvm::raw_svector_ostream OS(Str);
3904 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003905 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 ClassSpec->getTemplateArgs().data(),
3907 ClassSpec->getTemplateArgs().size(),
3908 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003909 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 }
3911
3912 return clang_getCursorSpelling(C);
3913}
3914
3915CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3916 switch (Kind) {
3917 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004045 case CXCursor_ObjCSelfExpr:
4046 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004135 case CXCursor_SEHLeaveStmt:
4136 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004165 case CXCursor_PackedAttr:
4166 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004167 case CXCursor_PureAttr:
4168 return cxstring::createRef("attribute(pure)");
4169 case CXCursor_ConstAttr:
4170 return cxstring::createRef("attribute(const)");
4171 case CXCursor_NoDuplicateAttr:
4172 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004173 case CXCursor_CUDAConstantAttr:
4174 return cxstring::createRef("attribute(constant)");
4175 case CXCursor_CUDADeviceAttr:
4176 return cxstring::createRef("attribute(device)");
4177 case CXCursor_CUDAGlobalAttr:
4178 return cxstring::createRef("attribute(global)");
4179 case CXCursor_CUDAHostAttr:
4180 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004181 case CXCursor_CUDASharedAttr:
4182 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004218 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004220 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004222 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004224 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004226 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004230 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004231 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004232 return cxstring::createRef("OMPParallelDirective");
4233 case CXCursor_OMPSimdDirective:
4234 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004235 case CXCursor_OMPForDirective:
4236 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004237 case CXCursor_OMPForSimdDirective:
4238 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004239 case CXCursor_OMPSectionsDirective:
4240 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004241 case CXCursor_OMPSectionDirective:
4242 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004243 case CXCursor_OMPSingleDirective:
4244 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004245 case CXCursor_OMPMasterDirective:
4246 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004247 case CXCursor_OMPCriticalDirective:
4248 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004249 case CXCursor_OMPParallelForDirective:
4250 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004251 case CXCursor_OMPParallelForSimdDirective:
4252 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004253 case CXCursor_OMPParallelSectionsDirective:
4254 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004255 case CXCursor_OMPTaskDirective:
4256 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004257 case CXCursor_OMPTaskyieldDirective:
4258 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004259 case CXCursor_OMPBarrierDirective:
4260 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004261 case CXCursor_OMPTaskwaitDirective:
4262 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004263 case CXCursor_OMPFlushDirective:
4264 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004265 case CXCursor_OMPOrderedDirective:
4266 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004267 case CXCursor_OMPAtomicDirective:
4268 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004269 case CXCursor_OMPTargetDirective:
4270 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004271 case CXCursor_OMPTeamsDirective:
4272 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004273 case CXCursor_OverloadCandidate:
4274 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 }
4276
4277 llvm_unreachable("Unhandled CXCursorKind");
4278}
4279
4280struct GetCursorData {
4281 SourceLocation TokenBeginLoc;
4282 bool PointsAtMacroArgExpansion;
4283 bool VisitedObjCPropertyImplDecl;
4284 SourceLocation VisitedDeclaratorDeclStartLoc;
4285 CXCursor &BestCursor;
4286
4287 GetCursorData(SourceManager &SM,
4288 SourceLocation tokenBegin, CXCursor &outputCursor)
4289 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4290 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4291 VisitedObjCPropertyImplDecl = false;
4292 }
4293};
4294
4295static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4296 CXCursor parent,
4297 CXClientData client_data) {
4298 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4299 CXCursor *BestCursor = &Data->BestCursor;
4300
4301 // If we point inside a macro argument we should provide info of what the
4302 // token is so use the actual cursor, don't replace it with a macro expansion
4303 // cursor.
4304 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4305 return CXChildVisit_Recurse;
4306
4307 if (clang_isDeclaration(cursor.kind)) {
4308 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004309 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4311 if (MD->isImplicit())
4312 return CXChildVisit_Break;
4313
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004314 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4316 // Check that when we have multiple @class references in the same line,
4317 // that later ones do not override the previous ones.
4318 // If we have:
4319 // @class Foo, Bar;
4320 // source ranges for both start at '@', so 'Bar' will end up overriding
4321 // 'Foo' even though the cursor location was at 'Foo'.
4322 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4323 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004324 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004325 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4326 if (PrevID != ID &&
4327 !PrevID->isThisDeclarationADefinition() &&
4328 !ID->isThisDeclarationADefinition())
4329 return CXChildVisit_Break;
4330 }
4331
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004332 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4334 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4335 // Check that when we have multiple declarators in the same line,
4336 // that later ones do not override the previous ones.
4337 // If we have:
4338 // int Foo, Bar;
4339 // source ranges for both start at 'int', so 'Bar' will end up overriding
4340 // 'Foo' even though the cursor location was at 'Foo'.
4341 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4342 return CXChildVisit_Break;
4343 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4344
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004345 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004346 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4347 (void)PropImp;
4348 // Check that when we have multiple @synthesize in the same line,
4349 // that later ones do not override the previous ones.
4350 // If we have:
4351 // @synthesize Foo, Bar;
4352 // source ranges for both start at '@', so 'Bar' will end up overriding
4353 // 'Foo' even though the cursor location was at 'Foo'.
4354 if (Data->VisitedObjCPropertyImplDecl)
4355 return CXChildVisit_Break;
4356 Data->VisitedObjCPropertyImplDecl = true;
4357 }
4358 }
4359
4360 if (clang_isExpression(cursor.kind) &&
4361 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004362 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 // Avoid having the cursor of an expression replace the declaration cursor
4364 // when the expression source range overlaps the declaration range.
4365 // This can happen for C++ constructor expressions whose range generally
4366 // include the variable declaration, e.g.:
4367 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4368 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4369 D->getLocation() == Data->TokenBeginLoc)
4370 return CXChildVisit_Break;
4371 }
4372 }
4373
4374 // If our current best cursor is the construction of a temporary object,
4375 // don't replace that cursor with a type reference, because we want
4376 // clang_getCursor() to point at the constructor.
4377 if (clang_isExpression(BestCursor->kind) &&
4378 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4379 cursor.kind == CXCursor_TypeRef) {
4380 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4381 // as having the actual point on the type reference.
4382 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4383 return CXChildVisit_Recurse;
4384 }
4385
4386 *BestCursor = cursor;
4387 return CXChildVisit_Recurse;
4388}
4389
4390CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004391 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004392 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004394 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004395
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004396 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004397 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4398
4399 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4400 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4401
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004402 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 CXFile SearchFile;
4404 unsigned SearchLine, SearchColumn;
4405 CXFile ResultFile;
4406 unsigned ResultLine, ResultColumn;
4407 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4408 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4409 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004410
4411 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4412 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004413 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004414 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 SearchFileName = clang_getFileName(SearchFile);
4416 ResultFileName = clang_getFileName(ResultFile);
4417 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4418 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004419 *Log << llvm::format("(%s:%d:%d) = %s",
4420 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4421 clang_getCString(KindSpelling))
4422 << llvm::format("(%s:%d:%d):%s%s",
4423 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4424 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004425 clang_disposeString(SearchFileName);
4426 clang_disposeString(ResultFileName);
4427 clang_disposeString(KindSpelling);
4428 clang_disposeString(USR);
4429
4430 CXCursor Definition = clang_getCursorDefinition(Result);
4431 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4432 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4433 CXString DefinitionKindSpelling
4434 = clang_getCursorKindSpelling(Definition.kind);
4435 CXFile DefinitionFile;
4436 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004437 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004438 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004440 *Log << llvm::format(" -> %s(%s:%d:%d)",
4441 clang_getCString(DefinitionKindSpelling),
4442 clang_getCString(DefinitionFileName),
4443 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 clang_disposeString(DefinitionFileName);
4445 clang_disposeString(DefinitionKindSpelling);
4446 }
4447 }
4448
4449 return Result;
4450}
4451
4452CXCursor clang_getNullCursor(void) {
4453 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4454}
4455
4456unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004457 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4458 // can't set consistently. For example, when visiting a DeclStmt we will set
4459 // it but we don't set it on the result of clang_getCursorDefinition for
4460 // a reference of the same declaration.
4461 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4462 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4463 // to provide that kind of info.
4464 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004465 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004466 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004467 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004468
Guy Benyei11169dd2012-12-18 14:30:41 +00004469 return X == Y;
4470}
4471
4472unsigned clang_hashCursor(CXCursor C) {
4473 unsigned Index = 0;
4474 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4475 Index = 1;
4476
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004477 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004478 std::make_pair(C.kind, C.data[Index]));
4479}
4480
4481unsigned clang_isInvalid(enum CXCursorKind K) {
4482 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4483}
4484
4485unsigned clang_isDeclaration(enum CXCursorKind K) {
4486 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4487 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4488}
4489
4490unsigned clang_isReference(enum CXCursorKind K) {
4491 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4492}
4493
4494unsigned clang_isExpression(enum CXCursorKind K) {
4495 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4496}
4497
4498unsigned clang_isStatement(enum CXCursorKind K) {
4499 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4500}
4501
4502unsigned clang_isAttribute(enum CXCursorKind K) {
4503 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4504}
4505
4506unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4507 return K == CXCursor_TranslationUnit;
4508}
4509
4510unsigned clang_isPreprocessing(enum CXCursorKind K) {
4511 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4512}
4513
4514unsigned clang_isUnexposed(enum CXCursorKind K) {
4515 switch (K) {
4516 case CXCursor_UnexposedDecl:
4517 case CXCursor_UnexposedExpr:
4518 case CXCursor_UnexposedStmt:
4519 case CXCursor_UnexposedAttr:
4520 return true;
4521 default:
4522 return false;
4523 }
4524}
4525
4526CXCursorKind clang_getCursorKind(CXCursor C) {
4527 return C.kind;
4528}
4529
4530CXSourceLocation clang_getCursorLocation(CXCursor C) {
4531 if (clang_isReference(C.kind)) {
4532 switch (C.kind) {
4533 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004534 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 = getCursorObjCSuperClassRef(C);
4536 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4537 }
4538
4539 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004540 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 = getCursorObjCProtocolRef(C);
4542 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4543 }
4544
4545 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004546 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 = getCursorObjCClassRef(C);
4548 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4549 }
4550
4551 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004552 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4554 }
4555
4556 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004557 std::pair<const TemplateDecl *, SourceLocation> P =
4558 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4560 }
4561
4562 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004563 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4565 }
4566
4567 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004568 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4570 }
4571
4572 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004573 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004574 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4575 }
4576
4577 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004578 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 if (!BaseSpec)
4580 return clang_getNullLocation();
4581
4582 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4583 return cxloc::translateSourceLocation(getCursorContext(C),
4584 TSInfo->getTypeLoc().getBeginLoc());
4585
4586 return cxloc::translateSourceLocation(getCursorContext(C),
4587 BaseSpec->getLocStart());
4588 }
4589
4590 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004591 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4593 }
4594
4595 case CXCursor_OverloadedDeclRef:
4596 return cxloc::translateSourceLocation(getCursorContext(C),
4597 getCursorOverloadedDeclRef(C).second);
4598
4599 default:
4600 // FIXME: Need a way to enumerate all non-reference cases.
4601 llvm_unreachable("Missed a reference kind");
4602 }
4603 }
4604
4605 if (clang_isExpression(C.kind))
4606 return cxloc::translateSourceLocation(getCursorContext(C),
4607 getLocationFromExpr(getCursorExpr(C)));
4608
4609 if (clang_isStatement(C.kind))
4610 return cxloc::translateSourceLocation(getCursorContext(C),
4611 getCursorStmt(C)->getLocStart());
4612
4613 if (C.kind == CXCursor_PreprocessingDirective) {
4614 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4615 return cxloc::translateSourceLocation(getCursorContext(C), L);
4616 }
4617
4618 if (C.kind == CXCursor_MacroExpansion) {
4619 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004620 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 return cxloc::translateSourceLocation(getCursorContext(C), L);
4622 }
4623
4624 if (C.kind == CXCursor_MacroDefinition) {
4625 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4626 return cxloc::translateSourceLocation(getCursorContext(C), L);
4627 }
4628
4629 if (C.kind == CXCursor_InclusionDirective) {
4630 SourceLocation L
4631 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4632 return cxloc::translateSourceLocation(getCursorContext(C), L);
4633 }
4634
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004635 if (clang_isAttribute(C.kind)) {
4636 SourceLocation L
4637 = cxcursor::getCursorAttr(C)->getLocation();
4638 return cxloc::translateSourceLocation(getCursorContext(C), L);
4639 }
4640
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 if (!clang_isDeclaration(C.kind))
4642 return clang_getNullLocation();
4643
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004644 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 if (!D)
4646 return clang_getNullLocation();
4647
4648 SourceLocation Loc = D->getLocation();
4649 // FIXME: Multiple variables declared in a single declaration
4650 // currently lack the information needed to correctly determine their
4651 // ranges when accounting for the type-specifier. We use context
4652 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4653 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004654 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 if (!cxcursor::isFirstInDeclGroup(C))
4656 Loc = VD->getLocation();
4657 }
4658
4659 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004660 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 Loc = MD->getSelectorStartLoc();
4662
4663 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4664}
4665
4666} // end extern "C"
4667
4668CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4669 assert(TU);
4670
4671 // Guard against an invalid SourceLocation, or we may assert in one
4672 // of the following calls.
4673 if (SLoc.isInvalid())
4674 return clang_getNullCursor();
4675
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004676 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004677
4678 // Translate the given source location to make it point at the beginning of
4679 // the token under the cursor.
4680 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4681 CXXUnit->getASTContext().getLangOpts());
4682
4683 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4684 if (SLoc.isValid()) {
4685 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4686 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4687 /*VisitPreprocessorLast=*/true,
4688 /*VisitIncludedEntities=*/false,
4689 SourceLocation(SLoc));
4690 CursorVis.visitFileRegion();
4691 }
4692
4693 return Result;
4694}
4695
4696static SourceRange getRawCursorExtent(CXCursor C) {
4697 if (clang_isReference(C.kind)) {
4698 switch (C.kind) {
4699 case CXCursor_ObjCSuperClassRef:
4700 return getCursorObjCSuperClassRef(C).second;
4701
4702 case CXCursor_ObjCProtocolRef:
4703 return getCursorObjCProtocolRef(C).second;
4704
4705 case CXCursor_ObjCClassRef:
4706 return getCursorObjCClassRef(C).second;
4707
4708 case CXCursor_TypeRef:
4709 return getCursorTypeRef(C).second;
4710
4711 case CXCursor_TemplateRef:
4712 return getCursorTemplateRef(C).second;
4713
4714 case CXCursor_NamespaceRef:
4715 return getCursorNamespaceRef(C).second;
4716
4717 case CXCursor_MemberRef:
4718 return getCursorMemberRef(C).second;
4719
4720 case CXCursor_CXXBaseSpecifier:
4721 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4722
4723 case CXCursor_LabelRef:
4724 return getCursorLabelRef(C).second;
4725
4726 case CXCursor_OverloadedDeclRef:
4727 return getCursorOverloadedDeclRef(C).second;
4728
4729 case CXCursor_VariableRef:
4730 return getCursorVariableRef(C).second;
4731
4732 default:
4733 // FIXME: Need a way to enumerate all non-reference cases.
4734 llvm_unreachable("Missed a reference kind");
4735 }
4736 }
4737
4738 if (clang_isExpression(C.kind))
4739 return getCursorExpr(C)->getSourceRange();
4740
4741 if (clang_isStatement(C.kind))
4742 return getCursorStmt(C)->getSourceRange();
4743
4744 if (clang_isAttribute(C.kind))
4745 return getCursorAttr(C)->getRange();
4746
4747 if (C.kind == CXCursor_PreprocessingDirective)
4748 return cxcursor::getCursorPreprocessingDirective(C);
4749
4750 if (C.kind == CXCursor_MacroExpansion) {
4751 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004752 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 return TU->mapRangeFromPreamble(Range);
4754 }
4755
4756 if (C.kind == CXCursor_MacroDefinition) {
4757 ASTUnit *TU = getCursorASTUnit(C);
4758 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4759 return TU->mapRangeFromPreamble(Range);
4760 }
4761
4762 if (C.kind == CXCursor_InclusionDirective) {
4763 ASTUnit *TU = getCursorASTUnit(C);
4764 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4765 return TU->mapRangeFromPreamble(Range);
4766 }
4767
4768 if (C.kind == CXCursor_TranslationUnit) {
4769 ASTUnit *TU = getCursorASTUnit(C);
4770 FileID MainID = TU->getSourceManager().getMainFileID();
4771 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4772 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4773 return SourceRange(Start, End);
4774 }
4775
4776 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004777 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004778 if (!D)
4779 return SourceRange();
4780
4781 SourceRange R = D->getSourceRange();
4782 // FIXME: Multiple variables declared in a single declaration
4783 // currently lack the information needed to correctly determine their
4784 // ranges when accounting for the type-specifier. We use context
4785 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4786 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004787 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004788 if (!cxcursor::isFirstInDeclGroup(C))
4789 R.setBegin(VD->getLocation());
4790 }
4791 return R;
4792 }
4793 return SourceRange();
4794}
4795
4796/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4797/// the decl-specifier-seq for declarations.
4798static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4799 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004800 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 if (!D)
4802 return SourceRange();
4803
4804 SourceRange R = D->getSourceRange();
4805
4806 // Adjust the start of the location for declarations preceded by
4807 // declaration specifiers.
4808 SourceLocation StartLoc;
4809 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4810 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4811 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004812 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4814 StartLoc = TI->getTypeLoc().getLocStart();
4815 }
4816
4817 if (StartLoc.isValid() && R.getBegin().isValid() &&
4818 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4819 R.setBegin(StartLoc);
4820
4821 // FIXME: Multiple variables declared in a single declaration
4822 // currently lack the information needed to correctly determine their
4823 // ranges when accounting for the type-specifier. We use context
4824 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4825 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004826 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004827 if (!cxcursor::isFirstInDeclGroup(C))
4828 R.setBegin(VD->getLocation());
4829 }
4830
4831 return R;
4832 }
4833
4834 return getRawCursorExtent(C);
4835}
4836
4837extern "C" {
4838
4839CXSourceRange clang_getCursorExtent(CXCursor C) {
4840 SourceRange R = getRawCursorExtent(C);
4841 if (R.isInvalid())
4842 return clang_getNullRange();
4843
4844 return cxloc::translateSourceRange(getCursorContext(C), R);
4845}
4846
4847CXCursor clang_getCursorReferenced(CXCursor C) {
4848 if (clang_isInvalid(C.kind))
4849 return clang_getNullCursor();
4850
4851 CXTranslationUnit tu = getCursorTU(C);
4852 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004853 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004854 if (!D)
4855 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004856 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004858 if (const ObjCPropertyImplDecl *PropImpl =
4859 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004860 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4861 return MakeCXCursor(Property, tu);
4862
4863 return C;
4864 }
4865
4866 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004867 const Expr *E = getCursorExpr(C);
4868 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 if (D) {
4870 CXCursor declCursor = MakeCXCursor(D, tu);
4871 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4872 declCursor);
4873 return declCursor;
4874 }
4875
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004876 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 return MakeCursorOverloadedDeclRef(Ovl, tu);
4878
4879 return clang_getNullCursor();
4880 }
4881
4882 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004883 const Stmt *S = getCursorStmt(C);
4884 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 if (LabelDecl *label = Goto->getLabel())
4886 if (LabelStmt *labelS = label->getStmt())
4887 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4888
4889 return clang_getNullCursor();
4890 }
Richard Smith66a81862015-05-04 02:25:31 +00004891
Guy Benyei11169dd2012-12-18 14:30:41 +00004892 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004893 if (const MacroDefinitionRecord *Def =
4894 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004895 return MakeMacroDefinitionCursor(Def, tu);
4896 }
4897
4898 if (!clang_isReference(C.kind))
4899 return clang_getNullCursor();
4900
4901 switch (C.kind) {
4902 case CXCursor_ObjCSuperClassRef:
4903 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4904
4905 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004906 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4907 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004908 return MakeCXCursor(Def, tu);
4909
4910 return MakeCXCursor(Prot, tu);
4911 }
4912
4913 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004914 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4915 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004916 return MakeCXCursor(Def, tu);
4917
4918 return MakeCXCursor(Class, tu);
4919 }
4920
4921 case CXCursor_TypeRef:
4922 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4923
4924 case CXCursor_TemplateRef:
4925 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4926
4927 case CXCursor_NamespaceRef:
4928 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4929
4930 case CXCursor_MemberRef:
4931 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4932
4933 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004934 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4936 tu ));
4937 }
4938
4939 case CXCursor_LabelRef:
4940 // FIXME: We end up faking the "parent" declaration here because we
4941 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004942 return MakeCXCursor(getCursorLabelRef(C).first,
4943 cxtu::getASTUnit(tu)->getASTContext()
4944 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 tu);
4946
4947 case CXCursor_OverloadedDeclRef:
4948 return C;
4949
4950 case CXCursor_VariableRef:
4951 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4952
4953 default:
4954 // We would prefer to enumerate all non-reference cursor kinds here.
4955 llvm_unreachable("Unhandled reference cursor kind");
4956 }
4957}
4958
4959CXCursor clang_getCursorDefinition(CXCursor C) {
4960 if (clang_isInvalid(C.kind))
4961 return clang_getNullCursor();
4962
4963 CXTranslationUnit TU = getCursorTU(C);
4964
4965 bool WasReference = false;
4966 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4967 C = clang_getCursorReferenced(C);
4968 WasReference = true;
4969 }
4970
4971 if (C.kind == CXCursor_MacroExpansion)
4972 return clang_getCursorReferenced(C);
4973
4974 if (!clang_isDeclaration(C.kind))
4975 return clang_getNullCursor();
4976
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004977 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004978 if (!D)
4979 return clang_getNullCursor();
4980
4981 switch (D->getKind()) {
4982 // Declaration kinds that don't really separate the notions of
4983 // declaration and definition.
4984 case Decl::Namespace:
4985 case Decl::Typedef:
4986 case Decl::TypeAlias:
4987 case Decl::TypeAliasTemplate:
4988 case Decl::TemplateTypeParm:
4989 case Decl::EnumConstant:
4990 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004991 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 case Decl::IndirectField:
4993 case Decl::ObjCIvar:
4994 case Decl::ObjCAtDefsField:
4995 case Decl::ImplicitParam:
4996 case Decl::ParmVar:
4997 case Decl::NonTypeTemplateParm:
4998 case Decl::TemplateTemplateParm:
4999 case Decl::ObjCCategoryImpl:
5000 case Decl::ObjCImplementation:
5001 case Decl::AccessSpec:
5002 case Decl::LinkageSpec:
5003 case Decl::ObjCPropertyImpl:
5004 case Decl::FileScopeAsm:
5005 case Decl::StaticAssert:
5006 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005007 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005008 case Decl::Label: // FIXME: Is this right??
5009 case Decl::ClassScopeFunctionSpecialization:
5010 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005011 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005012 return C;
5013
5014 // Declaration kinds that don't make any sense here, but are
5015 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005016 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005018 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005019 break;
5020
5021 // Declaration kinds for which the definition is not resolvable.
5022 case Decl::UnresolvedUsingTypename:
5023 case Decl::UnresolvedUsingValue:
5024 break;
5025
5026 case Decl::UsingDirective:
5027 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5028 TU);
5029
5030 case Decl::NamespaceAlias:
5031 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5032
5033 case Decl::Enum:
5034 case Decl::Record:
5035 case Decl::CXXRecord:
5036 case Decl::ClassTemplateSpecialization:
5037 case Decl::ClassTemplatePartialSpecialization:
5038 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5039 return MakeCXCursor(Def, TU);
5040 return clang_getNullCursor();
5041
5042 case Decl::Function:
5043 case Decl::CXXMethod:
5044 case Decl::CXXConstructor:
5045 case Decl::CXXDestructor:
5046 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005047 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005048 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005049 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 return clang_getNullCursor();
5051 }
5052
Larisse Voufo39a1e502013-08-06 01:03:05 +00005053 case Decl::Var:
5054 case Decl::VarTemplateSpecialization:
5055 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005057 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005058 return MakeCXCursor(Def, TU);
5059 return clang_getNullCursor();
5060 }
5061
5062 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005063 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005064 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5065 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5066 return clang_getNullCursor();
5067 }
5068
5069 case Decl::ClassTemplate: {
5070 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5071 ->getDefinition())
5072 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5073 TU);
5074 return clang_getNullCursor();
5075 }
5076
Larisse Voufo39a1e502013-08-06 01:03:05 +00005077 case Decl::VarTemplate: {
5078 if (VarDecl *Def =
5079 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5080 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5081 return clang_getNullCursor();
5082 }
5083
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 case Decl::Using:
5085 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5086 D->getLocation(), TU);
5087
5088 case Decl::UsingShadow:
5089 return clang_getCursorDefinition(
5090 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5091 TU));
5092
5093 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005094 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005095 if (Method->isThisDeclarationADefinition())
5096 return C;
5097
5098 // Dig out the method definition in the associated
5099 // @implementation, if we have it.
5100 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005101 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5103 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5104 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5105 Method->isInstanceMethod()))
5106 if (Def->isThisDeclarationADefinition())
5107 return MakeCXCursor(Def, TU);
5108
5109 return clang_getNullCursor();
5110 }
5111
5112 case Decl::ObjCCategory:
5113 if (ObjCCategoryImplDecl *Impl
5114 = cast<ObjCCategoryDecl>(D)->getImplementation())
5115 return MakeCXCursor(Impl, TU);
5116 return clang_getNullCursor();
5117
5118 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005119 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 return MakeCXCursor(Def, TU);
5121 return clang_getNullCursor();
5122
5123 case Decl::ObjCInterface: {
5124 // There are two notions of a "definition" for an Objective-C
5125 // class: the interface and its implementation. When we resolved a
5126 // reference to an Objective-C class, produce the @interface as
5127 // the definition; when we were provided with the interface,
5128 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005129 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005131 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 return MakeCXCursor(Def, TU);
5133 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5134 return MakeCXCursor(Impl, TU);
5135 return clang_getNullCursor();
5136 }
5137
5138 case Decl::ObjCProperty:
5139 // FIXME: We don't really know where to find the
5140 // ObjCPropertyImplDecls that implement this property.
5141 return clang_getNullCursor();
5142
5143 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005144 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005146 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005147 return MakeCXCursor(Def, TU);
5148
5149 return clang_getNullCursor();
5150
5151 case Decl::Friend:
5152 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5153 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5154 return clang_getNullCursor();
5155
5156 case Decl::FriendTemplate:
5157 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5158 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5159 return clang_getNullCursor();
5160 }
5161
5162 return clang_getNullCursor();
5163}
5164
5165unsigned clang_isCursorDefinition(CXCursor C) {
5166 if (!clang_isDeclaration(C.kind))
5167 return 0;
5168
5169 return clang_getCursorDefinition(C) == C;
5170}
5171
5172CXCursor clang_getCanonicalCursor(CXCursor C) {
5173 if (!clang_isDeclaration(C.kind))
5174 return C;
5175
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005176 if (const Decl *D = getCursorDecl(C)) {
5177 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5179 return MakeCXCursor(CatD, getCursorTU(C));
5180
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005181 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5182 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005183 return MakeCXCursor(IFD, getCursorTU(C));
5184
5185 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5186 }
5187
5188 return C;
5189}
5190
5191int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5192 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5193}
5194
5195unsigned clang_getNumOverloadedDecls(CXCursor C) {
5196 if (C.kind != CXCursor_OverloadedDeclRef)
5197 return 0;
5198
5199 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005200 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 return E->getNumDecls();
5202
5203 if (OverloadedTemplateStorage *S
5204 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5205 return S->size();
5206
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005207 const Decl *D = Storage.get<const Decl *>();
5208 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 return Using->shadow_size();
5210
5211 return 0;
5212}
5213
5214CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5215 if (cursor.kind != CXCursor_OverloadedDeclRef)
5216 return clang_getNullCursor();
5217
5218 if (index >= clang_getNumOverloadedDecls(cursor))
5219 return clang_getNullCursor();
5220
5221 CXTranslationUnit TU = getCursorTU(cursor);
5222 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005223 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 return MakeCXCursor(E->decls_begin()[index], TU);
5225
5226 if (OverloadedTemplateStorage *S
5227 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5228 return MakeCXCursor(S->begin()[index], TU);
5229
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005230 const Decl *D = Storage.get<const Decl *>();
5231 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 // FIXME: This is, unfortunately, linear time.
5233 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5234 std::advance(Pos, index);
5235 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5236 }
5237
5238 return clang_getNullCursor();
5239}
5240
5241void clang_getDefinitionSpellingAndExtent(CXCursor C,
5242 const char **startBuf,
5243 const char **endBuf,
5244 unsigned *startLine,
5245 unsigned *startColumn,
5246 unsigned *endLine,
5247 unsigned *endColumn) {
5248 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005249 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5251
5252 SourceManager &SM = FD->getASTContext().getSourceManager();
5253 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5254 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5255 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5256 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5257 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5258 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5259}
5260
5261
5262CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5263 unsigned PieceIndex) {
5264 RefNamePieces Pieces;
5265
5266 switch (C.kind) {
5267 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005268 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005269 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5270 E->getQualifierLoc().getSourceRange());
5271 break;
5272
5273 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005274 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5276 E->getQualifierLoc().getSourceRange(),
5277 E->getOptionalExplicitTemplateArgs());
5278 break;
5279
5280 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005281 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005283 const Expr *Callee = OCE->getCallee();
5284 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 Callee = ICE->getSubExpr();
5286
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005287 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5289 DRE->getQualifierLoc().getSourceRange());
5290 }
5291 break;
5292
5293 default:
5294 break;
5295 }
5296
5297 if (Pieces.empty()) {
5298 if (PieceIndex == 0)
5299 return clang_getCursorExtent(C);
5300 } else if (PieceIndex < Pieces.size()) {
5301 SourceRange R = Pieces[PieceIndex];
5302 if (R.isValid())
5303 return cxloc::translateSourceRange(getCursorContext(C), R);
5304 }
5305
5306 return clang_getNullRange();
5307}
5308
5309void clang_enableStackTraces(void) {
5310 llvm::sys::PrintStackTraceOnErrorSignal();
5311}
5312
5313void clang_executeOnThread(void (*fn)(void*), void *user_data,
5314 unsigned stack_size) {
5315 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5316}
5317
5318} // end: extern "C"
5319
5320//===----------------------------------------------------------------------===//
5321// Token-based Operations.
5322//===----------------------------------------------------------------------===//
5323
5324/* CXToken layout:
5325 * int_data[0]: a CXTokenKind
5326 * int_data[1]: starting token location
5327 * int_data[2]: token length
5328 * int_data[3]: reserved
5329 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5330 * otherwise unused.
5331 */
5332extern "C" {
5333
5334CXTokenKind clang_getTokenKind(CXToken CXTok) {
5335 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5336}
5337
5338CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5339 switch (clang_getTokenKind(CXTok)) {
5340 case CXToken_Identifier:
5341 case CXToken_Keyword:
5342 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005343 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 ->getNameStart());
5345
5346 case CXToken_Literal: {
5347 // We have stashed the starting pointer in the ptr_data field. Use it.
5348 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005349 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 }
5351
5352 case CXToken_Punctuation:
5353 case CXToken_Comment:
5354 break;
5355 }
5356
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005357 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005358 LOG_BAD_TU(TU);
5359 return cxstring::createEmpty();
5360 }
5361
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 // We have to find the starting buffer pointer the hard way, by
5363 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005364 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005366 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005367
5368 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5369 std::pair<FileID, unsigned> LocInfo
5370 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5371 bool Invalid = false;
5372 StringRef Buffer
5373 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5374 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005375 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005376
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005377 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005378}
5379
5380CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005381 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005382 LOG_BAD_TU(TU);
5383 return clang_getNullLocation();
5384 }
5385
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005386 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005387 if (!CXXUnit)
5388 return clang_getNullLocation();
5389
5390 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5391 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5392}
5393
5394CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005395 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005396 LOG_BAD_TU(TU);
5397 return clang_getNullRange();
5398 }
5399
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005400 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005401 if (!CXXUnit)
5402 return clang_getNullRange();
5403
5404 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5405 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5406}
5407
5408static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5409 SmallVectorImpl<CXToken> &CXTokens) {
5410 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5411 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005412 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005413 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005414 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005415
5416 // Cannot tokenize across files.
5417 if (BeginLocInfo.first != EndLocInfo.first)
5418 return;
5419
5420 // Create a lexer
5421 bool Invalid = false;
5422 StringRef Buffer
5423 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5424 if (Invalid)
5425 return;
5426
5427 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5428 CXXUnit->getASTContext().getLangOpts(),
5429 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5430 Lex.SetCommentRetentionState(true);
5431
5432 // Lex tokens until we hit the end of the range.
5433 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5434 Token Tok;
5435 bool previousWasAt = false;
5436 do {
5437 // Lex the next token
5438 Lex.LexFromRawLexer(Tok);
5439 if (Tok.is(tok::eof))
5440 break;
5441
5442 // Initialize the CXToken.
5443 CXToken CXTok;
5444
5445 // - Common fields
5446 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5447 CXTok.int_data[2] = Tok.getLength();
5448 CXTok.int_data[3] = 0;
5449
5450 // - Kind-specific fields
5451 if (Tok.isLiteral()) {
5452 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005453 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005454 } else if (Tok.is(tok::raw_identifier)) {
5455 // Lookup the identifier to determine whether we have a keyword.
5456 IdentifierInfo *II
5457 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5458
5459 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5460 CXTok.int_data[0] = CXToken_Keyword;
5461 }
5462 else {
5463 CXTok.int_data[0] = Tok.is(tok::identifier)
5464 ? CXToken_Identifier
5465 : CXToken_Keyword;
5466 }
5467 CXTok.ptr_data = II;
5468 } else if (Tok.is(tok::comment)) {
5469 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005470 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 } else {
5472 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005473 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 }
5475 CXTokens.push_back(CXTok);
5476 previousWasAt = Tok.is(tok::at);
5477 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5478}
5479
5480void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5481 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005482 LOG_FUNC_SECTION {
5483 *Log << TU << ' ' << Range;
5484 }
5485
Guy Benyei11169dd2012-12-18 14:30:41 +00005486 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005487 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005488 if (NumTokens)
5489 *NumTokens = 0;
5490
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005491 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005492 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005493 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005494 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005495
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005496 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 if (!CXXUnit || !Tokens || !NumTokens)
5498 return;
5499
5500 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5501
5502 SourceRange R = cxloc::translateCXSourceRange(Range);
5503 if (R.isInvalid())
5504 return;
5505
5506 SmallVector<CXToken, 32> CXTokens;
5507 getTokens(CXXUnit, R, CXTokens);
5508
5509 if (CXTokens.empty())
5510 return;
5511
5512 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5513 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5514 *NumTokens = CXTokens.size();
5515}
5516
5517void clang_disposeTokens(CXTranslationUnit TU,
5518 CXToken *Tokens, unsigned NumTokens) {
5519 free(Tokens);
5520}
5521
5522} // end: extern "C"
5523
5524//===----------------------------------------------------------------------===//
5525// Token annotation APIs.
5526//===----------------------------------------------------------------------===//
5527
Guy Benyei11169dd2012-12-18 14:30:41 +00005528static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5529 CXCursor parent,
5530 CXClientData client_data);
5531static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5532 CXClientData client_data);
5533
5534namespace {
5535class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005536 CXToken *Tokens;
5537 CXCursor *Cursors;
5538 unsigned NumTokens;
5539 unsigned TokIdx;
5540 unsigned PreprocessingTokIdx;
5541 CursorVisitor AnnotateVis;
5542 SourceManager &SrcMgr;
5543 bool HasContextSensitiveKeywords;
5544
5545 struct PostChildrenInfo {
5546 CXCursor Cursor;
5547 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005548 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005549 unsigned BeforeChildrenTokenIdx;
5550 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005551 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005552
5553 CXToken &getTok(unsigned Idx) {
5554 assert(Idx < NumTokens);
5555 return Tokens[Idx];
5556 }
5557 const CXToken &getTok(unsigned Idx) const {
5558 assert(Idx < NumTokens);
5559 return Tokens[Idx];
5560 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005561 bool MoreTokens() const { return TokIdx < NumTokens; }
5562 unsigned NextToken() const { return TokIdx; }
5563 void AdvanceToken() { ++TokIdx; }
5564 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005565 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005566 }
5567 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005568 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005569 }
5570 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005571 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005572 }
5573
5574 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005575 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005576 SourceRange);
5577
5578public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005579 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005580 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005581 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005582 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005583 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 AnnotateTokensVisitor, this,
5585 /*VisitPreprocessorLast=*/true,
5586 /*VisitIncludedEntities=*/false,
5587 RegionOfInterest,
5588 /*VisitDeclsOnly=*/false,
5589 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005590 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005591 HasContextSensitiveKeywords(false) { }
5592
5593 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5594 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5595 bool postVisitChildren(CXCursor cursor);
5596 void AnnotateTokens();
5597
5598 /// \brief Determine whether the annotator saw any cursors that have
5599 /// context-sensitive keywords.
5600 bool hasContextSensitiveKeywords() const {
5601 return HasContextSensitiveKeywords;
5602 }
5603
5604 ~AnnotateTokensWorker() {
5605 assert(PostChildrenInfos.empty());
5606 }
5607};
5608}
5609
5610void AnnotateTokensWorker::AnnotateTokens() {
5611 // Walk the AST within the region of interest, annotating tokens
5612 // along the way.
5613 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005614}
Guy Benyei11169dd2012-12-18 14:30:41 +00005615
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005616static inline void updateCursorAnnotation(CXCursor &Cursor,
5617 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005618 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005619 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005620 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005621}
5622
5623/// \brief It annotates and advances tokens with a cursor until the comparison
5624//// between the cursor location and the source range is the same as
5625/// \arg compResult.
5626///
5627/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5628/// Pass RangeOverlap to annotate tokens inside a range.
5629void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5630 RangeComparisonResult compResult,
5631 SourceRange range) {
5632 while (MoreTokens()) {
5633 const unsigned I = NextToken();
5634 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005635 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5636 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005637
5638 SourceLocation TokLoc = GetTokenLoc(I);
5639 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005640 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005641 AdvanceToken();
5642 continue;
5643 }
5644 break;
5645 }
5646}
5647
5648/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005649/// \returns true if it advanced beyond all macro tokens, false otherwise.
5650bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005651 CXCursor updateC,
5652 RangeComparisonResult compResult,
5653 SourceRange range) {
5654 assert(MoreTokens());
5655 assert(isFunctionMacroToken(NextToken()) &&
5656 "Should be called only for macro arg tokens");
5657
5658 // This works differently than annotateAndAdvanceTokens; because expanded
5659 // macro arguments can have arbitrary translation-unit source order, we do not
5660 // advance the token index one by one until a token fails the range test.
5661 // We only advance once past all of the macro arg tokens if all of them
5662 // pass the range test. If one of them fails we keep the token index pointing
5663 // at the start of the macro arg tokens so that the failing token will be
5664 // annotated by a subsequent annotation try.
5665
5666 bool atLeastOneCompFail = false;
5667
5668 unsigned I = NextToken();
5669 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5670 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5671 if (TokLoc.isFileID())
5672 continue; // not macro arg token, it's parens or comma.
5673 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5674 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5675 Cursors[I] = updateC;
5676 } else
5677 atLeastOneCompFail = true;
5678 }
5679
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005680 if (atLeastOneCompFail)
5681 return false;
5682
5683 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5684 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005685}
5686
5687enum CXChildVisitResult
5688AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005689 SourceRange cursorRange = getRawCursorExtent(cursor);
5690 if (cursorRange.isInvalid())
5691 return CXChildVisit_Recurse;
5692
5693 if (!HasContextSensitiveKeywords) {
5694 // Objective-C properties can have context-sensitive keywords.
5695 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005696 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005697 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5698 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5699 }
5700 // Objective-C methods can have context-sensitive keywords.
5701 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5702 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005703 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005704 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5705 if (Method->getObjCDeclQualifier())
5706 HasContextSensitiveKeywords = true;
5707 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005708 for (const auto *P : Method->params()) {
5709 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005710 HasContextSensitiveKeywords = true;
5711 break;
5712 }
5713 }
5714 }
5715 }
5716 }
5717 // C++ methods can have context-sensitive keywords.
5718 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005719 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5721 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5722 HasContextSensitiveKeywords = true;
5723 }
5724 }
5725 // C++ classes can have context-sensitive keywords.
5726 else if (cursor.kind == CXCursor_StructDecl ||
5727 cursor.kind == CXCursor_ClassDecl ||
5728 cursor.kind == CXCursor_ClassTemplate ||
5729 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005730 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005731 if (D->hasAttr<FinalAttr>())
5732 HasContextSensitiveKeywords = true;
5733 }
5734 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005735
5736 // Don't override a property annotation with its getter/setter method.
5737 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5738 parent.kind == CXCursor_ObjCPropertyDecl)
5739 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005740
5741 if (clang_isPreprocessing(cursor.kind)) {
5742 // Items in the preprocessing record are kept separate from items in
5743 // declarations, so we keep a separate token index.
5744 unsigned SavedTokIdx = TokIdx;
5745 TokIdx = PreprocessingTokIdx;
5746
5747 // Skip tokens up until we catch up to the beginning of the preprocessing
5748 // entry.
5749 while (MoreTokens()) {
5750 const unsigned I = NextToken();
5751 SourceLocation TokLoc = GetTokenLoc(I);
5752 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5753 case RangeBefore:
5754 AdvanceToken();
5755 continue;
5756 case RangeAfter:
5757 case RangeOverlap:
5758 break;
5759 }
5760 break;
5761 }
5762
5763 // Look at all of the tokens within this range.
5764 while (MoreTokens()) {
5765 const unsigned I = NextToken();
5766 SourceLocation TokLoc = GetTokenLoc(I);
5767 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5768 case RangeBefore:
5769 llvm_unreachable("Infeasible");
5770 case RangeAfter:
5771 break;
5772 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005773 // For macro expansions, just note where the beginning of the macro
5774 // expansion occurs.
5775 if (cursor.kind == CXCursor_MacroExpansion) {
5776 if (TokLoc == cursorRange.getBegin())
5777 Cursors[I] = cursor;
5778 AdvanceToken();
5779 break;
5780 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005781 // We may have already annotated macro names inside macro definitions.
5782 if (Cursors[I].kind != CXCursor_MacroExpansion)
5783 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005784 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005785 continue;
5786 }
5787 break;
5788 }
5789
5790 // Save the preprocessing token index; restore the non-preprocessing
5791 // token index.
5792 PreprocessingTokIdx = TokIdx;
5793 TokIdx = SavedTokIdx;
5794 return CXChildVisit_Recurse;
5795 }
5796
5797 if (cursorRange.isInvalid())
5798 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005799
5800 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005801 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005802 const enum CXCursorKind K = clang_getCursorKind(parent);
5803 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005804 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5805 // Attributes are annotated out-of-order, skip tokens until we reach it.
5806 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005807 ? clang_getNullCursor() : parent;
5808
5809 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5810
5811 // Avoid having the cursor of an expression "overwrite" the annotation of the
5812 // variable declaration that it belongs to.
5813 // This can happen for C++ constructor expressions whose range generally
5814 // include the variable declaration, e.g.:
5815 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005816 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005817 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005818 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005819 const unsigned I = NextToken();
5820 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5821 E->getLocStart() == D->getLocation() &&
5822 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005823 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005824 AdvanceToken();
5825 }
5826 }
5827 }
5828
5829 // Before recursing into the children keep some state that we are going
5830 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5831 // extra work after the child nodes are visited.
5832 // Note that we don't call VisitChildren here to avoid traversing statements
5833 // code-recursively which can blow the stack.
5834
5835 PostChildrenInfo Info;
5836 Info.Cursor = cursor;
5837 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005838 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005839 Info.BeforeChildrenTokenIdx = NextToken();
5840 PostChildrenInfos.push_back(Info);
5841
5842 return CXChildVisit_Recurse;
5843}
5844
5845bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5846 if (PostChildrenInfos.empty())
5847 return false;
5848 const PostChildrenInfo &Info = PostChildrenInfos.back();
5849 if (!clang_equalCursors(Info.Cursor, cursor))
5850 return false;
5851
5852 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5853 const unsigned AfterChildren = NextToken();
5854 SourceRange cursorRange = Info.CursorRange;
5855
5856 // Scan the tokens that are at the end of the cursor, but are not captured
5857 // but the child cursors.
5858 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5859
5860 // Scan the tokens that are at the beginning of the cursor, but are not
5861 // capture by the child cursors.
5862 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5863 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5864 break;
5865
5866 Cursors[I] = cursor;
5867 }
5868
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005869 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5870 // encountered the attribute cursor.
5871 if (clang_isAttribute(cursor.kind))
5872 TokIdx = Info.BeforeReachingCursorIdx;
5873
Guy Benyei11169dd2012-12-18 14:30:41 +00005874 PostChildrenInfos.pop_back();
5875 return false;
5876}
5877
5878static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5879 CXCursor parent,
5880 CXClientData client_data) {
5881 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5882}
5883
5884static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5885 CXClientData client_data) {
5886 return static_cast<AnnotateTokensWorker*>(client_data)->
5887 postVisitChildren(cursor);
5888}
5889
5890namespace {
5891
5892/// \brief Uses the macro expansions in the preprocessing record to find
5893/// and mark tokens that are macro arguments. This info is used by the
5894/// AnnotateTokensWorker.
5895class MarkMacroArgTokensVisitor {
5896 SourceManager &SM;
5897 CXToken *Tokens;
5898 unsigned NumTokens;
5899 unsigned CurIdx;
5900
5901public:
5902 MarkMacroArgTokensVisitor(SourceManager &SM,
5903 CXToken *tokens, unsigned numTokens)
5904 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5905
5906 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5907 if (cursor.kind != CXCursor_MacroExpansion)
5908 return CXChildVisit_Continue;
5909
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005910 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005911 if (macroRange.getBegin() == macroRange.getEnd())
5912 return CXChildVisit_Continue; // it's not a function macro.
5913
5914 for (; CurIdx < NumTokens; ++CurIdx) {
5915 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5916 macroRange.getBegin()))
5917 break;
5918 }
5919
5920 if (CurIdx == NumTokens)
5921 return CXChildVisit_Break;
5922
5923 for (; CurIdx < NumTokens; ++CurIdx) {
5924 SourceLocation tokLoc = getTokenLoc(CurIdx);
5925 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5926 break;
5927
5928 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5929 }
5930
5931 if (CurIdx == NumTokens)
5932 return CXChildVisit_Break;
5933
5934 return CXChildVisit_Continue;
5935 }
5936
5937private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005938 CXToken &getTok(unsigned Idx) {
5939 assert(Idx < NumTokens);
5940 return Tokens[Idx];
5941 }
5942 const CXToken &getTok(unsigned Idx) const {
5943 assert(Idx < NumTokens);
5944 return Tokens[Idx];
5945 }
5946
Guy Benyei11169dd2012-12-18 14:30:41 +00005947 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005948 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005949 }
5950
5951 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5952 // The third field is reserved and currently not used. Use it here
5953 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005954 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005955 }
5956};
5957
5958} // end anonymous namespace
5959
5960static CXChildVisitResult
5961MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5962 CXClientData client_data) {
5963 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5964 parent);
5965}
5966
5967namespace {
5968 struct clang_annotateTokens_Data {
5969 CXTranslationUnit TU;
5970 ASTUnit *CXXUnit;
5971 CXToken *Tokens;
5972 unsigned NumTokens;
5973 CXCursor *Cursors;
5974 };
5975}
5976
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005977/// \brief Used by \c annotatePreprocessorTokens.
5978/// \returns true if lexing was finished, false otherwise.
5979static bool lexNext(Lexer &Lex, Token &Tok,
5980 unsigned &NextIdx, unsigned NumTokens) {
5981 if (NextIdx >= NumTokens)
5982 return true;
5983
5984 ++NextIdx;
5985 Lex.LexFromRawLexer(Tok);
5986 if (Tok.is(tok::eof))
5987 return true;
5988
5989 return false;
5990}
5991
Guy Benyei11169dd2012-12-18 14:30:41 +00005992static void annotatePreprocessorTokens(CXTranslationUnit TU,
5993 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005994 CXCursor *Cursors,
5995 CXToken *Tokens,
5996 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005997 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005998
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005999 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006000 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6001 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006002 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006003 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006004 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006005
6006 if (BeginLocInfo.first != EndLocInfo.first)
6007 return;
6008
6009 StringRef Buffer;
6010 bool Invalid = false;
6011 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6012 if (Buffer.empty() || Invalid)
6013 return;
6014
6015 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6016 CXXUnit->getASTContext().getLangOpts(),
6017 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6018 Buffer.end());
6019 Lex.SetCommentRetentionState(true);
6020
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006021 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006022 // Lex tokens in raw mode until we hit the end of the range, to avoid
6023 // entering #includes or expanding macros.
6024 while (true) {
6025 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006026 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6027 break;
6028 unsigned TokIdx = NextIdx-1;
6029 assert(Tok.getLocation() ==
6030 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006031
6032 reprocess:
6033 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006034 // We have found a preprocessing directive. Annotate the tokens
6035 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006036 //
6037 // FIXME: Some simple tests here could identify macro definitions and
6038 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006039
6040 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006041 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6042 break;
6043
Craig Topper69186e72014-06-08 08:38:04 +00006044 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006045 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006046 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6047 break;
6048
6049 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006050 IdentifierInfo &II =
6051 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006052 SourceLocation MappedTokLoc =
6053 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6054 MI = getMacroInfo(II, MappedTokLoc, TU);
6055 }
6056 }
6057
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006058 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006059 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006060 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6061 finished = true;
6062 break;
6063 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006064 // If we are in a macro definition, check if the token was ever a
6065 // macro name and annotate it if that's the case.
6066 if (MI) {
6067 SourceLocation SaveLoc = Tok.getLocation();
6068 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006069 MacroDefinitionRecord *MacroDef =
6070 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006071 Tok.setLocation(SaveLoc);
6072 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006073 Cursors[NextIdx - 1] =
6074 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006075 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006076 } while (!Tok.isAtStartOfLine());
6077
6078 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6079 assert(TokIdx <= LastIdx);
6080 SourceLocation EndLoc =
6081 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6082 CXCursor Cursor =
6083 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6084
6085 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006086 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006087
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006088 if (finished)
6089 break;
6090 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006091 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006092 }
6093}
6094
6095// This gets run a separate thread to avoid stack blowout.
6096static void clang_annotateTokensImpl(void *UserData) {
6097 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6098 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6099 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6100 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6101 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6102
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006103 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006104 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6105 setThreadBackgroundPriority();
6106
6107 // Determine the region of interest, which contains all of the tokens.
6108 SourceRange RegionOfInterest;
6109 RegionOfInterest.setBegin(
6110 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6111 RegionOfInterest.setEnd(
6112 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6113 Tokens[NumTokens-1])));
6114
Guy Benyei11169dd2012-12-18 14:30:41 +00006115 // Relex the tokens within the source range to look for preprocessing
6116 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006117 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006118
6119 // If begin location points inside a macro argument, set it to the expansion
6120 // location so we can have the full context when annotating semantically.
6121 {
6122 SourceManager &SM = CXXUnit->getSourceManager();
6123 SourceLocation Loc =
6124 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6125 if (Loc.isMacroID())
6126 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6127 }
6128
Guy Benyei11169dd2012-12-18 14:30:41 +00006129 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6130 // Search and mark tokens that are macro argument expansions.
6131 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6132 Tokens, NumTokens);
6133 CursorVisitor MacroArgMarker(TU,
6134 MarkMacroArgTokensVisitorDelegate, &Visitor,
6135 /*VisitPreprocessorLast=*/true,
6136 /*VisitIncludedEntities=*/false,
6137 RegionOfInterest);
6138 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6139 }
6140
6141 // Annotate all of the source locations in the region of interest that map to
6142 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006143 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006144
6145 // FIXME: We use a ridiculous stack size here because the data-recursion
6146 // algorithm uses a large stack frame than the non-data recursive version,
6147 // and AnnotationTokensWorker currently transforms the data-recursion
6148 // algorithm back into a traditional recursion by explicitly calling
6149 // VisitChildren(). We will need to remove this explicit recursive call.
6150 W.AnnotateTokens();
6151
6152 // If we ran into any entities that involve context-sensitive keywords,
6153 // take another pass through the tokens to mark them as such.
6154 if (W.hasContextSensitiveKeywords()) {
6155 for (unsigned I = 0; I != NumTokens; ++I) {
6156 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6157 continue;
6158
6159 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6160 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006161 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006162 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6163 if (Property->getPropertyAttributesAsWritten() != 0 &&
6164 llvm::StringSwitch<bool>(II->getName())
6165 .Case("readonly", true)
6166 .Case("assign", true)
6167 .Case("unsafe_unretained", true)
6168 .Case("readwrite", true)
6169 .Case("retain", true)
6170 .Case("copy", true)
6171 .Case("nonatomic", true)
6172 .Case("atomic", true)
6173 .Case("getter", true)
6174 .Case("setter", true)
6175 .Case("strong", true)
6176 .Case("weak", true)
6177 .Default(false))
6178 Tokens[I].int_data[0] = CXToken_Keyword;
6179 }
6180 continue;
6181 }
6182
6183 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6184 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6185 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6186 if (llvm::StringSwitch<bool>(II->getName())
6187 .Case("in", true)
6188 .Case("out", true)
6189 .Case("inout", true)
6190 .Case("oneway", true)
6191 .Case("bycopy", true)
6192 .Case("byref", true)
6193 .Default(false))
6194 Tokens[I].int_data[0] = CXToken_Keyword;
6195 continue;
6196 }
6197
6198 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6199 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6200 Tokens[I].int_data[0] = CXToken_Keyword;
6201 continue;
6202 }
6203 }
6204 }
6205}
6206
6207extern "C" {
6208
6209void clang_annotateTokens(CXTranslationUnit TU,
6210 CXToken *Tokens, unsigned NumTokens,
6211 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006212 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006213 LOG_BAD_TU(TU);
6214 return;
6215 }
6216 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006217 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006218 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006219 }
6220
6221 LOG_FUNC_SECTION {
6222 *Log << TU << ' ';
6223 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6224 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6225 *Log << clang_getRange(bloc, eloc);
6226 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006227
6228 // Any token we don't specifically annotate will have a NULL cursor.
6229 CXCursor C = clang_getNullCursor();
6230 for (unsigned I = 0; I != NumTokens; ++I)
6231 Cursors[I] = C;
6232
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006233 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006234 if (!CXXUnit)
6235 return;
6236
6237 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6238
6239 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6240 llvm::CrashRecoveryContext CRC;
6241 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6242 GetSafetyThreadStackSize() * 2)) {
6243 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6244 }
6245}
6246
6247} // end: extern "C"
6248
6249//===----------------------------------------------------------------------===//
6250// Operations for querying linkage of a cursor.
6251//===----------------------------------------------------------------------===//
6252
6253extern "C" {
6254CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6255 if (!clang_isDeclaration(cursor.kind))
6256 return CXLinkage_Invalid;
6257
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006258 const Decl *D = cxcursor::getCursorDecl(cursor);
6259 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006260 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006261 case NoLinkage:
6262 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006263 case InternalLinkage: return CXLinkage_Internal;
6264 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6265 case ExternalLinkage: return CXLinkage_External;
6266 };
6267
6268 return CXLinkage_Invalid;
6269}
6270} // end: extern "C"
6271
6272//===----------------------------------------------------------------------===//
6273// Operations for querying language of a cursor.
6274//===----------------------------------------------------------------------===//
6275
6276static CXLanguageKind getDeclLanguage(const Decl *D) {
6277 if (!D)
6278 return CXLanguage_C;
6279
6280 switch (D->getKind()) {
6281 default:
6282 break;
6283 case Decl::ImplicitParam:
6284 case Decl::ObjCAtDefsField:
6285 case Decl::ObjCCategory:
6286 case Decl::ObjCCategoryImpl:
6287 case Decl::ObjCCompatibleAlias:
6288 case Decl::ObjCImplementation:
6289 case Decl::ObjCInterface:
6290 case Decl::ObjCIvar:
6291 case Decl::ObjCMethod:
6292 case Decl::ObjCProperty:
6293 case Decl::ObjCPropertyImpl:
6294 case Decl::ObjCProtocol:
6295 return CXLanguage_ObjC;
6296 case Decl::CXXConstructor:
6297 case Decl::CXXConversion:
6298 case Decl::CXXDestructor:
6299 case Decl::CXXMethod:
6300 case Decl::CXXRecord:
6301 case Decl::ClassTemplate:
6302 case Decl::ClassTemplatePartialSpecialization:
6303 case Decl::ClassTemplateSpecialization:
6304 case Decl::Friend:
6305 case Decl::FriendTemplate:
6306 case Decl::FunctionTemplate:
6307 case Decl::LinkageSpec:
6308 case Decl::Namespace:
6309 case Decl::NamespaceAlias:
6310 case Decl::NonTypeTemplateParm:
6311 case Decl::StaticAssert:
6312 case Decl::TemplateTemplateParm:
6313 case Decl::TemplateTypeParm:
6314 case Decl::UnresolvedUsingTypename:
6315 case Decl::UnresolvedUsingValue:
6316 case Decl::Using:
6317 case Decl::UsingDirective:
6318 case Decl::UsingShadow:
6319 return CXLanguage_CPlusPlus;
6320 }
6321
6322 return CXLanguage_C;
6323}
6324
6325extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006326
6327static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6328 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6329 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006330
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006331 switch (D->getAvailability()) {
6332 case AR_Available:
6333 case AR_NotYetIntroduced:
6334 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006335 return getCursorAvailabilityForDecl(
6336 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006337 return CXAvailability_Available;
6338
6339 case AR_Deprecated:
6340 return CXAvailability_Deprecated;
6341
6342 case AR_Unavailable:
6343 return CXAvailability_NotAvailable;
6344 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006345
6346 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006347}
6348
Guy Benyei11169dd2012-12-18 14:30:41 +00006349enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6350 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006351 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6352 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006353
6354 return CXAvailability_Available;
6355}
6356
6357static CXVersion convertVersion(VersionTuple In) {
6358 CXVersion Out = { -1, -1, -1 };
6359 if (In.empty())
6360 return Out;
6361
6362 Out.Major = In.getMajor();
6363
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006364 Optional<unsigned> Minor = In.getMinor();
6365 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006366 Out.Minor = *Minor;
6367 else
6368 return Out;
6369
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006370 Optional<unsigned> Subminor = In.getSubminor();
6371 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006372 Out.Subminor = *Subminor;
6373
6374 return Out;
6375}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006376
6377static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6378 int *always_deprecated,
6379 CXString *deprecated_message,
6380 int *always_unavailable,
6381 CXString *unavailable_message,
6382 CXPlatformAvailability *availability,
6383 int availability_size) {
6384 bool HadAvailAttr = false;
6385 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006386 for (auto A : D->attrs()) {
6387 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006388 HadAvailAttr = true;
6389 if (always_deprecated)
6390 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006391 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006392 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006393 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006394 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006395 continue;
6396 }
6397
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006398 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006399 HadAvailAttr = true;
6400 if (always_unavailable)
6401 *always_unavailable = 1;
6402 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006403 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006404 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6405 }
6406 continue;
6407 }
6408
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006409 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006410 HadAvailAttr = true;
6411 if (N < availability_size) {
6412 availability[N].Platform
6413 = cxstring::createDup(Avail->getPlatform()->getName());
6414 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6415 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6416 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6417 availability[N].Unavailable = Avail->getUnavailable();
6418 availability[N].Message = cxstring::createDup(Avail->getMessage());
6419 }
6420 ++N;
6421 }
6422 }
6423
6424 if (!HadAvailAttr)
6425 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6426 return getCursorPlatformAvailabilityForDecl(
6427 cast<Decl>(EnumConst->getDeclContext()),
6428 always_deprecated,
6429 deprecated_message,
6430 always_unavailable,
6431 unavailable_message,
6432 availability,
6433 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006434
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006435 return N;
6436}
6437
Guy Benyei11169dd2012-12-18 14:30:41 +00006438int clang_getCursorPlatformAvailability(CXCursor cursor,
6439 int *always_deprecated,
6440 CXString *deprecated_message,
6441 int *always_unavailable,
6442 CXString *unavailable_message,
6443 CXPlatformAvailability *availability,
6444 int availability_size) {
6445 if (always_deprecated)
6446 *always_deprecated = 0;
6447 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006448 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006449 if (always_unavailable)
6450 *always_unavailable = 0;
6451 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006452 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006453
Guy Benyei11169dd2012-12-18 14:30:41 +00006454 if (!clang_isDeclaration(cursor.kind))
6455 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006456
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006457 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006458 if (!D)
6459 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006460
6461 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6462 deprecated_message,
6463 always_unavailable,
6464 unavailable_message,
6465 availability,
6466 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006467}
6468
6469void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6470 clang_disposeString(availability->Platform);
6471 clang_disposeString(availability->Message);
6472}
6473
6474CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6475 if (clang_isDeclaration(cursor.kind))
6476 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6477
6478 return CXLanguage_Invalid;
6479}
6480
6481 /// \brief If the given cursor is the "templated" declaration
6482 /// descibing a class or function template, return the class or
6483 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006484static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006485 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006486 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006487
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006488 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006489 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6490 return FunTmpl;
6491
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006492 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006493 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6494 return ClassTmpl;
6495
6496 return D;
6497}
6498
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006499
6500enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6501 StorageClass sc = SC_None;
6502 const Decl *D = getCursorDecl(C);
6503 if (D) {
6504 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6505 sc = FD->getStorageClass();
6506 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6507 sc = VD->getStorageClass();
6508 } else {
6509 return CX_SC_Invalid;
6510 }
6511 } else {
6512 return CX_SC_Invalid;
6513 }
6514 switch (sc) {
6515 case SC_None:
6516 return CX_SC_None;
6517 case SC_Extern:
6518 return CX_SC_Extern;
6519 case SC_Static:
6520 return CX_SC_Static;
6521 case SC_PrivateExtern:
6522 return CX_SC_PrivateExtern;
6523 case SC_OpenCLWorkGroupLocal:
6524 return CX_SC_OpenCLWorkGroupLocal;
6525 case SC_Auto:
6526 return CX_SC_Auto;
6527 case SC_Register:
6528 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006529 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006530 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006531}
6532
Guy Benyei11169dd2012-12-18 14:30:41 +00006533CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6534 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006535 if (const Decl *D = getCursorDecl(cursor)) {
6536 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006537 if (!DC)
6538 return clang_getNullCursor();
6539
6540 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6541 getCursorTU(cursor));
6542 }
6543 }
6544
6545 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006546 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006547 return MakeCXCursor(D, getCursorTU(cursor));
6548 }
6549
6550 return clang_getNullCursor();
6551}
6552
6553CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6554 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006555 if (const Decl *D = getCursorDecl(cursor)) {
6556 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006557 if (!DC)
6558 return clang_getNullCursor();
6559
6560 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6561 getCursorTU(cursor));
6562 }
6563 }
6564
6565 // FIXME: Note that we can't easily compute the lexical context of a
6566 // statement or expression, so we return nothing.
6567 return clang_getNullCursor();
6568}
6569
6570CXFile clang_getIncludedFile(CXCursor cursor) {
6571 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006572 return nullptr;
6573
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006574 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006575 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006576}
6577
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006578unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6579 if (C.kind != CXCursor_ObjCPropertyDecl)
6580 return CXObjCPropertyAttr_noattr;
6581
6582 unsigned Result = CXObjCPropertyAttr_noattr;
6583 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6584 ObjCPropertyDecl::PropertyAttributeKind Attr =
6585 PD->getPropertyAttributesAsWritten();
6586
6587#define SET_CXOBJCPROP_ATTR(A) \
6588 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6589 Result |= CXObjCPropertyAttr_##A
6590 SET_CXOBJCPROP_ATTR(readonly);
6591 SET_CXOBJCPROP_ATTR(getter);
6592 SET_CXOBJCPROP_ATTR(assign);
6593 SET_CXOBJCPROP_ATTR(readwrite);
6594 SET_CXOBJCPROP_ATTR(retain);
6595 SET_CXOBJCPROP_ATTR(copy);
6596 SET_CXOBJCPROP_ATTR(nonatomic);
6597 SET_CXOBJCPROP_ATTR(setter);
6598 SET_CXOBJCPROP_ATTR(atomic);
6599 SET_CXOBJCPROP_ATTR(weak);
6600 SET_CXOBJCPROP_ATTR(strong);
6601 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6602#undef SET_CXOBJCPROP_ATTR
6603
6604 return Result;
6605}
6606
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006607unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6608 if (!clang_isDeclaration(C.kind))
6609 return CXObjCDeclQualifier_None;
6610
6611 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6612 const Decl *D = getCursorDecl(C);
6613 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6614 QT = MD->getObjCDeclQualifier();
6615 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6616 QT = PD->getObjCDeclQualifier();
6617 if (QT == Decl::OBJC_TQ_None)
6618 return CXObjCDeclQualifier_None;
6619
6620 unsigned Result = CXObjCDeclQualifier_None;
6621 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6622 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6623 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6624 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6625 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6626 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6627
6628 return Result;
6629}
6630
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006631unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6632 if (!clang_isDeclaration(C.kind))
6633 return 0;
6634
6635 const Decl *D = getCursorDecl(C);
6636 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6637 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6638 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6639 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6640
6641 return 0;
6642}
6643
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006644unsigned clang_Cursor_isVariadic(CXCursor C) {
6645 if (!clang_isDeclaration(C.kind))
6646 return 0;
6647
6648 const Decl *D = getCursorDecl(C);
6649 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6650 return FD->isVariadic();
6651 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6652 return MD->isVariadic();
6653
6654 return 0;
6655}
6656
Guy Benyei11169dd2012-12-18 14:30:41 +00006657CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6658 if (!clang_isDeclaration(C.kind))
6659 return clang_getNullRange();
6660
6661 const Decl *D = getCursorDecl(C);
6662 ASTContext &Context = getCursorContext(C);
6663 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6664 if (!RC)
6665 return clang_getNullRange();
6666
6667 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6668}
6669
6670CXString clang_Cursor_getRawCommentText(CXCursor C) {
6671 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006672 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006673
6674 const Decl *D = getCursorDecl(C);
6675 ASTContext &Context = getCursorContext(C);
6676 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6677 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6678 StringRef();
6679
6680 // Don't duplicate the string because RawText points directly into source
6681 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006682 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006683}
6684
6685CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6686 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006687 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006688
6689 const Decl *D = getCursorDecl(C);
6690 const ASTContext &Context = getCursorContext(C);
6691 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6692
6693 if (RC) {
6694 StringRef BriefText = RC->getBriefText(Context);
6695
6696 // Don't duplicate the string because RawComment ensures that this memory
6697 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006698 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006699 }
6700
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006701 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006702}
6703
Guy Benyei11169dd2012-12-18 14:30:41 +00006704CXModule clang_Cursor_getModule(CXCursor C) {
6705 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006706 if (const ImportDecl *ImportD =
6707 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006708 return ImportD->getImportedModule();
6709 }
6710
Craig Topper69186e72014-06-08 08:38:04 +00006711 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006712}
6713
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006714CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6715 if (isNotUsableTU(TU)) {
6716 LOG_BAD_TU(TU);
6717 return nullptr;
6718 }
6719 if (!File)
6720 return nullptr;
6721 FileEntry *FE = static_cast<FileEntry *>(File);
6722
6723 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6724 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6725 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6726
Richard Smithfeb54b62014-10-23 02:01:19 +00006727 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006728}
6729
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006730CXFile clang_Module_getASTFile(CXModule CXMod) {
6731 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006732 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006733 Module *Mod = static_cast<Module*>(CXMod);
6734 return const_cast<FileEntry *>(Mod->getASTFile());
6735}
6736
Guy Benyei11169dd2012-12-18 14:30:41 +00006737CXModule clang_Module_getParent(CXModule CXMod) {
6738 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006739 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006740 Module *Mod = static_cast<Module*>(CXMod);
6741 return Mod->Parent;
6742}
6743
6744CXString clang_Module_getName(CXModule CXMod) {
6745 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006746 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006747 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006748 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006749}
6750
6751CXString clang_Module_getFullName(CXModule CXMod) {
6752 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006753 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006754 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006755 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006756}
6757
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006758int clang_Module_isSystem(CXModule CXMod) {
6759 if (!CXMod)
6760 return 0;
6761 Module *Mod = static_cast<Module*>(CXMod);
6762 return Mod->IsSystem;
6763}
6764
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006765unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6766 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006767 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006768 LOG_BAD_TU(TU);
6769 return 0;
6770 }
6771 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006772 return 0;
6773 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006774 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6775 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6776 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006777}
6778
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006779CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6780 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006781 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006782 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006783 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006784 }
6785 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006786 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006787 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006788 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006789
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006790 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6791 if (Index < TopHeaders.size())
6792 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006793
Craig Topper69186e72014-06-08 08:38:04 +00006794 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006795}
6796
6797} // end: extern "C"
6798
6799//===----------------------------------------------------------------------===//
6800// C++ AST instrospection.
6801//===----------------------------------------------------------------------===//
6802
6803extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006804unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6805 if (!clang_isDeclaration(C.kind))
6806 return 0;
6807
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006808 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006809 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006810 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006811 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6812}
6813
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006814unsigned clang_CXXMethod_isConst(CXCursor C) {
6815 if (!clang_isDeclaration(C.kind))
6816 return 0;
6817
6818 const Decl *D = cxcursor::getCursorDecl(C);
6819 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006820 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006821 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6822}
6823
Guy Benyei11169dd2012-12-18 14:30:41 +00006824unsigned clang_CXXMethod_isStatic(CXCursor C) {
6825 if (!clang_isDeclaration(C.kind))
6826 return 0;
6827
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006828 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006829 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006830 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006831 return (Method && Method->isStatic()) ? 1 : 0;
6832}
6833
6834unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6835 if (!clang_isDeclaration(C.kind))
6836 return 0;
6837
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006838 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006839 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006840 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006841 return (Method && Method->isVirtual()) ? 1 : 0;
6842}
6843} // end: extern "C"
6844
6845//===----------------------------------------------------------------------===//
6846// Attribute introspection.
6847//===----------------------------------------------------------------------===//
6848
6849extern "C" {
6850CXType clang_getIBOutletCollectionType(CXCursor C) {
6851 if (C.kind != CXCursor_IBOutletCollectionAttr)
6852 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6853
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006854 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006855 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6856
6857 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6858}
6859} // end: extern "C"
6860
6861//===----------------------------------------------------------------------===//
6862// Inspecting memory usage.
6863//===----------------------------------------------------------------------===//
6864
6865typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6866
6867static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6868 enum CXTUResourceUsageKind k,
6869 unsigned long amount) {
6870 CXTUResourceUsageEntry entry = { k, amount };
6871 entries.push_back(entry);
6872}
6873
6874extern "C" {
6875
6876const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6877 const char *str = "";
6878 switch (kind) {
6879 case CXTUResourceUsage_AST:
6880 str = "ASTContext: expressions, declarations, and types";
6881 break;
6882 case CXTUResourceUsage_Identifiers:
6883 str = "ASTContext: identifiers";
6884 break;
6885 case CXTUResourceUsage_Selectors:
6886 str = "ASTContext: selectors";
6887 break;
6888 case CXTUResourceUsage_GlobalCompletionResults:
6889 str = "Code completion: cached global results";
6890 break;
6891 case CXTUResourceUsage_SourceManagerContentCache:
6892 str = "SourceManager: content cache allocator";
6893 break;
6894 case CXTUResourceUsage_AST_SideTables:
6895 str = "ASTContext: side tables";
6896 break;
6897 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6898 str = "SourceManager: malloc'ed memory buffers";
6899 break;
6900 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6901 str = "SourceManager: mmap'ed memory buffers";
6902 break;
6903 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6904 str = "ExternalASTSource: malloc'ed memory buffers";
6905 break;
6906 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6907 str = "ExternalASTSource: mmap'ed memory buffers";
6908 break;
6909 case CXTUResourceUsage_Preprocessor:
6910 str = "Preprocessor: malloc'ed memory";
6911 break;
6912 case CXTUResourceUsage_PreprocessingRecord:
6913 str = "Preprocessor: PreprocessingRecord";
6914 break;
6915 case CXTUResourceUsage_SourceManager_DataStructures:
6916 str = "SourceManager: data structures and tables";
6917 break;
6918 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6919 str = "Preprocessor: header search tables";
6920 break;
6921 }
6922 return str;
6923}
6924
6925CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006926 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006927 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006928 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006929 return usage;
6930 }
6931
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006932 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006933 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006934 ASTContext &astContext = astUnit->getASTContext();
6935
6936 // How much memory is used by AST nodes and types?
6937 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6938 (unsigned long) astContext.getASTAllocatedMemory());
6939
6940 // How much memory is used by identifiers?
6941 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6942 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6943
6944 // How much memory is used for selectors?
6945 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6946 (unsigned long) astContext.Selectors.getTotalMemory());
6947
6948 // How much memory is used by ASTContext's side tables?
6949 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6950 (unsigned long) astContext.getSideTableAllocatedMemory());
6951
6952 // How much memory is used for caching global code completion results?
6953 unsigned long completionBytes = 0;
6954 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006955 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006956 completionBytes = completionAllocator->getTotalMemory();
6957 }
6958 createCXTUResourceUsageEntry(*entries,
6959 CXTUResourceUsage_GlobalCompletionResults,
6960 completionBytes);
6961
6962 // How much memory is being used by SourceManager's content cache?
6963 createCXTUResourceUsageEntry(*entries,
6964 CXTUResourceUsage_SourceManagerContentCache,
6965 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6966
6967 // How much memory is being used by the MemoryBuffer's in SourceManager?
6968 const SourceManager::MemoryBufferSizes &srcBufs =
6969 astUnit->getSourceManager().getMemoryBufferSizes();
6970
6971 createCXTUResourceUsageEntry(*entries,
6972 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6973 (unsigned long) srcBufs.malloc_bytes);
6974 createCXTUResourceUsageEntry(*entries,
6975 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6976 (unsigned long) srcBufs.mmap_bytes);
6977 createCXTUResourceUsageEntry(*entries,
6978 CXTUResourceUsage_SourceManager_DataStructures,
6979 (unsigned long) astContext.getSourceManager()
6980 .getDataStructureSizes());
6981
6982 // How much memory is being used by the ExternalASTSource?
6983 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6984 const ExternalASTSource::MemoryBufferSizes &sizes =
6985 esrc->getMemoryBufferSizes();
6986
6987 createCXTUResourceUsageEntry(*entries,
6988 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6989 (unsigned long) sizes.malloc_bytes);
6990 createCXTUResourceUsageEntry(*entries,
6991 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6992 (unsigned long) sizes.mmap_bytes);
6993 }
6994
6995 // How much memory is being used by the Preprocessor?
6996 Preprocessor &pp = astUnit->getPreprocessor();
6997 createCXTUResourceUsageEntry(*entries,
6998 CXTUResourceUsage_Preprocessor,
6999 pp.getTotalMemory());
7000
7001 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7002 createCXTUResourceUsageEntry(*entries,
7003 CXTUResourceUsage_PreprocessingRecord,
7004 pRec->getTotalMemory());
7005 }
7006
7007 createCXTUResourceUsageEntry(*entries,
7008 CXTUResourceUsage_Preprocessor_HeaderSearch,
7009 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007010
Guy Benyei11169dd2012-12-18 14:30:41 +00007011 CXTUResourceUsage usage = { (void*) entries.get(),
7012 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007013 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007014 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007015 return usage;
7016}
7017
7018void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7019 if (usage.data)
7020 delete (MemUsageEntries*) usage.data;
7021}
7022
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007023CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7024 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007025 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007026 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007027
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007028 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007029 LOG_BAD_TU(TU);
7030 return skipped;
7031 }
7032
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007033 if (!file)
7034 return skipped;
7035
7036 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7037 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7038 if (!ppRec)
7039 return skipped;
7040
7041 ASTContext &Ctx = astUnit->getASTContext();
7042 SourceManager &sm = Ctx.getSourceManager();
7043 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7044 FileID wantedFileID = sm.translateFile(fileEntry);
7045
7046 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7047 std::vector<SourceRange> wantedRanges;
7048 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7049 i != ei; ++i) {
7050 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7051 wantedRanges.push_back(*i);
7052 }
7053
7054 skipped->count = wantedRanges.size();
7055 skipped->ranges = new CXSourceRange[skipped->count];
7056 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7057 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7058
7059 return skipped;
7060}
7061
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007062void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7063 if (ranges) {
7064 delete[] ranges->ranges;
7065 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007066 }
7067}
7068
Guy Benyei11169dd2012-12-18 14:30:41 +00007069} // end extern "C"
7070
7071void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7072 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7073 for (unsigned I = 0; I != Usage.numEntries; ++I)
7074 fprintf(stderr, " %s: %lu\n",
7075 clang_getTUResourceUsageName(Usage.entries[I].kind),
7076 Usage.entries[I].amount);
7077
7078 clang_disposeCXTUResourceUsage(Usage);
7079}
7080
7081//===----------------------------------------------------------------------===//
7082// Misc. utility functions.
7083//===----------------------------------------------------------------------===//
7084
7085/// Default to using an 8 MB stack size on "safety" threads.
7086static unsigned SafetyStackThreadSize = 8 << 20;
7087
7088namespace clang {
7089
7090bool RunSafely(llvm::CrashRecoveryContext &CRC,
7091 void (*Fn)(void*), void *UserData,
7092 unsigned Size) {
7093 if (!Size)
7094 Size = GetSafetyThreadStackSize();
7095 if (Size)
7096 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7097 return CRC.RunSafely(Fn, UserData);
7098}
7099
7100unsigned GetSafetyThreadStackSize() {
7101 return SafetyStackThreadSize;
7102}
7103
7104void SetSafetyThreadStackSize(unsigned Value) {
7105 SafetyStackThreadSize = Value;
7106}
7107
7108}
7109
7110void clang::setThreadBackgroundPriority() {
7111 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7112 return;
7113
Alp Toker1a86ad22014-07-06 06:24:00 +00007114#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007115 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7116#endif
7117}
7118
7119void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7120 if (!Unit)
7121 return;
7122
7123 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7124 DEnd = Unit->stored_diag_end();
7125 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007126 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007127 CXString Msg = clang_formatDiagnostic(&Diag,
7128 clang_defaultDiagnosticDisplayOptions());
7129 fprintf(stderr, "%s\n", clang_getCString(Msg));
7130 clang_disposeString(Msg);
7131 }
7132#ifdef LLVM_ON_WIN32
7133 // On Windows, force a flush, since there may be multiple copies of
7134 // stderr and stdout in the file system, all with different buffers
7135 // but writing to the same device.
7136 fflush(stderr);
7137#endif
7138}
7139
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007140MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7141 SourceLocation MacroDefLoc,
7142 CXTranslationUnit TU){
7143 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007144 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007145 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007146 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007147
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007148 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007149 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007150 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007151 if (MD) {
7152 for (MacroDirective::DefInfo
7153 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7154 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7155 return Def.getMacroInfo();
7156 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007157 }
7158
Craig Topper69186e72014-06-08 08:38:04 +00007159 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007160}
7161
Richard Smith66a81862015-05-04 02:25:31 +00007162const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007163 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007164 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007165 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007166 const IdentifierInfo *II = MacroDef->getName();
7167 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007168 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007169
7170 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7171}
7172
Richard Smith66a81862015-05-04 02:25:31 +00007173MacroDefinitionRecord *
7174cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7175 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007176 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007177 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007178 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007179 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007180
7181 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007182 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007183 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7184 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007185 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007186
7187 // Check that the token is inside the definition and not its argument list.
7188 SourceManager &SM = Unit->getSourceManager();
7189 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007190 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007191 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007192 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007193
7194 Preprocessor &PP = Unit->getPreprocessor();
7195 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7196 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007197 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007198
Alp Toker2d57cea2014-05-17 04:53:25 +00007199 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007200 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007201 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007202
7203 // Check that the identifier is not one of the macro arguments.
7204 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007205 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007206
Richard Smith20e883e2015-04-29 23:20:19 +00007207 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007208 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007209 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007210
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007211 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007212}
7213
Richard Smith66a81862015-05-04 02:25:31 +00007214MacroDefinitionRecord *
7215cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7216 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007217 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007218 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007219
7220 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007221 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007222 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007223 Preprocessor &PP = Unit->getPreprocessor();
7224 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007225 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007226 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7227 Token Tok;
7228 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007229 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007230
7231 return checkForMacroInMacroDefinition(MI, Tok, TU);
7232}
7233
Guy Benyei11169dd2012-12-18 14:30:41 +00007234extern "C" {
7235
7236CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007237 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007238}
7239
7240} // end: extern "C"
7241
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007242Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7243 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007244 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007245 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007246 if (Unit->isMainFileAST())
7247 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007248 return *this;
7249 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007250 } else {
7251 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007252 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007253 return *this;
7254}
7255
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007256Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7257 *this << FE->getName();
7258 return *this;
7259}
7260
7261Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7262 CXString cursorName = clang_getCursorDisplayName(cursor);
7263 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7264 clang_disposeString(cursorName);
7265 return *this;
7266}
7267
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007268Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7269 CXFile File;
7270 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007271 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007272 CXString FileName = clang_getFileName(File);
7273 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7274 clang_disposeString(FileName);
7275 return *this;
7276}
7277
7278Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7279 CXSourceLocation BLoc = clang_getRangeStart(range);
7280 CXSourceLocation ELoc = clang_getRangeEnd(range);
7281
7282 CXFile BFile;
7283 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007284 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007285
7286 CXFile EFile;
7287 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007288 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007289
7290 CXString BFileName = clang_getFileName(BFile);
7291 if (BFile == EFile) {
7292 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7293 BLine, BColumn, ELine, EColumn);
7294 } else {
7295 CXString EFileName = clang_getFileName(EFile);
7296 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7297 BLine, BColumn)
7298 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7299 ELine, EColumn);
7300 clang_disposeString(EFileName);
7301 }
7302 clang_disposeString(BFileName);
7303 return *this;
7304}
7305
7306Logger &cxindex::Logger::operator<<(CXString Str) {
7307 *this << clang_getCString(Str);
7308 return *this;
7309}
7310
7311Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7312 LogOS << Fmt;
7313 return *this;
7314}
7315
Chandler Carruth37ad2582014-06-27 15:14:39 +00007316static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7317
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007318cxindex::Logger::~Logger() {
7319 LogOS.flush();
7320
Chandler Carruth37ad2582014-06-27 15:14:39 +00007321 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007322
7323 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7324
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007325 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007326 OS << "[libclang:" << Name << ':';
7327
Alp Toker1a86ad22014-07-06 06:24:00 +00007328#ifdef USE_DARWIN_THREADS
7329 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007330 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7331 OS << tid << ':';
7332#endif
7333
7334 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7335 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007336 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007337
7338 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007339 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007340 OS << "--------------------------------------------------\n";
7341 }
7342}