blob: eaecd64dbe8c0477eef97deb3ecae68404543b0c [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;
457
458 continue;
459 }
460
461 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
462 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
463 return true;
464
465 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);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000571 if (MacroDefinition *MacroDef =
572 checkForMacroInMacroDefinition(MI, Loc, TU))
573 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());
1985}
1986
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001987void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1988
Alexey Bataev236070f2014-06-20 11:19:47 +00001989void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1990
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001991void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1992
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001993void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1994
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001995void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1996
Alexey Bataevdea47612014-07-23 07:46:59 +00001997void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1998
Alexey Bataev67a4f222014-07-23 10:25:33 +00001999void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2000
Alexey Bataev459dec02014-07-24 06:46:57 +00002001void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2002
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002003void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2004
Alexey Bataev756c1962013-09-24 03:17:45 +00002005template<typename T>
2006void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002007 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002008 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002009 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002010}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002011
2012void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002013 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002014 for (const auto *E : C->private_copies()) {
2015 Visitor->AddStmt(E);
2016 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002017}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002018void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2019 const OMPFirstprivateClause *C) {
2020 VisitOMPClauseList(C);
2021}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002022void OMPClauseEnqueue::VisitOMPLastprivateClause(
2023 const OMPLastprivateClause *C) {
2024 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002025 for (auto *E : C->private_copies()) {
2026 Visitor->AddStmt(E);
2027 }
2028 for (auto *E : C->source_exprs()) {
2029 Visitor->AddStmt(E);
2030 }
2031 for (auto *E : C->destination_exprs()) {
2032 Visitor->AddStmt(E);
2033 }
2034 for (auto *E : C->assignment_ops()) {
2035 Visitor->AddStmt(E);
2036 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002037}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002038void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002039 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002040}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002041void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2042 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002043 for (auto *E : C->lhs_exprs()) {
2044 Visitor->AddStmt(E);
2045 }
2046 for (auto *E : C->rhs_exprs()) {
2047 Visitor->AddStmt(E);
2048 }
2049 for (auto *E : C->reduction_ops()) {
2050 Visitor->AddStmt(E);
2051 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002052}
Alexander Musman8dba6642014-04-22 13:09:42 +00002053void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2054 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002055 for (const auto *E : C->inits()) {
2056 Visitor->AddStmt(E);
2057 }
2058 for (const auto *E : C->updates()) {
2059 Visitor->AddStmt(E);
2060 }
2061 for (const auto *E : C->finals()) {
2062 Visitor->AddStmt(E);
2063 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002064 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002065 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002066}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002067void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2068 VisitOMPClauseList(C);
2069 Visitor->AddStmt(C->getAlignment());
2070}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002071void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2072 VisitOMPClauseList(C);
2073}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002074void
2075OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2076 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002077 for (auto *E : C->source_exprs()) {
2078 Visitor->AddStmt(E);
2079 }
2080 for (auto *E : C->destination_exprs()) {
2081 Visitor->AddStmt(E);
2082 }
2083 for (auto *E : C->assignment_ops()) {
2084 Visitor->AddStmt(E);
2085 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002086}
Alexey Bataev6125da92014-07-21 11:26:11 +00002087void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2088 VisitOMPClauseList(C);
2089}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002090}
Alexey Bataev756c1962013-09-24 03:17:45 +00002091
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002092void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2093 unsigned size = WL.size();
2094 OMPClauseEnqueue Visitor(this);
2095 Visitor.Visit(S);
2096 if (size == WL.size())
2097 return;
2098 // Now reverse the entries we just added. This will match the DFS
2099 // ordering performed by the worklist.
2100 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2101 std::reverse(I, E);
2102}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002103void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002104 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2105}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002106void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002107 AddDecl(B->getBlockDecl());
2108}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002110 EnqueueChildren(E);
2111 AddTypeLoc(E->getTypeSourceInfo());
2112}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002113void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2114 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002115 E = S->body_rend(); I != E; ++I) {
2116 AddStmt(*I);
2117 }
2118}
2119void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 AddStmt(S->getSubStmt());
2122 AddDeclarationNameInfo(S);
2123 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2124 AddNestedNameSpecifierLoc(QualifierLoc);
2125}
2126
2127void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002128VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002129 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2130 AddDeclarationNameInfo(E);
2131 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2132 AddNestedNameSpecifierLoc(QualifierLoc);
2133 if (!E->isImplicitAccess())
2134 AddStmt(E->getBase());
2135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 // Enqueue the initializer , if any.
2138 AddStmt(E->getInitializer());
2139 // Enqueue the array size, if any.
2140 AddStmt(E->getArraySize());
2141 // Enqueue the allocated type.
2142 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2143 // Enqueue the placement arguments.
2144 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2145 AddStmt(E->getPlacementArg(I-1));
2146}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2149 AddStmt(CE->getArg(I-1));
2150 AddStmt(CE->getCallee());
2151 AddStmt(CE->getArg(0));
2152}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2154 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 // Visit the name of the type being destroyed.
2156 AddTypeLoc(E->getDestroyedTypeInfo());
2157 // Visit the scope type that looks disturbingly like the nested-name-specifier
2158 // but isn't.
2159 AddTypeLoc(E->getScopeTypeInfo());
2160 // Visit the nested-name-specifier.
2161 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2162 AddNestedNameSpecifierLoc(QualifierLoc);
2163 // Visit base expression.
2164 AddStmt(E->getBase());
2165}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002166void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2167 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002168 AddTypeLoc(E->getTypeSourceInfo());
2169}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002170void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2171 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 EnqueueChildren(E);
2173 AddTypeLoc(E->getTypeSourceInfo());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 EnqueueChildren(E);
2177 if (E->isTypeOperand())
2178 AddTypeLoc(E->getTypeOperandSourceInfo());
2179}
2180
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2182 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 EnqueueChildren(E);
2184 AddTypeLoc(E->getTypeSourceInfo());
2185}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002186void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002187 EnqueueChildren(E);
2188 if (E->isTypeOperand())
2189 AddTypeLoc(E->getTypeOperandSourceInfo());
2190}
2191
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 EnqueueChildren(S);
2194 AddDecl(S->getExceptionDecl());
2195}
2196
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002197void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002198 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002199 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002200 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002201}
2202
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 if (DR->hasExplicitTemplateArgs()) {
2205 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2206 }
2207 WL.push_back(DeclRefExprParts(DR, Parent));
2208}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2210 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002211 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2212 AddDeclarationNameInfo(E);
2213 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2214}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 unsigned size = WL.size();
2217 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002218 for (const auto *D : S->decls()) {
2219 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 isFirst = false;
2221 }
2222 if (size == WL.size())
2223 return;
2224 // Now reverse the entries we just added. This will match the DFS
2225 // ordering performed by the worklist.
2226 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2227 std::reverse(I, E);
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 D = E->designators_rbegin(), DEnd = E->designators_rend();
2233 D != DEnd; ++D) {
2234 if (D->isFieldDesignator()) {
2235 if (FieldDecl *Field = D->getField())
2236 AddMemberRef(Field, D->getFieldLoc());
2237 continue;
2238 }
2239 if (D->isArrayDesignator()) {
2240 AddStmt(E->getArrayIndex(*D));
2241 continue;
2242 }
2243 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2244 AddStmt(E->getArrayRangeEnd(*D));
2245 AddStmt(E->getArrayRangeStart(*D));
2246 }
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 EnqueueChildren(E);
2250 AddTypeLoc(E->getTypeInfoAsWritten());
2251}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 AddStmt(FS->getBody());
2254 AddStmt(FS->getInc());
2255 AddStmt(FS->getCond());
2256 AddDecl(FS->getConditionVariable());
2257 AddStmt(FS->getInit());
2258}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2261}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 AddStmt(If->getElse());
2264 AddStmt(If->getThen());
2265 AddStmt(If->getCond());
2266 AddDecl(If->getConditionVariable());
2267}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 // We care about the syntactic form of the initializer list, only.
2270 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2271 IE = Syntactic;
2272 EnqueueChildren(IE);
2273}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 WL.push_back(MemberExprParts(M, Parent));
2276
2277 // If the base of the member access expression is an implicit 'this', don't
2278 // visit it.
2279 // FIXME: If we ever want to show these implicit accesses, this will be
2280 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002281 if (M->isImplicitAccess())
2282 return;
2283
2284 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2285 // real field that that we are interested in.
2286 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2287 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2288 if (FD->isAnonymousStructOrUnion()) {
2289 AddStmt(SubME->getBase());
2290 return;
2291 }
2292 }
2293 }
2294
2295 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002296}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002298 AddTypeLoc(E->getEncodedTypeSourceInfo());
2299}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002300void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002301 EnqueueChildren(M);
2302 AddTypeLoc(M->getClassReceiverTypeInfo());
2303}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002304void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002305 // Visit the components of the offsetof expression.
2306 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2307 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2308 const OffsetOfNode &Node = E->getComponent(I-1);
2309 switch (Node.getKind()) {
2310 case OffsetOfNode::Array:
2311 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2312 break;
2313 case OffsetOfNode::Field:
2314 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2315 break;
2316 case OffsetOfNode::Identifier:
2317 case OffsetOfNode::Base:
2318 continue;
2319 }
2320 }
2321 // Visit the type into which we're computing the offset.
2322 AddTypeLoc(E->getTypeSourceInfo());
2323}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002324void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002325 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2326 WL.push_back(OverloadExprParts(E, Parent));
2327}
2328void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002329 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002330 EnqueueChildren(E);
2331 if (E->isArgumentType())
2332 AddTypeLoc(E->getArgumentTypeInfo());
2333}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002334void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002335 EnqueueChildren(S);
2336}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002337void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002338 AddStmt(S->getBody());
2339 AddStmt(S->getCond());
2340 AddDecl(S->getConditionVariable());
2341}
2342
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002343void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002344 AddStmt(W->getBody());
2345 AddStmt(W->getCond());
2346 AddDecl(W->getConditionVariable());
2347}
2348
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002349void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002350 for (unsigned I = E->getNumArgs(); I > 0; --I)
2351 AddTypeLoc(E->getArg(I-1));
2352}
2353
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002354void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002355 AddTypeLoc(E->getQueriedTypeSourceInfo());
2356}
2357
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002358void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002359 EnqueueChildren(E);
2360}
2361
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002362void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002363 VisitOverloadExpr(U);
2364 if (!U->isImplicitAccess())
2365 AddStmt(U->getBase());
2366}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002367void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002368 AddStmt(E->getSubExpr());
2369 AddTypeLoc(E->getWrittenTypeInfo());
2370}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002371void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002372 WL.push_back(SizeOfPackExprParts(E, Parent));
2373}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002374void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002375 // If the opaque value has a source expression, just transparently
2376 // visit that. This is useful for (e.g.) pseudo-object expressions.
2377 if (Expr *SourceExpr = E->getSourceExpr())
2378 return Visit(SourceExpr);
2379}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002380void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002381 AddStmt(E->getBody());
2382 WL.push_back(LambdaExprParts(E, Parent));
2383}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002384void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002385 // Treat the expression like its syntactic form.
2386 Visit(E->getSyntacticForm());
2387}
2388
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002389void EnqueueVisitor::VisitOMPExecutableDirective(
2390 const OMPExecutableDirective *D) {
2391 EnqueueChildren(D);
2392 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2393 E = D->clauses().end();
2394 I != E; ++I)
2395 EnqueueChildren(*I);
2396}
2397
Alexander Musman3aaab662014-08-19 11:27:13 +00002398void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2399 VisitOMPExecutableDirective(D);
2400}
2401
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002402void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2403 VisitOMPExecutableDirective(D);
2404}
2405
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002406void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002407 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002408}
2409
Alexey Bataevf29276e2014-06-18 04:14:57 +00002410void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002411 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002412}
2413
Alexander Musmanf82886e2014-09-18 05:12:34 +00002414void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2415 VisitOMPLoopDirective(D);
2416}
2417
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002418void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2419 VisitOMPExecutableDirective(D);
2420}
2421
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002422void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2423 VisitOMPExecutableDirective(D);
2424}
2425
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002426void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2427 VisitOMPExecutableDirective(D);
2428}
2429
Alexander Musman80c22892014-07-17 08:54:58 +00002430void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2431 VisitOMPExecutableDirective(D);
2432}
2433
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002434void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2435 VisitOMPExecutableDirective(D);
2436 AddDeclarationNameInfo(D);
2437}
2438
Alexey Bataev4acb8592014-07-07 13:01:15 +00002439void
2440EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002441 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002442}
2443
Alexander Musmane4e893b2014-09-23 09:33:00 +00002444void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2445 const OMPParallelForSimdDirective *D) {
2446 VisitOMPLoopDirective(D);
2447}
2448
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002449void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2450 const OMPParallelSectionsDirective *D) {
2451 VisitOMPExecutableDirective(D);
2452}
2453
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002454void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2455 VisitOMPExecutableDirective(D);
2456}
2457
Alexey Bataev68446b72014-07-18 07:47:19 +00002458void
2459EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2460 VisitOMPExecutableDirective(D);
2461}
2462
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002463void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2464 VisitOMPExecutableDirective(D);
2465}
2466
Alexey Bataev2df347a2014-07-18 10:17:07 +00002467void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2468 VisitOMPExecutableDirective(D);
2469}
2470
Alexey Bataev6125da92014-07-21 11:26:11 +00002471void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2472 VisitOMPExecutableDirective(D);
2473}
2474
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002475void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2476 VisitOMPExecutableDirective(D);
2477}
2478
Alexey Bataev0162e452014-07-22 10:10:35 +00002479void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2480 VisitOMPExecutableDirective(D);
2481}
2482
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002483void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2484 VisitOMPExecutableDirective(D);
2485}
2486
Alexey Bataev13314bf2014-10-09 04:18:56 +00002487void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2488 VisitOMPExecutableDirective(D);
2489}
2490
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002491void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002492 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2493}
2494
2495bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2496 if (RegionOfInterest.isValid()) {
2497 SourceRange Range = getRawCursorExtent(C);
2498 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2499 return false;
2500 }
2501 return true;
2502}
2503
2504bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2505 while (!WL.empty()) {
2506 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002507 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002508
2509 // Set the Parent field, then back to its old value once we're done.
2510 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2511
2512 switch (LI.getKind()) {
2513 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002514 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002515 if (!D)
2516 continue;
2517
2518 // For now, perform default visitation for Decls.
2519 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2520 cast<DeclVisit>(&LI)->isFirst())))
2521 return true;
2522
2523 continue;
2524 }
2525 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2526 const ASTTemplateArgumentListInfo *ArgList =
2527 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2528 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2529 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2530 Arg != ArgEnd; ++Arg) {
2531 if (VisitTemplateArgumentLoc(*Arg))
2532 return true;
2533 }
2534 continue;
2535 }
2536 case VisitorJob::TypeLocVisitKind: {
2537 // Perform default visitation for TypeLocs.
2538 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2539 return true;
2540 continue;
2541 }
2542 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002543 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002544 if (LabelStmt *stmt = LS->getStmt()) {
2545 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2546 TU))) {
2547 return true;
2548 }
2549 }
2550 continue;
2551 }
2552
2553 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2554 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2555 if (VisitNestedNameSpecifierLoc(V->get()))
2556 return true;
2557 continue;
2558 }
2559
2560 case VisitorJob::DeclarationNameInfoVisitKind: {
2561 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2562 ->get()))
2563 return true;
2564 continue;
2565 }
2566 case VisitorJob::MemberRefVisitKind: {
2567 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2568 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2569 return true;
2570 continue;
2571 }
2572 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002573 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002574 if (!S)
2575 continue;
2576
2577 // Update the current cursor.
2578 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2579 if (!IsInRegionOfInterest(Cursor))
2580 continue;
2581 switch (Visitor(Cursor, Parent, ClientData)) {
2582 case CXChildVisit_Break: return true;
2583 case CXChildVisit_Continue: break;
2584 case CXChildVisit_Recurse:
2585 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002586 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002587 EnqueueWorkList(WL, S);
2588 break;
2589 }
2590 continue;
2591 }
2592 case VisitorJob::MemberExprPartsKind: {
2593 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002594 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002595
2596 // Visit the nested-name-specifier
2597 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2598 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2599 return true;
2600
2601 // Visit the declaration name.
2602 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2603 return true;
2604
2605 // Visit the explicitly-specified template arguments, if any.
2606 if (M->hasExplicitTemplateArgs()) {
2607 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2608 *ArgEnd = Arg + M->getNumTemplateArgs();
2609 Arg != ArgEnd; ++Arg) {
2610 if (VisitTemplateArgumentLoc(*Arg))
2611 return true;
2612 }
2613 }
2614 continue;
2615 }
2616 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002617 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002618 // Visit nested-name-specifier, if present.
2619 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2620 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2621 return true;
2622 // Visit declaration name.
2623 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2624 return true;
2625 continue;
2626 }
2627 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002628 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002629 // Visit the nested-name-specifier.
2630 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2631 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2632 return true;
2633 // Visit the declaration name.
2634 if (VisitDeclarationNameInfo(O->getNameInfo()))
2635 return true;
2636 // Visit the overloaded declaration reference.
2637 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2638 return true;
2639 continue;
2640 }
2641 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002642 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002643 NamedDecl *Pack = E->getPack();
2644 if (isa<TemplateTypeParmDecl>(Pack)) {
2645 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2646 E->getPackLoc(), TU)))
2647 return true;
2648
2649 continue;
2650 }
2651
2652 if (isa<TemplateTemplateParmDecl>(Pack)) {
2653 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2654 E->getPackLoc(), TU)))
2655 return true;
2656
2657 continue;
2658 }
2659
2660 // Non-type template parameter packs and function parameter packs are
2661 // treated like DeclRefExpr cursors.
2662 continue;
2663 }
2664
2665 case VisitorJob::LambdaExprPartsKind: {
2666 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002667 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002668 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2669 CEnd = E->explicit_capture_end();
2670 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002671 // FIXME: Lambda init-captures.
2672 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002673 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002674
Guy Benyei11169dd2012-12-18 14:30:41 +00002675 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2676 C->getLocation(),
2677 TU)))
2678 return true;
2679 }
2680
2681 // Visit parameters and return type, if present.
2682 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2683 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2684 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2685 // Visit the whole type.
2686 if (Visit(TL))
2687 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002688 } else if (FunctionProtoTypeLoc Proto =
2689 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002690 if (E->hasExplicitParameters()) {
2691 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002692 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2693 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002694 return true;
2695 } else {
2696 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002697 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002698 return true;
2699 }
2700 }
2701 }
2702 break;
2703 }
2704
2705 case VisitorJob::PostChildrenVisitKind:
2706 if (PostChildrenVisitor(Parent, ClientData))
2707 return true;
2708 break;
2709 }
2710 }
2711 return false;
2712}
2713
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002714bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002715 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002716 if (!WorkListFreeList.empty()) {
2717 WL = WorkListFreeList.back();
2718 WL->clear();
2719 WorkListFreeList.pop_back();
2720 }
2721 else {
2722 WL = new VisitorWorkList();
2723 WorkListCache.push_back(WL);
2724 }
2725 EnqueueWorkList(*WL, S);
2726 bool result = RunVisitorWorkList(*WL);
2727 WorkListFreeList.push_back(WL);
2728 return result;
2729}
2730
2731namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002732typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002733RefNamePieces
2734buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2735 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2736 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002737 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2738 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2739 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2740
2741 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2742
2743 RefNamePieces Pieces;
2744
2745 if (WantQualifier && QLoc.isValid())
2746 Pieces.push_back(QLoc);
2747
2748 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2749 Pieces.push_back(NI.getLoc());
2750
2751 if (WantTemplateArgs && TemplateArgs)
2752 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2753 TemplateArgs->RAngleLoc));
2754
2755 if (Kind == DeclarationName::CXXOperatorName) {
2756 Pieces.push_back(SourceLocation::getFromRawEncoding(
2757 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2758 Pieces.push_back(SourceLocation::getFromRawEncoding(
2759 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2760 }
2761
2762 if (WantSinglePiece) {
2763 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2764 Pieces.clear();
2765 Pieces.push_back(R);
2766 }
2767
2768 return Pieces;
2769}
2770}
2771
2772//===----------------------------------------------------------------------===//
2773// Misc. API hooks.
2774//===----------------------------------------------------------------------===//
2775
Chad Rosier05c71aa2013-03-27 18:28:23 +00002776static void fatal_error_handler(void *user_data, const std::string& reason,
2777 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002778 // Write the result out to stderr avoiding errs() because raw_ostreams can
2779 // call report_fatal_error.
2780 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2781 ::abort();
2782}
2783
Chandler Carruth66660742014-06-27 16:37:27 +00002784namespace {
2785struct RegisterFatalErrorHandler {
2786 RegisterFatalErrorHandler() {
2787 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2788 }
2789};
2790}
2791
2792static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2793
Guy Benyei11169dd2012-12-18 14:30:41 +00002794extern "C" {
2795CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2796 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002797 // We use crash recovery to make some of our APIs more reliable, implicitly
2798 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002799 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2800 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002801
Chandler Carruth66660742014-06-27 16:37:27 +00002802 // Look through the managed static to trigger construction of the managed
2803 // static which registers our fatal error handler. This ensures it is only
2804 // registered once.
2805 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002806
2807 CIndexer *CIdxr = new CIndexer();
2808 if (excludeDeclarationsFromPCH)
2809 CIdxr->setOnlyLocalDecls();
2810 if (displayDiagnostics)
2811 CIdxr->setDisplayDiagnostics();
2812
2813 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2814 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2815 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2816 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2817 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2818 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2819
2820 return CIdxr;
2821}
2822
2823void clang_disposeIndex(CXIndex CIdx) {
2824 if (CIdx)
2825 delete static_cast<CIndexer *>(CIdx);
2826}
2827
2828void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2829 if (CIdx)
2830 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2831}
2832
2833unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2834 if (CIdx)
2835 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2836 return 0;
2837}
2838
2839void clang_toggleCrashRecovery(unsigned isEnabled) {
2840 if (isEnabled)
2841 llvm::CrashRecoveryContext::Enable();
2842 else
2843 llvm::CrashRecoveryContext::Disable();
2844}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002845
Guy Benyei11169dd2012-12-18 14:30:41 +00002846CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2847 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002848 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002849 enum CXErrorCode Result =
2850 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002851 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002852 assert((TU && Result == CXError_Success) ||
2853 (!TU && Result != CXError_Success));
2854 return TU;
2855}
2856
2857enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2858 const char *ast_filename,
2859 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002860 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002861 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002862
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002863 if (!CIdx || !ast_filename || !out_TU)
2864 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002865
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002866 LOG_FUNC_SECTION {
2867 *Log << ast_filename;
2868 }
2869
Guy Benyei11169dd2012-12-18 14:30:41 +00002870 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2871 FileSystemOptions FileSystemOpts;
2872
Justin Bognerd512c1e2014-10-15 00:33:06 +00002873 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2874 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002875 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2876 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2877 /*CaptureDiagnostics=*/true,
2878 /*AllowPCHWithCompilerErrors=*/true,
2879 /*UserFilesAreVolatile=*/true);
2880 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002881 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002882}
2883
2884unsigned clang_defaultEditingTranslationUnitOptions() {
2885 return CXTranslationUnit_PrecompiledPreamble |
2886 CXTranslationUnit_CacheCompletionResults;
2887}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002888
Guy Benyei11169dd2012-12-18 14:30:41 +00002889CXTranslationUnit
2890clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2891 const char *source_filename,
2892 int num_command_line_args,
2893 const char * const *command_line_args,
2894 unsigned num_unsaved_files,
2895 struct CXUnsavedFile *unsaved_files) {
2896 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2897 return clang_parseTranslationUnit(CIdx, source_filename,
2898 command_line_args, num_command_line_args,
2899 unsaved_files, num_unsaved_files,
2900 Options);
2901}
2902
2903struct ParseTranslationUnitInfo {
2904 CXIndex CIdx;
2905 const char *source_filename;
2906 const char *const *command_line_args;
2907 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002908 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002909 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002910 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002911 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002912};
2913static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002914 const ParseTranslationUnitInfo *PTUI =
2915 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002916 CXIndex CIdx = PTUI->CIdx;
2917 const char *source_filename = PTUI->source_filename;
2918 const char * const *command_line_args = PTUI->command_line_args;
2919 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002920 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002921 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002922
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002923 // Set up the initial return values.
2924 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002925 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002926
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002927 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002928 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002929 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002930 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002931 }
2932
Guy Benyei11169dd2012-12-18 14:30:41 +00002933 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2934
2935 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2936 setThreadBackgroundPriority();
2937
2938 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2939 // FIXME: Add a flag for modules.
2940 TranslationUnitKind TUKind
2941 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002942 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002943 = options & CXTranslationUnit_CacheCompletionResults;
2944 bool IncludeBriefCommentsInCodeCompletion
2945 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2946 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2947 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2948
2949 // Configure the diagnostics.
2950 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002951 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002952
2953 // Recover resources if we crash before exiting this function.
2954 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2955 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002956 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002957
Ahmed Charlesb8984322014-03-07 20:03:18 +00002958 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2959 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002960
2961 // Recover resources if we crash before exiting this function.
2962 llvm::CrashRecoveryContextCleanupRegistrar<
2963 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2964
Alp Toker9d85b182014-07-07 01:23:14 +00002965 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002966 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002967 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002968 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002969 }
2970
Ahmed Charlesb8984322014-03-07 20:03:18 +00002971 std::unique_ptr<std::vector<const char *>> Args(
2972 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002973
2974 // Recover resources if we crash before exiting this method.
2975 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2976 ArgsCleanup(Args.get());
2977
2978 // Since the Clang C library is primarily used by batch tools dealing with
2979 // (often very broken) source code, where spell-checking can have a
2980 // significant negative impact on performance (particularly when
2981 // precompiled headers are involved), we disable it by default.
2982 // Only do this if we haven't found a spell-checking-related argument.
2983 bool FoundSpellCheckingArgument = false;
2984 for (int I = 0; I != num_command_line_args; ++I) {
2985 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2986 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2987 FoundSpellCheckingArgument = true;
2988 break;
2989 }
2990 }
2991 if (!FoundSpellCheckingArgument)
2992 Args->push_back("-fno-spell-checking");
2993
2994 Args->insert(Args->end(), command_line_args,
2995 command_line_args + num_command_line_args);
2996
2997 // The 'source_filename' argument is optional. If the caller does not
2998 // specify it then it is assumed that the source file is specified
2999 // in the actual argument list.
3000 // Put the source file after command_line_args otherwise if '-x' flag is
3001 // present it will be unused.
3002 if (source_filename)
3003 Args->push_back(source_filename);
3004
3005 // Do we need the detailed preprocessing record?
3006 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3007 Args->push_back("-Xclang");
3008 Args->push_back("-detailed-preprocessing-record");
3009 }
3010
3011 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003012 std::unique_ptr<ASTUnit> ErrUnit;
3013 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00003014 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003015 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3016 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3017 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3018 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3019 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3020 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003021
3022 if (NumErrors != Diags->getClient()->getNumErrors()) {
3023 // Make sure to check that 'Unit' is non-NULL.
3024 if (CXXIdx->getDisplayDiagnostics())
3025 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3026 }
3027
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003028 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3029 PTUI->result = CXError_ASTReadError;
3030 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003031 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003032 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3033 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003034}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003035
3036CXTranslationUnit
3037clang_parseTranslationUnit(CXIndex CIdx,
3038 const char *source_filename,
3039 const char *const *command_line_args,
3040 int num_command_line_args,
3041 struct CXUnsavedFile *unsaved_files,
3042 unsigned num_unsaved_files,
3043 unsigned options) {
3044 CXTranslationUnit TU;
3045 enum CXErrorCode Result = clang_parseTranslationUnit2(
3046 CIdx, source_filename, command_line_args, num_command_line_args,
3047 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003048 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003049 assert((TU && Result == CXError_Success) ||
3050 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003051 return TU;
3052}
3053
3054enum CXErrorCode clang_parseTranslationUnit2(
3055 CXIndex CIdx,
3056 const char *source_filename,
3057 const char *const *command_line_args,
3058 int num_command_line_args,
3059 struct CXUnsavedFile *unsaved_files,
3060 unsigned num_unsaved_files,
3061 unsigned options,
3062 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003063 LOG_FUNC_SECTION {
3064 *Log << source_filename << ": ";
3065 for (int i = 0; i != num_command_line_args; ++i)
3066 *Log << command_line_args[i] << " ";
3067 }
3068
Alp Toker9d85b182014-07-07 01:23:14 +00003069 if (num_unsaved_files && !unsaved_files)
3070 return CXError_InvalidArguments;
3071
Alp Toker5c532982014-07-07 22:42:03 +00003072 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003073 ParseTranslationUnitInfo PTUI = {
3074 CIdx,
3075 source_filename,
3076 command_line_args,
3077 num_command_line_args,
3078 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3079 options,
3080 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003081 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003082 llvm::CrashRecoveryContext CRC;
3083
3084 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3085 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3086 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3087 fprintf(stderr, " 'command_line_args' : [");
3088 for (int i = 0; i != num_command_line_args; ++i) {
3089 if (i)
3090 fprintf(stderr, ", ");
3091 fprintf(stderr, "'%s'", command_line_args[i]);
3092 }
3093 fprintf(stderr, "],\n");
3094 fprintf(stderr, " 'unsaved_files' : [");
3095 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3096 if (i)
3097 fprintf(stderr, ", ");
3098 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3099 unsaved_files[i].Length);
3100 }
3101 fprintf(stderr, "],\n");
3102 fprintf(stderr, " 'options' : %d,\n", options);
3103 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003104
3105 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003106 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003107 if (CXTranslationUnit *TU = PTUI.out_TU)
3108 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003109 }
Alp Toker5c532982014-07-07 22:42:03 +00003110
3111 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003112}
3113
3114unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3115 return CXSaveTranslationUnit_None;
3116}
3117
3118namespace {
3119
3120struct SaveTranslationUnitInfo {
3121 CXTranslationUnit TU;
3122 const char *FileName;
3123 unsigned options;
3124 CXSaveError result;
3125};
3126
3127}
3128
3129static void clang_saveTranslationUnit_Impl(void *UserData) {
3130 SaveTranslationUnitInfo *STUI =
3131 static_cast<SaveTranslationUnitInfo*>(UserData);
3132
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003133 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003134 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3135 setThreadBackgroundPriority();
3136
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003137 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3139}
3140
3141int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3142 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003143 LOG_FUNC_SECTION {
3144 *Log << TU << ' ' << FileName;
3145 }
3146
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003147 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003148 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003150 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003151
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003152 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003153 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3154 if (!CXXUnit->hasSema())
3155 return CXSaveError_InvalidTU;
3156
3157 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3158
3159 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3160 getenv("LIBCLANG_NOTHREADS")) {
3161 clang_saveTranslationUnit_Impl(&STUI);
3162
3163 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3164 PrintLibclangResourceUsage(TU);
3165
3166 return STUI.result;
3167 }
3168
3169 // We have an AST that has invalid nodes due to compiler errors.
3170 // Use a crash recovery thread for protection.
3171
3172 llvm::CrashRecoveryContext CRC;
3173
3174 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3175 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3176 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3177 fprintf(stderr, " 'options' : %d,\n", options);
3178 fprintf(stderr, "}\n");
3179
3180 return CXSaveError_Unknown;
3181
3182 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3183 PrintLibclangResourceUsage(TU);
3184 }
3185
3186 return STUI.result;
3187}
3188
3189void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3190 if (CTUnit) {
3191 // If the translation unit has been marked as unsafe to free, just discard
3192 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003193 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3194 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 return;
3196
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003197 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003198 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003199 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3200 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003201 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 delete CTUnit;
3203 }
3204}
3205
3206unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3207 return CXReparse_None;
3208}
3209
3210struct ReparseTranslationUnitInfo {
3211 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003212 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003214 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003215};
3216
3217static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003218 const ReparseTranslationUnitInfo *RTUI =
3219 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003221 unsigned options = RTUI->options;
3222 (void) options;
3223
3224 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003225 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003226 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003227 RTUI->result = CXError_InvalidArguments;
3228 return;
3229 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003230
3231 // Reset the associated diagnostics.
3232 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003233 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003234
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003235 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3237 setThreadBackgroundPriority();
3238
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003239 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003240 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003241
3242 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3243 new std::vector<ASTUnit::RemappedFile>());
3244
Guy Benyei11169dd2012-12-18 14:30:41 +00003245 // Recover resources if we crash before exiting this function.
3246 llvm::CrashRecoveryContextCleanupRegistrar<
3247 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003248
3249 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003250 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003251 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003252 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003254
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003255 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003256 RTUI->result = CXError_Success;
3257 else if (isASTReadError(CXXUnit))
3258 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003259}
3260
3261int clang_reparseTranslationUnit(CXTranslationUnit TU,
3262 unsigned num_unsaved_files,
3263 struct CXUnsavedFile *unsaved_files,
3264 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003265 LOG_FUNC_SECTION {
3266 *Log << TU;
3267 }
3268
Alp Toker9d85b182014-07-07 01:23:14 +00003269 if (num_unsaved_files && !unsaved_files)
3270 return CXError_InvalidArguments;
3271
Alp Toker5c532982014-07-07 22:42:03 +00003272 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003273 ReparseTranslationUnitInfo RTUI = {
3274 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003275 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003276
3277 if (getenv("LIBCLANG_NOTHREADS")) {
3278 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003279 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 }
3281
3282 llvm::CrashRecoveryContext CRC;
3283
3284 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3285 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003286 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003287 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3289 PrintLibclangResourceUsage(TU);
3290
Alp Toker5c532982014-07-07 22:42:03 +00003291 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003292}
3293
3294
3295CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003296 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003297 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003298 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003299 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003300
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003301 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003302 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003303}
3304
3305CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003306 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003307 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003308 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003309 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003310
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003311 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003312 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3313}
3314
3315} // end: extern "C"
3316
3317//===----------------------------------------------------------------------===//
3318// CXFile Operations.
3319//===----------------------------------------------------------------------===//
3320
3321extern "C" {
3322CXString clang_getFileName(CXFile SFile) {
3323 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003324 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003325
3326 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003327 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003328}
3329
3330time_t clang_getFileTime(CXFile SFile) {
3331 if (!SFile)
3332 return 0;
3333
3334 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3335 return FEnt->getModificationTime();
3336}
3337
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003338CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003339 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003340 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003341 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003342 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003343
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003344 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003345
3346 FileManager &FMgr = CXXUnit->getFileManager();
3347 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3348}
3349
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003350unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3351 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003352 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003353 LOG_BAD_TU(TU);
3354 return 0;
3355 }
3356
3357 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 return 0;
3359
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003360 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 FileEntry *FEnt = static_cast<FileEntry *>(file);
3362 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3363 .isFileMultipleIncludeGuarded(FEnt);
3364}
3365
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003366int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3367 if (!file || !outID)
3368 return 1;
3369
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003370 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003371 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3372 outID->data[0] = ID.getDevice();
3373 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003374 outID->data[2] = FEnt->getModificationTime();
3375 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003376}
3377
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003378int clang_File_isEqual(CXFile file1, CXFile file2) {
3379 if (file1 == file2)
3380 return true;
3381
3382 if (!file1 || !file2)
3383 return false;
3384
3385 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3386 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3387 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3388}
3389
Guy Benyei11169dd2012-12-18 14:30:41 +00003390} // end: extern "C"
3391
3392//===----------------------------------------------------------------------===//
3393// CXCursor Operations.
3394//===----------------------------------------------------------------------===//
3395
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003396static const Decl *getDeclFromExpr(const Stmt *E) {
3397 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003398 return getDeclFromExpr(CE->getSubExpr());
3399
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003400 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003402 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003404 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003406 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 if (PRE->isExplicitProperty())
3408 return PRE->getExplicitProperty();
3409 // It could be messaging both getter and setter as in:
3410 // ++myobj.myprop;
3411 // in which case prefer to associate the setter since it is less obvious
3412 // from inspecting the source that the setter is going to get called.
3413 if (PRE->isMessagingSetter())
3414 return PRE->getImplicitPropertySetter();
3415 return PRE->getImplicitPropertyGetter();
3416 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003417 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003419 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 if (Expr *Src = OVE->getSourceExpr())
3421 return getDeclFromExpr(Src);
3422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003423 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003425 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 if (!CE->isElidable())
3427 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003428 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 return OME->getMethodDecl();
3430
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003431 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003433 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3435 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003436 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3438 isa<ParmVarDecl>(SizeOfPack->getPack()))
3439 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003440
3441 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003442}
3443
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003444static SourceLocation getLocationFromExpr(const Expr *E) {
3445 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 return getLocationFromExpr(CE->getSubExpr());
3447
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003448 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003449 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003450 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003451 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003452 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003454 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003456 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003458 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 return PropRef->getLocation();
3460
3461 return E->getLocStart();
3462}
3463
3464extern "C" {
3465
3466unsigned clang_visitChildren(CXCursor parent,
3467 CXCursorVisitor visitor,
3468 CXClientData client_data) {
3469 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3470 /*VisitPreprocessorLast=*/false);
3471 return CursorVis.VisitChildren(parent);
3472}
3473
3474#ifndef __has_feature
3475#define __has_feature(x) 0
3476#endif
3477#if __has_feature(blocks)
3478typedef enum CXChildVisitResult
3479 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3480
3481static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3482 CXClientData client_data) {
3483 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3484 return block(cursor, parent);
3485}
3486#else
3487// If we are compiled with a compiler that doesn't have native blocks support,
3488// define and call the block manually, so the
3489typedef struct _CXChildVisitResult
3490{
3491 void *isa;
3492 int flags;
3493 int reserved;
3494 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3495 CXCursor);
3496} *CXCursorVisitorBlock;
3497
3498static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3499 CXClientData client_data) {
3500 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3501 return block->invoke(block, cursor, parent);
3502}
3503#endif
3504
3505
3506unsigned clang_visitChildrenWithBlock(CXCursor parent,
3507 CXCursorVisitorBlock block) {
3508 return clang_visitChildren(parent, visitWithBlock, block);
3509}
3510
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003511static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003513 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003514
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003515 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003517 if (const ObjCPropertyImplDecl *PropImpl =
3518 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003520 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003521
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003522 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003524 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003525
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003526 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 }
3528
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003529 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003530 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003531
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003532 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3534 // and returns different names. NamedDecl returns the class name and
3535 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003536 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003537
3538 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003539 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003540
3541 SmallString<1024> S;
3542 llvm::raw_svector_ostream os(S);
3543 ND->printName(os);
3544
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003545 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003546}
3547
3548CXString clang_getCursorSpelling(CXCursor C) {
3549 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003550 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003551
3552 if (clang_isReference(C.kind)) {
3553 switch (C.kind) {
3554 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003555 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003556 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 }
3558 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003559 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003560 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 }
3562 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003563 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003565 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 }
3567 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003568 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003569 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 }
3571 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003572 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 assert(Type && "Missing type decl");
3574
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003575 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 getAsString());
3577 }
3578 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003579 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 assert(Template && "Missing template decl");
3581
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003582 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 }
3584
3585 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003586 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003587 assert(NS && "Missing namespace decl");
3588
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003589 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 }
3591
3592 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003593 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 assert(Field && "Missing member decl");
3595
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003596 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 }
3598
3599 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003600 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 assert(Label && "Missing label");
3602
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003603 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 }
3605
3606 case CXCursor_OverloadedDeclRef: {
3607 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003608 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3609 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003610 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003611 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003613 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003614 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 OverloadedTemplateStorage *Ovl
3616 = Storage.get<OverloadedTemplateStorage*>();
3617 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003618 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003619 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 }
3621
3622 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003623 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 assert(Var && "Missing variable decl");
3625
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003626 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 }
3628
3629 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 }
3632 }
3633
3634 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003635 const Expr *E = getCursorExpr(C);
3636
3637 if (C.kind == CXCursor_ObjCStringLiteral ||
3638 C.kind == CXCursor_StringLiteral) {
3639 const StringLiteral *SLit;
3640 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3641 SLit = OSL->getString();
3642 } else {
3643 SLit = cast<StringLiteral>(E);
3644 }
3645 SmallString<256> Buf;
3646 llvm::raw_svector_ostream OS(Buf);
3647 SLit->outputString(OS);
3648 return cxstring::createDup(OS.str());
3649 }
3650
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003651 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 if (D)
3653 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003654 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 }
3656
3657 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003658 const Stmt *S = getCursorStmt(C);
3659 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003661
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003662 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 }
3664
3665 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 ->getNameStart());
3668
3669 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 ->getNameStart());
3672
3673 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003674 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003675
3676 if (clang_isDeclaration(C.kind))
3677 return getDeclSpelling(getCursorDecl(C));
3678
3679 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003680 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003681 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 }
3683
3684 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003685 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003686 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 }
3688
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003689 if (C.kind == CXCursor_PackedAttr) {
3690 return cxstring::createRef("packed");
3691 }
3692
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003693 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003694}
3695
3696CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3697 unsigned pieceIndex,
3698 unsigned options) {
3699 if (clang_Cursor_isNull(C))
3700 return clang_getNullRange();
3701
3702 ASTContext &Ctx = getCursorContext(C);
3703
3704 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003705 const Stmt *S = getCursorStmt(C);
3706 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 if (pieceIndex > 0)
3708 return clang_getNullRange();
3709 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3710 }
3711
3712 return clang_getNullRange();
3713 }
3714
3715 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003716 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3718 if (pieceIndex >= ME->getNumSelectorLocs())
3719 return clang_getNullRange();
3720 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3721 }
3722 }
3723
3724 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3725 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003726 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3728 if (pieceIndex >= MD->getNumSelectorLocs())
3729 return clang_getNullRange();
3730 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3731 }
3732 }
3733
3734 if (C.kind == CXCursor_ObjCCategoryDecl ||
3735 C.kind == CXCursor_ObjCCategoryImplDecl) {
3736 if (pieceIndex > 0)
3737 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003738 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3740 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003741 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3743 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3744 }
3745
3746 if (C.kind == CXCursor_ModuleImportDecl) {
3747 if (pieceIndex > 0)
3748 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003749 if (const ImportDecl *ImportD =
3750 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3752 if (!Locs.empty())
3753 return cxloc::translateSourceRange(Ctx,
3754 SourceRange(Locs.front(), Locs.back()));
3755 }
3756 return clang_getNullRange();
3757 }
3758
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003759 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3760 C.kind == CXCursor_ConversionFunction) {
3761 if (pieceIndex > 0)
3762 return clang_getNullRange();
3763 if (const FunctionDecl *FD =
3764 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3765 DeclarationNameInfo FunctionName = FD->getNameInfo();
3766 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3767 }
3768 return clang_getNullRange();
3769 }
3770
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 // FIXME: A CXCursor_InclusionDirective should give the location of the
3772 // filename, but we don't keep track of this.
3773
3774 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3775 // but we don't keep track of this.
3776
3777 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3778 // but we don't keep track of this.
3779
3780 // Default handling, give the location of the cursor.
3781
3782 if (pieceIndex > 0)
3783 return clang_getNullRange();
3784
3785 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3786 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3787 return cxloc::translateSourceRange(Ctx, Loc);
3788}
3789
Eli Bendersky44a206f2014-07-31 18:04:56 +00003790CXString clang_Cursor_getMangling(CXCursor C) {
3791 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3792 return cxstring::createEmpty();
3793
Eli Bendersky44a206f2014-07-31 18:04:56 +00003794 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003795 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003796 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3797 return cxstring::createEmpty();
3798
Eli Bendersky79759592014-08-01 15:01:10 +00003799 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003800 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003801 ASTContext &Ctx = ND->getASTContext();
3802 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003803
Eli Bendersky79759592014-08-01 15:01:10 +00003804 std::string FrontendBuf;
3805 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3806 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003807
Eli Bendersky79759592014-08-01 15:01:10 +00003808 // Now apply backend mangling.
3809 std::unique_ptr<llvm::DataLayout> DL(
3810 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3811 llvm::Mangler BackendMangler(DL.get());
3812
3813 std::string FinalBuf;
3814 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3815 BackendMangler.getNameWithPrefix(FinalBufOS,
3816 llvm::Twine(FrontendBufOS.str()));
3817
3818 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003819}
3820
Guy Benyei11169dd2012-12-18 14:30:41 +00003821CXString clang_getCursorDisplayName(CXCursor C) {
3822 if (!clang_isDeclaration(C.kind))
3823 return clang_getCursorSpelling(C);
3824
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003825 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003827 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003828
3829 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003830 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 D = FunTmpl->getTemplatedDecl();
3832
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003833 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 SmallString<64> Str;
3835 llvm::raw_svector_ostream OS(Str);
3836 OS << *Function;
3837 if (Function->getPrimaryTemplate())
3838 OS << "<>";
3839 OS << "(";
3840 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3841 if (I)
3842 OS << ", ";
3843 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3844 }
3845
3846 if (Function->isVariadic()) {
3847 if (Function->getNumParams())
3848 OS << ", ";
3849 OS << "...";
3850 }
3851 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003852 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 }
3854
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003855 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 SmallString<64> Str;
3857 llvm::raw_svector_ostream OS(Str);
3858 OS << *ClassTemplate;
3859 OS << "<";
3860 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3861 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3862 if (I)
3863 OS << ", ";
3864
3865 NamedDecl *Param = Params->getParam(I);
3866 if (Param->getIdentifier()) {
3867 OS << Param->getIdentifier()->getName();
3868 continue;
3869 }
3870
3871 // There is no parameter name, which makes this tricky. Try to come up
3872 // with something useful that isn't too long.
3873 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3874 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3875 else if (NonTypeTemplateParmDecl *NTTP
3876 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3877 OS << NTTP->getType().getAsString(Policy);
3878 else
3879 OS << "template<...> class";
3880 }
3881
3882 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003883 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 }
3885
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003886 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3888 // If the type was explicitly written, use that.
3889 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003890 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003891
Benjamin Kramer9170e912013-02-22 15:46:01 +00003892 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 llvm::raw_svector_ostream OS(Str);
3894 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003895 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 ClassSpec->getTemplateArgs().data(),
3897 ClassSpec->getTemplateArgs().size(),
3898 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003899 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 }
3901
3902 return clang_getCursorSpelling(C);
3903}
3904
3905CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3906 switch (Kind) {
3907 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004035 case CXCursor_ObjCSelfExpr:
4036 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004125 case CXCursor_SEHLeaveStmt:
4126 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004155 case CXCursor_PackedAttr:
4156 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004157 case CXCursor_PureAttr:
4158 return cxstring::createRef("attribute(pure)");
4159 case CXCursor_ConstAttr:
4160 return cxstring::createRef("attribute(const)");
4161 case CXCursor_NoDuplicateAttr:
4162 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004163 case CXCursor_CUDAConstantAttr:
4164 return cxstring::createRef("attribute(constant)");
4165 case CXCursor_CUDADeviceAttr:
4166 return cxstring::createRef("attribute(device)");
4167 case CXCursor_CUDAGlobalAttr:
4168 return cxstring::createRef("attribute(global)");
4169 case CXCursor_CUDAHostAttr:
4170 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004171 case CXCursor_CUDASharedAttr:
4172 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004218 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004220 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004221 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004222 return cxstring::createRef("OMPParallelDirective");
4223 case CXCursor_OMPSimdDirective:
4224 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004225 case CXCursor_OMPForDirective:
4226 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004227 case CXCursor_OMPForSimdDirective:
4228 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004229 case CXCursor_OMPSectionsDirective:
4230 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004231 case CXCursor_OMPSectionDirective:
4232 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004233 case CXCursor_OMPSingleDirective:
4234 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004235 case CXCursor_OMPMasterDirective:
4236 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004237 case CXCursor_OMPCriticalDirective:
4238 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004239 case CXCursor_OMPParallelForDirective:
4240 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004241 case CXCursor_OMPParallelForSimdDirective:
4242 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004243 case CXCursor_OMPParallelSectionsDirective:
4244 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004245 case CXCursor_OMPTaskDirective:
4246 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004247 case CXCursor_OMPTaskyieldDirective:
4248 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004249 case CXCursor_OMPBarrierDirective:
4250 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004251 case CXCursor_OMPTaskwaitDirective:
4252 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004253 case CXCursor_OMPFlushDirective:
4254 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004255 case CXCursor_OMPOrderedDirective:
4256 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004257 case CXCursor_OMPAtomicDirective:
4258 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004259 case CXCursor_OMPTargetDirective:
4260 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004261 case CXCursor_OMPTeamsDirective:
4262 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004263 case CXCursor_OverloadCandidate:
4264 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 }
4266
4267 llvm_unreachable("Unhandled CXCursorKind");
4268}
4269
4270struct GetCursorData {
4271 SourceLocation TokenBeginLoc;
4272 bool PointsAtMacroArgExpansion;
4273 bool VisitedObjCPropertyImplDecl;
4274 SourceLocation VisitedDeclaratorDeclStartLoc;
4275 CXCursor &BestCursor;
4276
4277 GetCursorData(SourceManager &SM,
4278 SourceLocation tokenBegin, CXCursor &outputCursor)
4279 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4280 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4281 VisitedObjCPropertyImplDecl = false;
4282 }
4283};
4284
4285static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4286 CXCursor parent,
4287 CXClientData client_data) {
4288 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4289 CXCursor *BestCursor = &Data->BestCursor;
4290
4291 // If we point inside a macro argument we should provide info of what the
4292 // token is so use the actual cursor, don't replace it with a macro expansion
4293 // cursor.
4294 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4295 return CXChildVisit_Recurse;
4296
4297 if (clang_isDeclaration(cursor.kind)) {
4298 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004299 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4301 if (MD->isImplicit())
4302 return CXChildVisit_Break;
4303
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004304 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4306 // Check that when we have multiple @class references in the same line,
4307 // that later ones do not override the previous ones.
4308 // If we have:
4309 // @class Foo, Bar;
4310 // source ranges for both start at '@', so 'Bar' will end up overriding
4311 // 'Foo' even though the cursor location was at 'Foo'.
4312 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4313 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004314 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4316 if (PrevID != ID &&
4317 !PrevID->isThisDeclarationADefinition() &&
4318 !ID->isThisDeclarationADefinition())
4319 return CXChildVisit_Break;
4320 }
4321
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004322 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4324 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4325 // Check that when we have multiple declarators in the same line,
4326 // that later ones do not override the previous ones.
4327 // If we have:
4328 // int Foo, Bar;
4329 // source ranges for both start at 'int', so 'Bar' will end up overriding
4330 // 'Foo' even though the cursor location was at 'Foo'.
4331 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4332 return CXChildVisit_Break;
4333 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4334
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004335 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004336 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4337 (void)PropImp;
4338 // Check that when we have multiple @synthesize in the same line,
4339 // that later ones do not override the previous ones.
4340 // If we have:
4341 // @synthesize Foo, Bar;
4342 // source ranges for both start at '@', so 'Bar' will end up overriding
4343 // 'Foo' even though the cursor location was at 'Foo'.
4344 if (Data->VisitedObjCPropertyImplDecl)
4345 return CXChildVisit_Break;
4346 Data->VisitedObjCPropertyImplDecl = true;
4347 }
4348 }
4349
4350 if (clang_isExpression(cursor.kind) &&
4351 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004352 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004353 // Avoid having the cursor of an expression replace the declaration cursor
4354 // when the expression source range overlaps the declaration range.
4355 // This can happen for C++ constructor expressions whose range generally
4356 // include the variable declaration, e.g.:
4357 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4358 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4359 D->getLocation() == Data->TokenBeginLoc)
4360 return CXChildVisit_Break;
4361 }
4362 }
4363
4364 // If our current best cursor is the construction of a temporary object,
4365 // don't replace that cursor with a type reference, because we want
4366 // clang_getCursor() to point at the constructor.
4367 if (clang_isExpression(BestCursor->kind) &&
4368 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4369 cursor.kind == CXCursor_TypeRef) {
4370 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4371 // as having the actual point on the type reference.
4372 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4373 return CXChildVisit_Recurse;
4374 }
4375
4376 *BestCursor = cursor;
4377 return CXChildVisit_Recurse;
4378}
4379
4380CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004381 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004382 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004383 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004384 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004385
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004386 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004387 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4388
4389 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4390 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4391
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004392 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 CXFile SearchFile;
4394 unsigned SearchLine, SearchColumn;
4395 CXFile ResultFile;
4396 unsigned ResultLine, ResultColumn;
4397 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4398 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4399 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004400
4401 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4402 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004403 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004404 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 SearchFileName = clang_getFileName(SearchFile);
4406 ResultFileName = clang_getFileName(ResultFile);
4407 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4408 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004409 *Log << llvm::format("(%s:%d:%d) = %s",
4410 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4411 clang_getCString(KindSpelling))
4412 << llvm::format("(%s:%d:%d):%s%s",
4413 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4414 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 clang_disposeString(SearchFileName);
4416 clang_disposeString(ResultFileName);
4417 clang_disposeString(KindSpelling);
4418 clang_disposeString(USR);
4419
4420 CXCursor Definition = clang_getCursorDefinition(Result);
4421 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4422 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4423 CXString DefinitionKindSpelling
4424 = clang_getCursorKindSpelling(Definition.kind);
4425 CXFile DefinitionFile;
4426 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004427 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004428 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004429 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004430 *Log << llvm::format(" -> %s(%s:%d:%d)",
4431 clang_getCString(DefinitionKindSpelling),
4432 clang_getCString(DefinitionFileName),
4433 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 clang_disposeString(DefinitionFileName);
4435 clang_disposeString(DefinitionKindSpelling);
4436 }
4437 }
4438
4439 return Result;
4440}
4441
4442CXCursor clang_getNullCursor(void) {
4443 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4444}
4445
4446unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004447 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4448 // can't set consistently. For example, when visiting a DeclStmt we will set
4449 // it but we don't set it on the result of clang_getCursorDefinition for
4450 // a reference of the same declaration.
4451 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4452 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4453 // to provide that kind of info.
4454 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004455 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004456 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004457 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004458
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 return X == Y;
4460}
4461
4462unsigned clang_hashCursor(CXCursor C) {
4463 unsigned Index = 0;
4464 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4465 Index = 1;
4466
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004467 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 std::make_pair(C.kind, C.data[Index]));
4469}
4470
4471unsigned clang_isInvalid(enum CXCursorKind K) {
4472 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4473}
4474
4475unsigned clang_isDeclaration(enum CXCursorKind K) {
4476 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4477 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4478}
4479
4480unsigned clang_isReference(enum CXCursorKind K) {
4481 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4482}
4483
4484unsigned clang_isExpression(enum CXCursorKind K) {
4485 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4486}
4487
4488unsigned clang_isStatement(enum CXCursorKind K) {
4489 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4490}
4491
4492unsigned clang_isAttribute(enum CXCursorKind K) {
4493 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4494}
4495
4496unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4497 return K == CXCursor_TranslationUnit;
4498}
4499
4500unsigned clang_isPreprocessing(enum CXCursorKind K) {
4501 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4502}
4503
4504unsigned clang_isUnexposed(enum CXCursorKind K) {
4505 switch (K) {
4506 case CXCursor_UnexposedDecl:
4507 case CXCursor_UnexposedExpr:
4508 case CXCursor_UnexposedStmt:
4509 case CXCursor_UnexposedAttr:
4510 return true;
4511 default:
4512 return false;
4513 }
4514}
4515
4516CXCursorKind clang_getCursorKind(CXCursor C) {
4517 return C.kind;
4518}
4519
4520CXSourceLocation clang_getCursorLocation(CXCursor C) {
4521 if (clang_isReference(C.kind)) {
4522 switch (C.kind) {
4523 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004524 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 = getCursorObjCSuperClassRef(C);
4526 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4527 }
4528
4529 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004530 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 = getCursorObjCProtocolRef(C);
4532 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4533 }
4534
4535 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004536 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 = getCursorObjCClassRef(C);
4538 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4539 }
4540
4541 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004542 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4544 }
4545
4546 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004547 std::pair<const TemplateDecl *, SourceLocation> P =
4548 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4550 }
4551
4552 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004553 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4555 }
4556
4557 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004558 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4560 }
4561
4562 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004563 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4565 }
4566
4567 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004568 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 if (!BaseSpec)
4570 return clang_getNullLocation();
4571
4572 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4573 return cxloc::translateSourceLocation(getCursorContext(C),
4574 TSInfo->getTypeLoc().getBeginLoc());
4575
4576 return cxloc::translateSourceLocation(getCursorContext(C),
4577 BaseSpec->getLocStart());
4578 }
4579
4580 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004581 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4583 }
4584
4585 case CXCursor_OverloadedDeclRef:
4586 return cxloc::translateSourceLocation(getCursorContext(C),
4587 getCursorOverloadedDeclRef(C).second);
4588
4589 default:
4590 // FIXME: Need a way to enumerate all non-reference cases.
4591 llvm_unreachable("Missed a reference kind");
4592 }
4593 }
4594
4595 if (clang_isExpression(C.kind))
4596 return cxloc::translateSourceLocation(getCursorContext(C),
4597 getLocationFromExpr(getCursorExpr(C)));
4598
4599 if (clang_isStatement(C.kind))
4600 return cxloc::translateSourceLocation(getCursorContext(C),
4601 getCursorStmt(C)->getLocStart());
4602
4603 if (C.kind == CXCursor_PreprocessingDirective) {
4604 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4605 return cxloc::translateSourceLocation(getCursorContext(C), L);
4606 }
4607
4608 if (C.kind == CXCursor_MacroExpansion) {
4609 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004610 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 return cxloc::translateSourceLocation(getCursorContext(C), L);
4612 }
4613
4614 if (C.kind == CXCursor_MacroDefinition) {
4615 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4616 return cxloc::translateSourceLocation(getCursorContext(C), L);
4617 }
4618
4619 if (C.kind == CXCursor_InclusionDirective) {
4620 SourceLocation L
4621 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4622 return cxloc::translateSourceLocation(getCursorContext(C), L);
4623 }
4624
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004625 if (clang_isAttribute(C.kind)) {
4626 SourceLocation L
4627 = cxcursor::getCursorAttr(C)->getLocation();
4628 return cxloc::translateSourceLocation(getCursorContext(C), L);
4629 }
4630
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 if (!clang_isDeclaration(C.kind))
4632 return clang_getNullLocation();
4633
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004634 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 if (!D)
4636 return clang_getNullLocation();
4637
4638 SourceLocation Loc = D->getLocation();
4639 // FIXME: Multiple variables declared in a single declaration
4640 // currently lack the information needed to correctly determine their
4641 // ranges when accounting for the type-specifier. We use context
4642 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4643 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004644 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 if (!cxcursor::isFirstInDeclGroup(C))
4646 Loc = VD->getLocation();
4647 }
4648
4649 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004650 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 Loc = MD->getSelectorStartLoc();
4652
4653 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4654}
4655
4656} // end extern "C"
4657
4658CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4659 assert(TU);
4660
4661 // Guard against an invalid SourceLocation, or we may assert in one
4662 // of the following calls.
4663 if (SLoc.isInvalid())
4664 return clang_getNullCursor();
4665
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004666 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004667
4668 // Translate the given source location to make it point at the beginning of
4669 // the token under the cursor.
4670 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4671 CXXUnit->getASTContext().getLangOpts());
4672
4673 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4674 if (SLoc.isValid()) {
4675 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4676 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4677 /*VisitPreprocessorLast=*/true,
4678 /*VisitIncludedEntities=*/false,
4679 SourceLocation(SLoc));
4680 CursorVis.visitFileRegion();
4681 }
4682
4683 return Result;
4684}
4685
4686static SourceRange getRawCursorExtent(CXCursor C) {
4687 if (clang_isReference(C.kind)) {
4688 switch (C.kind) {
4689 case CXCursor_ObjCSuperClassRef:
4690 return getCursorObjCSuperClassRef(C).second;
4691
4692 case CXCursor_ObjCProtocolRef:
4693 return getCursorObjCProtocolRef(C).second;
4694
4695 case CXCursor_ObjCClassRef:
4696 return getCursorObjCClassRef(C).second;
4697
4698 case CXCursor_TypeRef:
4699 return getCursorTypeRef(C).second;
4700
4701 case CXCursor_TemplateRef:
4702 return getCursorTemplateRef(C).second;
4703
4704 case CXCursor_NamespaceRef:
4705 return getCursorNamespaceRef(C).second;
4706
4707 case CXCursor_MemberRef:
4708 return getCursorMemberRef(C).second;
4709
4710 case CXCursor_CXXBaseSpecifier:
4711 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4712
4713 case CXCursor_LabelRef:
4714 return getCursorLabelRef(C).second;
4715
4716 case CXCursor_OverloadedDeclRef:
4717 return getCursorOverloadedDeclRef(C).second;
4718
4719 case CXCursor_VariableRef:
4720 return getCursorVariableRef(C).second;
4721
4722 default:
4723 // FIXME: Need a way to enumerate all non-reference cases.
4724 llvm_unreachable("Missed a reference kind");
4725 }
4726 }
4727
4728 if (clang_isExpression(C.kind))
4729 return getCursorExpr(C)->getSourceRange();
4730
4731 if (clang_isStatement(C.kind))
4732 return getCursorStmt(C)->getSourceRange();
4733
4734 if (clang_isAttribute(C.kind))
4735 return getCursorAttr(C)->getRange();
4736
4737 if (C.kind == CXCursor_PreprocessingDirective)
4738 return cxcursor::getCursorPreprocessingDirective(C);
4739
4740 if (C.kind == CXCursor_MacroExpansion) {
4741 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004742 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 return TU->mapRangeFromPreamble(Range);
4744 }
4745
4746 if (C.kind == CXCursor_MacroDefinition) {
4747 ASTUnit *TU = getCursorASTUnit(C);
4748 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4749 return TU->mapRangeFromPreamble(Range);
4750 }
4751
4752 if (C.kind == CXCursor_InclusionDirective) {
4753 ASTUnit *TU = getCursorASTUnit(C);
4754 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4755 return TU->mapRangeFromPreamble(Range);
4756 }
4757
4758 if (C.kind == CXCursor_TranslationUnit) {
4759 ASTUnit *TU = getCursorASTUnit(C);
4760 FileID MainID = TU->getSourceManager().getMainFileID();
4761 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4762 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4763 return SourceRange(Start, End);
4764 }
4765
4766 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004767 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 if (!D)
4769 return SourceRange();
4770
4771 SourceRange R = D->getSourceRange();
4772 // FIXME: Multiple variables declared in a single declaration
4773 // currently lack the information needed to correctly determine their
4774 // ranges when accounting for the type-specifier. We use context
4775 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4776 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004777 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004778 if (!cxcursor::isFirstInDeclGroup(C))
4779 R.setBegin(VD->getLocation());
4780 }
4781 return R;
4782 }
4783 return SourceRange();
4784}
4785
4786/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4787/// the decl-specifier-seq for declarations.
4788static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4789 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004790 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 if (!D)
4792 return SourceRange();
4793
4794 SourceRange R = D->getSourceRange();
4795
4796 // Adjust the start of the location for declarations preceded by
4797 // declaration specifiers.
4798 SourceLocation StartLoc;
4799 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4800 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4801 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004802 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004803 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4804 StartLoc = TI->getTypeLoc().getLocStart();
4805 }
4806
4807 if (StartLoc.isValid() && R.getBegin().isValid() &&
4808 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4809 R.setBegin(StartLoc);
4810
4811 // FIXME: Multiple variables declared in a single declaration
4812 // currently lack the information needed to correctly determine their
4813 // ranges when accounting for the type-specifier. We use context
4814 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4815 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004816 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 if (!cxcursor::isFirstInDeclGroup(C))
4818 R.setBegin(VD->getLocation());
4819 }
4820
4821 return R;
4822 }
4823
4824 return getRawCursorExtent(C);
4825}
4826
4827extern "C" {
4828
4829CXSourceRange clang_getCursorExtent(CXCursor C) {
4830 SourceRange R = getRawCursorExtent(C);
4831 if (R.isInvalid())
4832 return clang_getNullRange();
4833
4834 return cxloc::translateSourceRange(getCursorContext(C), R);
4835}
4836
4837CXCursor clang_getCursorReferenced(CXCursor C) {
4838 if (clang_isInvalid(C.kind))
4839 return clang_getNullCursor();
4840
4841 CXTranslationUnit tu = getCursorTU(C);
4842 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004843 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 if (!D)
4845 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004846 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004847 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004848 if (const ObjCPropertyImplDecl *PropImpl =
4849 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004850 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4851 return MakeCXCursor(Property, tu);
4852
4853 return C;
4854 }
4855
4856 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004857 const Expr *E = getCursorExpr(C);
4858 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 if (D) {
4860 CXCursor declCursor = MakeCXCursor(D, tu);
4861 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4862 declCursor);
4863 return declCursor;
4864 }
4865
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004866 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004867 return MakeCursorOverloadedDeclRef(Ovl, tu);
4868
4869 return clang_getNullCursor();
4870 }
4871
4872 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004873 const Stmt *S = getCursorStmt(C);
4874 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004875 if (LabelDecl *label = Goto->getLabel())
4876 if (LabelStmt *labelS = label->getStmt())
4877 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4878
4879 return clang_getNullCursor();
4880 }
4881
4882 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004883 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 return MakeMacroDefinitionCursor(Def, tu);
4885 }
4886
4887 if (!clang_isReference(C.kind))
4888 return clang_getNullCursor();
4889
4890 switch (C.kind) {
4891 case CXCursor_ObjCSuperClassRef:
4892 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4893
4894 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004895 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4896 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004897 return MakeCXCursor(Def, tu);
4898
4899 return MakeCXCursor(Prot, tu);
4900 }
4901
4902 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004903 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4904 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004905 return MakeCXCursor(Def, tu);
4906
4907 return MakeCXCursor(Class, tu);
4908 }
4909
4910 case CXCursor_TypeRef:
4911 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4912
4913 case CXCursor_TemplateRef:
4914 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4915
4916 case CXCursor_NamespaceRef:
4917 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4918
4919 case CXCursor_MemberRef:
4920 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4921
4922 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004923 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4925 tu ));
4926 }
4927
4928 case CXCursor_LabelRef:
4929 // FIXME: We end up faking the "parent" declaration here because we
4930 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004931 return MakeCXCursor(getCursorLabelRef(C).first,
4932 cxtu::getASTUnit(tu)->getASTContext()
4933 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004934 tu);
4935
4936 case CXCursor_OverloadedDeclRef:
4937 return C;
4938
4939 case CXCursor_VariableRef:
4940 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4941
4942 default:
4943 // We would prefer to enumerate all non-reference cursor kinds here.
4944 llvm_unreachable("Unhandled reference cursor kind");
4945 }
4946}
4947
4948CXCursor clang_getCursorDefinition(CXCursor C) {
4949 if (clang_isInvalid(C.kind))
4950 return clang_getNullCursor();
4951
4952 CXTranslationUnit TU = getCursorTU(C);
4953
4954 bool WasReference = false;
4955 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4956 C = clang_getCursorReferenced(C);
4957 WasReference = true;
4958 }
4959
4960 if (C.kind == CXCursor_MacroExpansion)
4961 return clang_getCursorReferenced(C);
4962
4963 if (!clang_isDeclaration(C.kind))
4964 return clang_getNullCursor();
4965
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004966 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004967 if (!D)
4968 return clang_getNullCursor();
4969
4970 switch (D->getKind()) {
4971 // Declaration kinds that don't really separate the notions of
4972 // declaration and definition.
4973 case Decl::Namespace:
4974 case Decl::Typedef:
4975 case Decl::TypeAlias:
4976 case Decl::TypeAliasTemplate:
4977 case Decl::TemplateTypeParm:
4978 case Decl::EnumConstant:
4979 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004980 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004981 case Decl::IndirectField:
4982 case Decl::ObjCIvar:
4983 case Decl::ObjCAtDefsField:
4984 case Decl::ImplicitParam:
4985 case Decl::ParmVar:
4986 case Decl::NonTypeTemplateParm:
4987 case Decl::TemplateTemplateParm:
4988 case Decl::ObjCCategoryImpl:
4989 case Decl::ObjCImplementation:
4990 case Decl::AccessSpec:
4991 case Decl::LinkageSpec:
4992 case Decl::ObjCPropertyImpl:
4993 case Decl::FileScopeAsm:
4994 case Decl::StaticAssert:
4995 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004996 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004997 case Decl::Label: // FIXME: Is this right??
4998 case Decl::ClassScopeFunctionSpecialization:
4999 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005000 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005001 return C;
5002
5003 // Declaration kinds that don't make any sense here, but are
5004 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005005 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005007 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005008 break;
5009
5010 // Declaration kinds for which the definition is not resolvable.
5011 case Decl::UnresolvedUsingTypename:
5012 case Decl::UnresolvedUsingValue:
5013 break;
5014
5015 case Decl::UsingDirective:
5016 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5017 TU);
5018
5019 case Decl::NamespaceAlias:
5020 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5021
5022 case Decl::Enum:
5023 case Decl::Record:
5024 case Decl::CXXRecord:
5025 case Decl::ClassTemplateSpecialization:
5026 case Decl::ClassTemplatePartialSpecialization:
5027 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5028 return MakeCXCursor(Def, TU);
5029 return clang_getNullCursor();
5030
5031 case Decl::Function:
5032 case Decl::CXXMethod:
5033 case Decl::CXXConstructor:
5034 case Decl::CXXDestructor:
5035 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005036 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005037 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005038 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005039 return clang_getNullCursor();
5040 }
5041
Larisse Voufo39a1e502013-08-06 01:03:05 +00005042 case Decl::Var:
5043 case Decl::VarTemplateSpecialization:
5044 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005046 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 return MakeCXCursor(Def, TU);
5048 return clang_getNullCursor();
5049 }
5050
5051 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005052 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5054 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5055 return clang_getNullCursor();
5056 }
5057
5058 case Decl::ClassTemplate: {
5059 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5060 ->getDefinition())
5061 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5062 TU);
5063 return clang_getNullCursor();
5064 }
5065
Larisse Voufo39a1e502013-08-06 01:03:05 +00005066 case Decl::VarTemplate: {
5067 if (VarDecl *Def =
5068 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5069 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5070 return clang_getNullCursor();
5071 }
5072
Guy Benyei11169dd2012-12-18 14:30:41 +00005073 case Decl::Using:
5074 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5075 D->getLocation(), TU);
5076
5077 case Decl::UsingShadow:
5078 return clang_getCursorDefinition(
5079 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5080 TU));
5081
5082 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005083 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 if (Method->isThisDeclarationADefinition())
5085 return C;
5086
5087 // Dig out the method definition in the associated
5088 // @implementation, if we have it.
5089 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005090 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005091 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5092 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5093 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5094 Method->isInstanceMethod()))
5095 if (Def->isThisDeclarationADefinition())
5096 return MakeCXCursor(Def, TU);
5097
5098 return clang_getNullCursor();
5099 }
5100
5101 case Decl::ObjCCategory:
5102 if (ObjCCategoryImplDecl *Impl
5103 = cast<ObjCCategoryDecl>(D)->getImplementation())
5104 return MakeCXCursor(Impl, TU);
5105 return clang_getNullCursor();
5106
5107 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005108 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 return MakeCXCursor(Def, TU);
5110 return clang_getNullCursor();
5111
5112 case Decl::ObjCInterface: {
5113 // There are two notions of a "definition" for an Objective-C
5114 // class: the interface and its implementation. When we resolved a
5115 // reference to an Objective-C class, produce the @interface as
5116 // the definition; when we were provided with the interface,
5117 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005118 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005120 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005121 return MakeCXCursor(Def, TU);
5122 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5123 return MakeCXCursor(Impl, TU);
5124 return clang_getNullCursor();
5125 }
5126
5127 case Decl::ObjCProperty:
5128 // FIXME: We don't really know where to find the
5129 // ObjCPropertyImplDecls that implement this property.
5130 return clang_getNullCursor();
5131
5132 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005133 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005135 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 return MakeCXCursor(Def, TU);
5137
5138 return clang_getNullCursor();
5139
5140 case Decl::Friend:
5141 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5142 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5143 return clang_getNullCursor();
5144
5145 case Decl::FriendTemplate:
5146 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5147 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5148 return clang_getNullCursor();
5149 }
5150
5151 return clang_getNullCursor();
5152}
5153
5154unsigned clang_isCursorDefinition(CXCursor C) {
5155 if (!clang_isDeclaration(C.kind))
5156 return 0;
5157
5158 return clang_getCursorDefinition(C) == C;
5159}
5160
5161CXCursor clang_getCanonicalCursor(CXCursor C) {
5162 if (!clang_isDeclaration(C.kind))
5163 return C;
5164
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005165 if (const Decl *D = getCursorDecl(C)) {
5166 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005167 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5168 return MakeCXCursor(CatD, getCursorTU(C));
5169
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005170 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5171 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 return MakeCXCursor(IFD, getCursorTU(C));
5173
5174 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5175 }
5176
5177 return C;
5178}
5179
5180int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5181 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5182}
5183
5184unsigned clang_getNumOverloadedDecls(CXCursor C) {
5185 if (C.kind != CXCursor_OverloadedDeclRef)
5186 return 0;
5187
5188 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005189 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 return E->getNumDecls();
5191
5192 if (OverloadedTemplateStorage *S
5193 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5194 return S->size();
5195
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005196 const Decl *D = Storage.get<const Decl *>();
5197 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 return Using->shadow_size();
5199
5200 return 0;
5201}
5202
5203CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5204 if (cursor.kind != CXCursor_OverloadedDeclRef)
5205 return clang_getNullCursor();
5206
5207 if (index >= clang_getNumOverloadedDecls(cursor))
5208 return clang_getNullCursor();
5209
5210 CXTranslationUnit TU = getCursorTU(cursor);
5211 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005212 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 return MakeCXCursor(E->decls_begin()[index], TU);
5214
5215 if (OverloadedTemplateStorage *S
5216 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5217 return MakeCXCursor(S->begin()[index], TU);
5218
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005219 const Decl *D = Storage.get<const Decl *>();
5220 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 // FIXME: This is, unfortunately, linear time.
5222 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5223 std::advance(Pos, index);
5224 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5225 }
5226
5227 return clang_getNullCursor();
5228}
5229
5230void clang_getDefinitionSpellingAndExtent(CXCursor C,
5231 const char **startBuf,
5232 const char **endBuf,
5233 unsigned *startLine,
5234 unsigned *startColumn,
5235 unsigned *endLine,
5236 unsigned *endColumn) {
5237 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005238 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005239 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5240
5241 SourceManager &SM = FD->getASTContext().getSourceManager();
5242 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5243 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5244 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5245 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5246 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5247 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5248}
5249
5250
5251CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5252 unsigned PieceIndex) {
5253 RefNamePieces Pieces;
5254
5255 switch (C.kind) {
5256 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005257 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5259 E->getQualifierLoc().getSourceRange());
5260 break;
5261
5262 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005263 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5265 E->getQualifierLoc().getSourceRange(),
5266 E->getOptionalExplicitTemplateArgs());
5267 break;
5268
5269 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005270 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005271 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005272 const Expr *Callee = OCE->getCallee();
5273 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 Callee = ICE->getSubExpr();
5275
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005276 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5278 DRE->getQualifierLoc().getSourceRange());
5279 }
5280 break;
5281
5282 default:
5283 break;
5284 }
5285
5286 if (Pieces.empty()) {
5287 if (PieceIndex == 0)
5288 return clang_getCursorExtent(C);
5289 } else if (PieceIndex < Pieces.size()) {
5290 SourceRange R = Pieces[PieceIndex];
5291 if (R.isValid())
5292 return cxloc::translateSourceRange(getCursorContext(C), R);
5293 }
5294
5295 return clang_getNullRange();
5296}
5297
5298void clang_enableStackTraces(void) {
5299 llvm::sys::PrintStackTraceOnErrorSignal();
5300}
5301
5302void clang_executeOnThread(void (*fn)(void*), void *user_data,
5303 unsigned stack_size) {
5304 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5305}
5306
5307} // end: extern "C"
5308
5309//===----------------------------------------------------------------------===//
5310// Token-based Operations.
5311//===----------------------------------------------------------------------===//
5312
5313/* CXToken layout:
5314 * int_data[0]: a CXTokenKind
5315 * int_data[1]: starting token location
5316 * int_data[2]: token length
5317 * int_data[3]: reserved
5318 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5319 * otherwise unused.
5320 */
5321extern "C" {
5322
5323CXTokenKind clang_getTokenKind(CXToken CXTok) {
5324 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5325}
5326
5327CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5328 switch (clang_getTokenKind(CXTok)) {
5329 case CXToken_Identifier:
5330 case CXToken_Keyword:
5331 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005332 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 ->getNameStart());
5334
5335 case CXToken_Literal: {
5336 // We have stashed the starting pointer in the ptr_data field. Use it.
5337 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005338 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 }
5340
5341 case CXToken_Punctuation:
5342 case CXToken_Comment:
5343 break;
5344 }
5345
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005346 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005347 LOG_BAD_TU(TU);
5348 return cxstring::createEmpty();
5349 }
5350
Guy Benyei11169dd2012-12-18 14:30:41 +00005351 // We have to find the starting buffer pointer the hard way, by
5352 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005353 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005355 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005356
5357 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5358 std::pair<FileID, unsigned> LocInfo
5359 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5360 bool Invalid = false;
5361 StringRef Buffer
5362 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5363 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005364 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005365
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005366 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005367}
5368
5369CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005370 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005371 LOG_BAD_TU(TU);
5372 return clang_getNullLocation();
5373 }
5374
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005375 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 if (!CXXUnit)
5377 return clang_getNullLocation();
5378
5379 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5380 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5381}
5382
5383CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005384 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005385 LOG_BAD_TU(TU);
5386 return clang_getNullRange();
5387 }
5388
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005389 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005390 if (!CXXUnit)
5391 return clang_getNullRange();
5392
5393 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5394 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5395}
5396
5397static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5398 SmallVectorImpl<CXToken> &CXTokens) {
5399 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5400 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005401 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005402 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005403 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005404
5405 // Cannot tokenize across files.
5406 if (BeginLocInfo.first != EndLocInfo.first)
5407 return;
5408
5409 // Create a lexer
5410 bool Invalid = false;
5411 StringRef Buffer
5412 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5413 if (Invalid)
5414 return;
5415
5416 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5417 CXXUnit->getASTContext().getLangOpts(),
5418 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5419 Lex.SetCommentRetentionState(true);
5420
5421 // Lex tokens until we hit the end of the range.
5422 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5423 Token Tok;
5424 bool previousWasAt = false;
5425 do {
5426 // Lex the next token
5427 Lex.LexFromRawLexer(Tok);
5428 if (Tok.is(tok::eof))
5429 break;
5430
5431 // Initialize the CXToken.
5432 CXToken CXTok;
5433
5434 // - Common fields
5435 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5436 CXTok.int_data[2] = Tok.getLength();
5437 CXTok.int_data[3] = 0;
5438
5439 // - Kind-specific fields
5440 if (Tok.isLiteral()) {
5441 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005442 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 } else if (Tok.is(tok::raw_identifier)) {
5444 // Lookup the identifier to determine whether we have a keyword.
5445 IdentifierInfo *II
5446 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5447
5448 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5449 CXTok.int_data[0] = CXToken_Keyword;
5450 }
5451 else {
5452 CXTok.int_data[0] = Tok.is(tok::identifier)
5453 ? CXToken_Identifier
5454 : CXToken_Keyword;
5455 }
5456 CXTok.ptr_data = II;
5457 } else if (Tok.is(tok::comment)) {
5458 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005459 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005460 } else {
5461 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005462 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 }
5464 CXTokens.push_back(CXTok);
5465 previousWasAt = Tok.is(tok::at);
5466 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5467}
5468
5469void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5470 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005471 LOG_FUNC_SECTION {
5472 *Log << TU << ' ' << Range;
5473 }
5474
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005476 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 if (NumTokens)
5478 *NumTokens = 0;
5479
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005480 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005481 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005482 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005483 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005484
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005485 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005486 if (!CXXUnit || !Tokens || !NumTokens)
5487 return;
5488
5489 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5490
5491 SourceRange R = cxloc::translateCXSourceRange(Range);
5492 if (R.isInvalid())
5493 return;
5494
5495 SmallVector<CXToken, 32> CXTokens;
5496 getTokens(CXXUnit, R, CXTokens);
5497
5498 if (CXTokens.empty())
5499 return;
5500
5501 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5502 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5503 *NumTokens = CXTokens.size();
5504}
5505
5506void clang_disposeTokens(CXTranslationUnit TU,
5507 CXToken *Tokens, unsigned NumTokens) {
5508 free(Tokens);
5509}
5510
5511} // end: extern "C"
5512
5513//===----------------------------------------------------------------------===//
5514// Token annotation APIs.
5515//===----------------------------------------------------------------------===//
5516
Guy Benyei11169dd2012-12-18 14:30:41 +00005517static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5518 CXCursor parent,
5519 CXClientData client_data);
5520static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5521 CXClientData client_data);
5522
5523namespace {
5524class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 CXToken *Tokens;
5526 CXCursor *Cursors;
5527 unsigned NumTokens;
5528 unsigned TokIdx;
5529 unsigned PreprocessingTokIdx;
5530 CursorVisitor AnnotateVis;
5531 SourceManager &SrcMgr;
5532 bool HasContextSensitiveKeywords;
5533
5534 struct PostChildrenInfo {
5535 CXCursor Cursor;
5536 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005537 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005538 unsigned BeforeChildrenTokenIdx;
5539 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005540 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005541
5542 CXToken &getTok(unsigned Idx) {
5543 assert(Idx < NumTokens);
5544 return Tokens[Idx];
5545 }
5546 const CXToken &getTok(unsigned Idx) const {
5547 assert(Idx < NumTokens);
5548 return Tokens[Idx];
5549 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005550 bool MoreTokens() const { return TokIdx < NumTokens; }
5551 unsigned NextToken() const { return TokIdx; }
5552 void AdvanceToken() { ++TokIdx; }
5553 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005554 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005555 }
5556 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005557 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005558 }
5559 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005560 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005561 }
5562
5563 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005564 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 SourceRange);
5566
5567public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005568 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005569 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005570 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005571 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005572 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005573 AnnotateTokensVisitor, this,
5574 /*VisitPreprocessorLast=*/true,
5575 /*VisitIncludedEntities=*/false,
5576 RegionOfInterest,
5577 /*VisitDeclsOnly=*/false,
5578 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005579 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005580 HasContextSensitiveKeywords(false) { }
5581
5582 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5583 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5584 bool postVisitChildren(CXCursor cursor);
5585 void AnnotateTokens();
5586
5587 /// \brief Determine whether the annotator saw any cursors that have
5588 /// context-sensitive keywords.
5589 bool hasContextSensitiveKeywords() const {
5590 return HasContextSensitiveKeywords;
5591 }
5592
5593 ~AnnotateTokensWorker() {
5594 assert(PostChildrenInfos.empty());
5595 }
5596};
5597}
5598
5599void AnnotateTokensWorker::AnnotateTokens() {
5600 // Walk the AST within the region of interest, annotating tokens
5601 // along the way.
5602 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005603}
Guy Benyei11169dd2012-12-18 14:30:41 +00005604
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005605static inline void updateCursorAnnotation(CXCursor &Cursor,
5606 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005607 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005608 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005609 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005610}
5611
5612/// \brief It annotates and advances tokens with a cursor until the comparison
5613//// between the cursor location and the source range is the same as
5614/// \arg compResult.
5615///
5616/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5617/// Pass RangeOverlap to annotate tokens inside a range.
5618void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5619 RangeComparisonResult compResult,
5620 SourceRange range) {
5621 while (MoreTokens()) {
5622 const unsigned I = NextToken();
5623 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005624 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5625 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005626
5627 SourceLocation TokLoc = GetTokenLoc(I);
5628 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005629 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 AdvanceToken();
5631 continue;
5632 }
5633 break;
5634 }
5635}
5636
5637/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005638/// \returns true if it advanced beyond all macro tokens, false otherwise.
5639bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 CXCursor updateC,
5641 RangeComparisonResult compResult,
5642 SourceRange range) {
5643 assert(MoreTokens());
5644 assert(isFunctionMacroToken(NextToken()) &&
5645 "Should be called only for macro arg tokens");
5646
5647 // This works differently than annotateAndAdvanceTokens; because expanded
5648 // macro arguments can have arbitrary translation-unit source order, we do not
5649 // advance the token index one by one until a token fails the range test.
5650 // We only advance once past all of the macro arg tokens if all of them
5651 // pass the range test. If one of them fails we keep the token index pointing
5652 // at the start of the macro arg tokens so that the failing token will be
5653 // annotated by a subsequent annotation try.
5654
5655 bool atLeastOneCompFail = false;
5656
5657 unsigned I = NextToken();
5658 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5659 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5660 if (TokLoc.isFileID())
5661 continue; // not macro arg token, it's parens or comma.
5662 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5663 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5664 Cursors[I] = updateC;
5665 } else
5666 atLeastOneCompFail = true;
5667 }
5668
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005669 if (atLeastOneCompFail)
5670 return false;
5671
5672 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5673 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005674}
5675
5676enum CXChildVisitResult
5677AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005678 SourceRange cursorRange = getRawCursorExtent(cursor);
5679 if (cursorRange.isInvalid())
5680 return CXChildVisit_Recurse;
5681
5682 if (!HasContextSensitiveKeywords) {
5683 // Objective-C properties can have context-sensitive keywords.
5684 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005685 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005686 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5687 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5688 }
5689 // Objective-C methods can have context-sensitive keywords.
5690 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5691 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005692 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005693 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5694 if (Method->getObjCDeclQualifier())
5695 HasContextSensitiveKeywords = true;
5696 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005697 for (const auto *P : Method->params()) {
5698 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 HasContextSensitiveKeywords = true;
5700 break;
5701 }
5702 }
5703 }
5704 }
5705 }
5706 // C++ methods can have context-sensitive keywords.
5707 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005708 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005709 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5710 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5711 HasContextSensitiveKeywords = true;
5712 }
5713 }
5714 // C++ classes can have context-sensitive keywords.
5715 else if (cursor.kind == CXCursor_StructDecl ||
5716 cursor.kind == CXCursor_ClassDecl ||
5717 cursor.kind == CXCursor_ClassTemplate ||
5718 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005719 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 if (D->hasAttr<FinalAttr>())
5721 HasContextSensitiveKeywords = true;
5722 }
5723 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005724
5725 // Don't override a property annotation with its getter/setter method.
5726 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5727 parent.kind == CXCursor_ObjCPropertyDecl)
5728 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005729
5730 if (clang_isPreprocessing(cursor.kind)) {
5731 // Items in the preprocessing record are kept separate from items in
5732 // declarations, so we keep a separate token index.
5733 unsigned SavedTokIdx = TokIdx;
5734 TokIdx = PreprocessingTokIdx;
5735
5736 // Skip tokens up until we catch up to the beginning of the preprocessing
5737 // entry.
5738 while (MoreTokens()) {
5739 const unsigned I = NextToken();
5740 SourceLocation TokLoc = GetTokenLoc(I);
5741 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5742 case RangeBefore:
5743 AdvanceToken();
5744 continue;
5745 case RangeAfter:
5746 case RangeOverlap:
5747 break;
5748 }
5749 break;
5750 }
5751
5752 // Look at all of the tokens within this range.
5753 while (MoreTokens()) {
5754 const unsigned I = NextToken();
5755 SourceLocation TokLoc = GetTokenLoc(I);
5756 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5757 case RangeBefore:
5758 llvm_unreachable("Infeasible");
5759 case RangeAfter:
5760 break;
5761 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005762 // For macro expansions, just note where the beginning of the macro
5763 // expansion occurs.
5764 if (cursor.kind == CXCursor_MacroExpansion) {
5765 if (TokLoc == cursorRange.getBegin())
5766 Cursors[I] = cursor;
5767 AdvanceToken();
5768 break;
5769 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005770 // We may have already annotated macro names inside macro definitions.
5771 if (Cursors[I].kind != CXCursor_MacroExpansion)
5772 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005773 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 continue;
5775 }
5776 break;
5777 }
5778
5779 // Save the preprocessing token index; restore the non-preprocessing
5780 // token index.
5781 PreprocessingTokIdx = TokIdx;
5782 TokIdx = SavedTokIdx;
5783 return CXChildVisit_Recurse;
5784 }
5785
5786 if (cursorRange.isInvalid())
5787 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005788
5789 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005790 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005791 const enum CXCursorKind K = clang_getCursorKind(parent);
5792 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005793 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5794 // Attributes are annotated out-of-order, skip tokens until we reach it.
5795 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 ? clang_getNullCursor() : parent;
5797
5798 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5799
5800 // Avoid having the cursor of an expression "overwrite" the annotation of the
5801 // variable declaration that it belongs to.
5802 // This can happen for C++ constructor expressions whose range generally
5803 // include the variable declaration, e.g.:
5804 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005805 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005806 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005807 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005808 const unsigned I = NextToken();
5809 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5810 E->getLocStart() == D->getLocation() &&
5811 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005812 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005813 AdvanceToken();
5814 }
5815 }
5816 }
5817
5818 // Before recursing into the children keep some state that we are going
5819 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5820 // extra work after the child nodes are visited.
5821 // Note that we don't call VisitChildren here to avoid traversing statements
5822 // code-recursively which can blow the stack.
5823
5824 PostChildrenInfo Info;
5825 Info.Cursor = cursor;
5826 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005827 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005828 Info.BeforeChildrenTokenIdx = NextToken();
5829 PostChildrenInfos.push_back(Info);
5830
5831 return CXChildVisit_Recurse;
5832}
5833
5834bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5835 if (PostChildrenInfos.empty())
5836 return false;
5837 const PostChildrenInfo &Info = PostChildrenInfos.back();
5838 if (!clang_equalCursors(Info.Cursor, cursor))
5839 return false;
5840
5841 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5842 const unsigned AfterChildren = NextToken();
5843 SourceRange cursorRange = Info.CursorRange;
5844
5845 // Scan the tokens that are at the end of the cursor, but are not captured
5846 // but the child cursors.
5847 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5848
5849 // Scan the tokens that are at the beginning of the cursor, but are not
5850 // capture by the child cursors.
5851 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5852 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5853 break;
5854
5855 Cursors[I] = cursor;
5856 }
5857
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005858 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5859 // encountered the attribute cursor.
5860 if (clang_isAttribute(cursor.kind))
5861 TokIdx = Info.BeforeReachingCursorIdx;
5862
Guy Benyei11169dd2012-12-18 14:30:41 +00005863 PostChildrenInfos.pop_back();
5864 return false;
5865}
5866
5867static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5868 CXCursor parent,
5869 CXClientData client_data) {
5870 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5871}
5872
5873static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5874 CXClientData client_data) {
5875 return static_cast<AnnotateTokensWorker*>(client_data)->
5876 postVisitChildren(cursor);
5877}
5878
5879namespace {
5880
5881/// \brief Uses the macro expansions in the preprocessing record to find
5882/// and mark tokens that are macro arguments. This info is used by the
5883/// AnnotateTokensWorker.
5884class MarkMacroArgTokensVisitor {
5885 SourceManager &SM;
5886 CXToken *Tokens;
5887 unsigned NumTokens;
5888 unsigned CurIdx;
5889
5890public:
5891 MarkMacroArgTokensVisitor(SourceManager &SM,
5892 CXToken *tokens, unsigned numTokens)
5893 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5894
5895 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5896 if (cursor.kind != CXCursor_MacroExpansion)
5897 return CXChildVisit_Continue;
5898
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005899 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005900 if (macroRange.getBegin() == macroRange.getEnd())
5901 return CXChildVisit_Continue; // it's not a function macro.
5902
5903 for (; CurIdx < NumTokens; ++CurIdx) {
5904 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5905 macroRange.getBegin()))
5906 break;
5907 }
5908
5909 if (CurIdx == NumTokens)
5910 return CXChildVisit_Break;
5911
5912 for (; CurIdx < NumTokens; ++CurIdx) {
5913 SourceLocation tokLoc = getTokenLoc(CurIdx);
5914 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5915 break;
5916
5917 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5918 }
5919
5920 if (CurIdx == NumTokens)
5921 return CXChildVisit_Break;
5922
5923 return CXChildVisit_Continue;
5924 }
5925
5926private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005927 CXToken &getTok(unsigned Idx) {
5928 assert(Idx < NumTokens);
5929 return Tokens[Idx];
5930 }
5931 const CXToken &getTok(unsigned Idx) const {
5932 assert(Idx < NumTokens);
5933 return Tokens[Idx];
5934 }
5935
Guy Benyei11169dd2012-12-18 14:30:41 +00005936 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005937 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005938 }
5939
5940 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5941 // The third field is reserved and currently not used. Use it here
5942 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005943 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005944 }
5945};
5946
5947} // end anonymous namespace
5948
5949static CXChildVisitResult
5950MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5951 CXClientData client_data) {
5952 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5953 parent);
5954}
5955
5956namespace {
5957 struct clang_annotateTokens_Data {
5958 CXTranslationUnit TU;
5959 ASTUnit *CXXUnit;
5960 CXToken *Tokens;
5961 unsigned NumTokens;
5962 CXCursor *Cursors;
5963 };
5964}
5965
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005966/// \brief Used by \c annotatePreprocessorTokens.
5967/// \returns true if lexing was finished, false otherwise.
5968static bool lexNext(Lexer &Lex, Token &Tok,
5969 unsigned &NextIdx, unsigned NumTokens) {
5970 if (NextIdx >= NumTokens)
5971 return true;
5972
5973 ++NextIdx;
5974 Lex.LexFromRawLexer(Tok);
5975 if (Tok.is(tok::eof))
5976 return true;
5977
5978 return false;
5979}
5980
Guy Benyei11169dd2012-12-18 14:30:41 +00005981static void annotatePreprocessorTokens(CXTranslationUnit TU,
5982 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005983 CXCursor *Cursors,
5984 CXToken *Tokens,
5985 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005986 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005987
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005988 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005989 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5990 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005991 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005992 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005993 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005994
5995 if (BeginLocInfo.first != EndLocInfo.first)
5996 return;
5997
5998 StringRef Buffer;
5999 bool Invalid = false;
6000 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6001 if (Buffer.empty() || Invalid)
6002 return;
6003
6004 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6005 CXXUnit->getASTContext().getLangOpts(),
6006 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6007 Buffer.end());
6008 Lex.SetCommentRetentionState(true);
6009
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006010 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 // Lex tokens in raw mode until we hit the end of the range, to avoid
6012 // entering #includes or expanding macros.
6013 while (true) {
6014 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006015 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6016 break;
6017 unsigned TokIdx = NextIdx-1;
6018 assert(Tok.getLocation() ==
6019 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006020
6021 reprocess:
6022 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006023 // We have found a preprocessing directive. Annotate the tokens
6024 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006025 //
6026 // FIXME: Some simple tests here could identify macro definitions and
6027 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006028
6029 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006030 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6031 break;
6032
Craig Topper69186e72014-06-08 08:38:04 +00006033 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006034 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006035 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6036 break;
6037
6038 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006039 IdentifierInfo &II =
6040 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006041 SourceLocation MappedTokLoc =
6042 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6043 MI = getMacroInfo(II, MappedTokLoc, TU);
6044 }
6045 }
6046
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006047 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006048 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006049 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6050 finished = true;
6051 break;
6052 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006053 // If we are in a macro definition, check if the token was ever a
6054 // macro name and annotate it if that's the case.
6055 if (MI) {
6056 SourceLocation SaveLoc = Tok.getLocation();
6057 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6058 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
6059 Tok.setLocation(SaveLoc);
6060 if (MacroDef)
6061 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6062 Tok.getLocation(), TU);
6063 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006064 } while (!Tok.isAtStartOfLine());
6065
6066 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6067 assert(TokIdx <= LastIdx);
6068 SourceLocation EndLoc =
6069 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6070 CXCursor Cursor =
6071 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6072
6073 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006074 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006075
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006076 if (finished)
6077 break;
6078 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006079 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006080 }
6081}
6082
6083// This gets run a separate thread to avoid stack blowout.
6084static void clang_annotateTokensImpl(void *UserData) {
6085 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6086 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6087 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6088 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6089 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6090
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006091 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006092 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6093 setThreadBackgroundPriority();
6094
6095 // Determine the region of interest, which contains all of the tokens.
6096 SourceRange RegionOfInterest;
6097 RegionOfInterest.setBegin(
6098 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6099 RegionOfInterest.setEnd(
6100 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6101 Tokens[NumTokens-1])));
6102
Guy Benyei11169dd2012-12-18 14:30:41 +00006103 // Relex the tokens within the source range to look for preprocessing
6104 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006105 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006106
6107 // If begin location points inside a macro argument, set it to the expansion
6108 // location so we can have the full context when annotating semantically.
6109 {
6110 SourceManager &SM = CXXUnit->getSourceManager();
6111 SourceLocation Loc =
6112 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6113 if (Loc.isMacroID())
6114 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6115 }
6116
Guy Benyei11169dd2012-12-18 14:30:41 +00006117 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6118 // Search and mark tokens that are macro argument expansions.
6119 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6120 Tokens, NumTokens);
6121 CursorVisitor MacroArgMarker(TU,
6122 MarkMacroArgTokensVisitorDelegate, &Visitor,
6123 /*VisitPreprocessorLast=*/true,
6124 /*VisitIncludedEntities=*/false,
6125 RegionOfInterest);
6126 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6127 }
6128
6129 // Annotate all of the source locations in the region of interest that map to
6130 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006131 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006132
6133 // FIXME: We use a ridiculous stack size here because the data-recursion
6134 // algorithm uses a large stack frame than the non-data recursive version,
6135 // and AnnotationTokensWorker currently transforms the data-recursion
6136 // algorithm back into a traditional recursion by explicitly calling
6137 // VisitChildren(). We will need to remove this explicit recursive call.
6138 W.AnnotateTokens();
6139
6140 // If we ran into any entities that involve context-sensitive keywords,
6141 // take another pass through the tokens to mark them as such.
6142 if (W.hasContextSensitiveKeywords()) {
6143 for (unsigned I = 0; I != NumTokens; ++I) {
6144 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6145 continue;
6146
6147 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6148 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006149 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006150 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6151 if (Property->getPropertyAttributesAsWritten() != 0 &&
6152 llvm::StringSwitch<bool>(II->getName())
6153 .Case("readonly", true)
6154 .Case("assign", true)
6155 .Case("unsafe_unretained", true)
6156 .Case("readwrite", true)
6157 .Case("retain", true)
6158 .Case("copy", true)
6159 .Case("nonatomic", true)
6160 .Case("atomic", true)
6161 .Case("getter", true)
6162 .Case("setter", true)
6163 .Case("strong", true)
6164 .Case("weak", true)
6165 .Default(false))
6166 Tokens[I].int_data[0] = CXToken_Keyword;
6167 }
6168 continue;
6169 }
6170
6171 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6172 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6173 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6174 if (llvm::StringSwitch<bool>(II->getName())
6175 .Case("in", true)
6176 .Case("out", true)
6177 .Case("inout", true)
6178 .Case("oneway", true)
6179 .Case("bycopy", true)
6180 .Case("byref", true)
6181 .Default(false))
6182 Tokens[I].int_data[0] = CXToken_Keyword;
6183 continue;
6184 }
6185
6186 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6187 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6188 Tokens[I].int_data[0] = CXToken_Keyword;
6189 continue;
6190 }
6191 }
6192 }
6193}
6194
6195extern "C" {
6196
6197void clang_annotateTokens(CXTranslationUnit TU,
6198 CXToken *Tokens, unsigned NumTokens,
6199 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006200 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006201 LOG_BAD_TU(TU);
6202 return;
6203 }
6204 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006205 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006206 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006207 }
6208
6209 LOG_FUNC_SECTION {
6210 *Log << TU << ' ';
6211 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6212 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6213 *Log << clang_getRange(bloc, eloc);
6214 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006215
6216 // Any token we don't specifically annotate will have a NULL cursor.
6217 CXCursor C = clang_getNullCursor();
6218 for (unsigned I = 0; I != NumTokens; ++I)
6219 Cursors[I] = C;
6220
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006221 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006222 if (!CXXUnit)
6223 return;
6224
6225 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6226
6227 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6228 llvm::CrashRecoveryContext CRC;
6229 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6230 GetSafetyThreadStackSize() * 2)) {
6231 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6232 }
6233}
6234
6235} // end: extern "C"
6236
6237//===----------------------------------------------------------------------===//
6238// Operations for querying linkage of a cursor.
6239//===----------------------------------------------------------------------===//
6240
6241extern "C" {
6242CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6243 if (!clang_isDeclaration(cursor.kind))
6244 return CXLinkage_Invalid;
6245
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006246 const Decl *D = cxcursor::getCursorDecl(cursor);
6247 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006248 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006249 case NoLinkage:
6250 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006251 case InternalLinkage: return CXLinkage_Internal;
6252 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6253 case ExternalLinkage: return CXLinkage_External;
6254 };
6255
6256 return CXLinkage_Invalid;
6257}
6258} // end: extern "C"
6259
6260//===----------------------------------------------------------------------===//
6261// Operations for querying language of a cursor.
6262//===----------------------------------------------------------------------===//
6263
6264static CXLanguageKind getDeclLanguage(const Decl *D) {
6265 if (!D)
6266 return CXLanguage_C;
6267
6268 switch (D->getKind()) {
6269 default:
6270 break;
6271 case Decl::ImplicitParam:
6272 case Decl::ObjCAtDefsField:
6273 case Decl::ObjCCategory:
6274 case Decl::ObjCCategoryImpl:
6275 case Decl::ObjCCompatibleAlias:
6276 case Decl::ObjCImplementation:
6277 case Decl::ObjCInterface:
6278 case Decl::ObjCIvar:
6279 case Decl::ObjCMethod:
6280 case Decl::ObjCProperty:
6281 case Decl::ObjCPropertyImpl:
6282 case Decl::ObjCProtocol:
6283 return CXLanguage_ObjC;
6284 case Decl::CXXConstructor:
6285 case Decl::CXXConversion:
6286 case Decl::CXXDestructor:
6287 case Decl::CXXMethod:
6288 case Decl::CXXRecord:
6289 case Decl::ClassTemplate:
6290 case Decl::ClassTemplatePartialSpecialization:
6291 case Decl::ClassTemplateSpecialization:
6292 case Decl::Friend:
6293 case Decl::FriendTemplate:
6294 case Decl::FunctionTemplate:
6295 case Decl::LinkageSpec:
6296 case Decl::Namespace:
6297 case Decl::NamespaceAlias:
6298 case Decl::NonTypeTemplateParm:
6299 case Decl::StaticAssert:
6300 case Decl::TemplateTemplateParm:
6301 case Decl::TemplateTypeParm:
6302 case Decl::UnresolvedUsingTypename:
6303 case Decl::UnresolvedUsingValue:
6304 case Decl::Using:
6305 case Decl::UsingDirective:
6306 case Decl::UsingShadow:
6307 return CXLanguage_CPlusPlus;
6308 }
6309
6310 return CXLanguage_C;
6311}
6312
6313extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006314
6315static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6316 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6317 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006318
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006319 switch (D->getAvailability()) {
6320 case AR_Available:
6321 case AR_NotYetIntroduced:
6322 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006323 return getCursorAvailabilityForDecl(
6324 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006325 return CXAvailability_Available;
6326
6327 case AR_Deprecated:
6328 return CXAvailability_Deprecated;
6329
6330 case AR_Unavailable:
6331 return CXAvailability_NotAvailable;
6332 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006333
6334 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006335}
6336
Guy Benyei11169dd2012-12-18 14:30:41 +00006337enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6338 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006339 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6340 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006341
6342 return CXAvailability_Available;
6343}
6344
6345static CXVersion convertVersion(VersionTuple In) {
6346 CXVersion Out = { -1, -1, -1 };
6347 if (In.empty())
6348 return Out;
6349
6350 Out.Major = In.getMajor();
6351
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006352 Optional<unsigned> Minor = In.getMinor();
6353 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006354 Out.Minor = *Minor;
6355 else
6356 return Out;
6357
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006358 Optional<unsigned> Subminor = In.getSubminor();
6359 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006360 Out.Subminor = *Subminor;
6361
6362 return Out;
6363}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006364
6365static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6366 int *always_deprecated,
6367 CXString *deprecated_message,
6368 int *always_unavailable,
6369 CXString *unavailable_message,
6370 CXPlatformAvailability *availability,
6371 int availability_size) {
6372 bool HadAvailAttr = false;
6373 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006374 for (auto A : D->attrs()) {
6375 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006376 HadAvailAttr = true;
6377 if (always_deprecated)
6378 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006379 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006380 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006381 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006382 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006383 continue;
6384 }
6385
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006386 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006387 HadAvailAttr = true;
6388 if (always_unavailable)
6389 *always_unavailable = 1;
6390 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006391 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006392 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6393 }
6394 continue;
6395 }
6396
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006397 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006398 HadAvailAttr = true;
6399 if (N < availability_size) {
6400 availability[N].Platform
6401 = cxstring::createDup(Avail->getPlatform()->getName());
6402 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6403 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6404 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6405 availability[N].Unavailable = Avail->getUnavailable();
6406 availability[N].Message = cxstring::createDup(Avail->getMessage());
6407 }
6408 ++N;
6409 }
6410 }
6411
6412 if (!HadAvailAttr)
6413 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6414 return getCursorPlatformAvailabilityForDecl(
6415 cast<Decl>(EnumConst->getDeclContext()),
6416 always_deprecated,
6417 deprecated_message,
6418 always_unavailable,
6419 unavailable_message,
6420 availability,
6421 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006422
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006423 return N;
6424}
6425
Guy Benyei11169dd2012-12-18 14:30:41 +00006426int clang_getCursorPlatformAvailability(CXCursor cursor,
6427 int *always_deprecated,
6428 CXString *deprecated_message,
6429 int *always_unavailable,
6430 CXString *unavailable_message,
6431 CXPlatformAvailability *availability,
6432 int availability_size) {
6433 if (always_deprecated)
6434 *always_deprecated = 0;
6435 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006436 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006437 if (always_unavailable)
6438 *always_unavailable = 0;
6439 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006440 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006441
Guy Benyei11169dd2012-12-18 14:30:41 +00006442 if (!clang_isDeclaration(cursor.kind))
6443 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006444
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006445 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006446 if (!D)
6447 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006448
6449 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6450 deprecated_message,
6451 always_unavailable,
6452 unavailable_message,
6453 availability,
6454 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006455}
6456
6457void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6458 clang_disposeString(availability->Platform);
6459 clang_disposeString(availability->Message);
6460}
6461
6462CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6463 if (clang_isDeclaration(cursor.kind))
6464 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6465
6466 return CXLanguage_Invalid;
6467}
6468
6469 /// \brief If the given cursor is the "templated" declaration
6470 /// descibing a class or function template, return the class or
6471 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006472static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006473 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006474 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006475
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006476 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006477 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6478 return FunTmpl;
6479
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006480 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006481 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6482 return ClassTmpl;
6483
6484 return D;
6485}
6486
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006487
6488enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6489 StorageClass sc = SC_None;
6490 const Decl *D = getCursorDecl(C);
6491 if (D) {
6492 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6493 sc = FD->getStorageClass();
6494 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6495 sc = VD->getStorageClass();
6496 } else {
6497 return CX_SC_Invalid;
6498 }
6499 } else {
6500 return CX_SC_Invalid;
6501 }
6502 switch (sc) {
6503 case SC_None:
6504 return CX_SC_None;
6505 case SC_Extern:
6506 return CX_SC_Extern;
6507 case SC_Static:
6508 return CX_SC_Static;
6509 case SC_PrivateExtern:
6510 return CX_SC_PrivateExtern;
6511 case SC_OpenCLWorkGroupLocal:
6512 return CX_SC_OpenCLWorkGroupLocal;
6513 case SC_Auto:
6514 return CX_SC_Auto;
6515 case SC_Register:
6516 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006517 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006518 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006519}
6520
Guy Benyei11169dd2012-12-18 14:30:41 +00006521CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6522 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006523 if (const Decl *D = getCursorDecl(cursor)) {
6524 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006525 if (!DC)
6526 return clang_getNullCursor();
6527
6528 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6529 getCursorTU(cursor));
6530 }
6531 }
6532
6533 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006534 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006535 return MakeCXCursor(D, getCursorTU(cursor));
6536 }
6537
6538 return clang_getNullCursor();
6539}
6540
6541CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6542 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006543 if (const Decl *D = getCursorDecl(cursor)) {
6544 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006545 if (!DC)
6546 return clang_getNullCursor();
6547
6548 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6549 getCursorTU(cursor));
6550 }
6551 }
6552
6553 // FIXME: Note that we can't easily compute the lexical context of a
6554 // statement or expression, so we return nothing.
6555 return clang_getNullCursor();
6556}
6557
6558CXFile clang_getIncludedFile(CXCursor cursor) {
6559 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006560 return nullptr;
6561
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006562 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006563 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006564}
6565
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006566unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6567 if (C.kind != CXCursor_ObjCPropertyDecl)
6568 return CXObjCPropertyAttr_noattr;
6569
6570 unsigned Result = CXObjCPropertyAttr_noattr;
6571 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6572 ObjCPropertyDecl::PropertyAttributeKind Attr =
6573 PD->getPropertyAttributesAsWritten();
6574
6575#define SET_CXOBJCPROP_ATTR(A) \
6576 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6577 Result |= CXObjCPropertyAttr_##A
6578 SET_CXOBJCPROP_ATTR(readonly);
6579 SET_CXOBJCPROP_ATTR(getter);
6580 SET_CXOBJCPROP_ATTR(assign);
6581 SET_CXOBJCPROP_ATTR(readwrite);
6582 SET_CXOBJCPROP_ATTR(retain);
6583 SET_CXOBJCPROP_ATTR(copy);
6584 SET_CXOBJCPROP_ATTR(nonatomic);
6585 SET_CXOBJCPROP_ATTR(setter);
6586 SET_CXOBJCPROP_ATTR(atomic);
6587 SET_CXOBJCPROP_ATTR(weak);
6588 SET_CXOBJCPROP_ATTR(strong);
6589 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6590#undef SET_CXOBJCPROP_ATTR
6591
6592 return Result;
6593}
6594
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006595unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6596 if (!clang_isDeclaration(C.kind))
6597 return CXObjCDeclQualifier_None;
6598
6599 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6600 const Decl *D = getCursorDecl(C);
6601 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6602 QT = MD->getObjCDeclQualifier();
6603 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6604 QT = PD->getObjCDeclQualifier();
6605 if (QT == Decl::OBJC_TQ_None)
6606 return CXObjCDeclQualifier_None;
6607
6608 unsigned Result = CXObjCDeclQualifier_None;
6609 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6610 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6611 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6612 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6613 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6614 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6615
6616 return Result;
6617}
6618
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006619unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6620 if (!clang_isDeclaration(C.kind))
6621 return 0;
6622
6623 const Decl *D = getCursorDecl(C);
6624 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6625 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6626 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6627 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6628
6629 return 0;
6630}
6631
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006632unsigned clang_Cursor_isVariadic(CXCursor C) {
6633 if (!clang_isDeclaration(C.kind))
6634 return 0;
6635
6636 const Decl *D = getCursorDecl(C);
6637 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6638 return FD->isVariadic();
6639 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6640 return MD->isVariadic();
6641
6642 return 0;
6643}
6644
Guy Benyei11169dd2012-12-18 14:30:41 +00006645CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6646 if (!clang_isDeclaration(C.kind))
6647 return clang_getNullRange();
6648
6649 const Decl *D = getCursorDecl(C);
6650 ASTContext &Context = getCursorContext(C);
6651 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6652 if (!RC)
6653 return clang_getNullRange();
6654
6655 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6656}
6657
6658CXString clang_Cursor_getRawCommentText(CXCursor C) {
6659 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006660 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006661
6662 const Decl *D = getCursorDecl(C);
6663 ASTContext &Context = getCursorContext(C);
6664 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6665 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6666 StringRef();
6667
6668 // Don't duplicate the string because RawText points directly into source
6669 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006670 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006671}
6672
6673CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6674 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006675 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006676
6677 const Decl *D = getCursorDecl(C);
6678 const ASTContext &Context = getCursorContext(C);
6679 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6680
6681 if (RC) {
6682 StringRef BriefText = RC->getBriefText(Context);
6683
6684 // Don't duplicate the string because RawComment ensures that this memory
6685 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006686 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006687 }
6688
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006689 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006690}
6691
Guy Benyei11169dd2012-12-18 14:30:41 +00006692CXModule clang_Cursor_getModule(CXCursor C) {
6693 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006694 if (const ImportDecl *ImportD =
6695 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006696 return ImportD->getImportedModule();
6697 }
6698
Craig Topper69186e72014-06-08 08:38:04 +00006699 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006700}
6701
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006702CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6703 if (isNotUsableTU(TU)) {
6704 LOG_BAD_TU(TU);
6705 return nullptr;
6706 }
6707 if (!File)
6708 return nullptr;
6709 FileEntry *FE = static_cast<FileEntry *>(File);
6710
6711 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6712 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6713 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6714
Richard Smithfeb54b62014-10-23 02:01:19 +00006715 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006716}
6717
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006718CXFile clang_Module_getASTFile(CXModule CXMod) {
6719 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006720 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006721 Module *Mod = static_cast<Module*>(CXMod);
6722 return const_cast<FileEntry *>(Mod->getASTFile());
6723}
6724
Guy Benyei11169dd2012-12-18 14:30:41 +00006725CXModule clang_Module_getParent(CXModule CXMod) {
6726 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006727 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006728 Module *Mod = static_cast<Module*>(CXMod);
6729 return Mod->Parent;
6730}
6731
6732CXString clang_Module_getName(CXModule CXMod) {
6733 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006734 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006735 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006736 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006737}
6738
6739CXString clang_Module_getFullName(CXModule CXMod) {
6740 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006741 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006742 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006743 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006744}
6745
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006746int clang_Module_isSystem(CXModule CXMod) {
6747 if (!CXMod)
6748 return 0;
6749 Module *Mod = static_cast<Module*>(CXMod);
6750 return Mod->IsSystem;
6751}
6752
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006753unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6754 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006755 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006756 LOG_BAD_TU(TU);
6757 return 0;
6758 }
6759 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006760 return 0;
6761 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006762 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6763 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6764 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006765}
6766
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006767CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6768 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006769 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006770 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006771 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006772 }
6773 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006774 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006775 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006776 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006777
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006778 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6779 if (Index < TopHeaders.size())
6780 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006781
Craig Topper69186e72014-06-08 08:38:04 +00006782 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006783}
6784
6785} // end: extern "C"
6786
6787//===----------------------------------------------------------------------===//
6788// C++ AST instrospection.
6789//===----------------------------------------------------------------------===//
6790
6791extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006792unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6793 if (!clang_isDeclaration(C.kind))
6794 return 0;
6795
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006796 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006797 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006798 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006799 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6800}
6801
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006802unsigned clang_CXXMethod_isConst(CXCursor C) {
6803 if (!clang_isDeclaration(C.kind))
6804 return 0;
6805
6806 const Decl *D = cxcursor::getCursorDecl(C);
6807 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006808 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006809 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6810}
6811
Guy Benyei11169dd2012-12-18 14:30:41 +00006812unsigned clang_CXXMethod_isStatic(CXCursor C) {
6813 if (!clang_isDeclaration(C.kind))
6814 return 0;
6815
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006816 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006817 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006818 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006819 return (Method && Method->isStatic()) ? 1 : 0;
6820}
6821
6822unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6823 if (!clang_isDeclaration(C.kind))
6824 return 0;
6825
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006826 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006827 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006828 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006829 return (Method && Method->isVirtual()) ? 1 : 0;
6830}
6831} // end: extern "C"
6832
6833//===----------------------------------------------------------------------===//
6834// Attribute introspection.
6835//===----------------------------------------------------------------------===//
6836
6837extern "C" {
6838CXType clang_getIBOutletCollectionType(CXCursor C) {
6839 if (C.kind != CXCursor_IBOutletCollectionAttr)
6840 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6841
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006842 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006843 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6844
6845 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6846}
6847} // end: extern "C"
6848
6849//===----------------------------------------------------------------------===//
6850// Inspecting memory usage.
6851//===----------------------------------------------------------------------===//
6852
6853typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6854
6855static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6856 enum CXTUResourceUsageKind k,
6857 unsigned long amount) {
6858 CXTUResourceUsageEntry entry = { k, amount };
6859 entries.push_back(entry);
6860}
6861
6862extern "C" {
6863
6864const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6865 const char *str = "";
6866 switch (kind) {
6867 case CXTUResourceUsage_AST:
6868 str = "ASTContext: expressions, declarations, and types";
6869 break;
6870 case CXTUResourceUsage_Identifiers:
6871 str = "ASTContext: identifiers";
6872 break;
6873 case CXTUResourceUsage_Selectors:
6874 str = "ASTContext: selectors";
6875 break;
6876 case CXTUResourceUsage_GlobalCompletionResults:
6877 str = "Code completion: cached global results";
6878 break;
6879 case CXTUResourceUsage_SourceManagerContentCache:
6880 str = "SourceManager: content cache allocator";
6881 break;
6882 case CXTUResourceUsage_AST_SideTables:
6883 str = "ASTContext: side tables";
6884 break;
6885 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6886 str = "SourceManager: malloc'ed memory buffers";
6887 break;
6888 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6889 str = "SourceManager: mmap'ed memory buffers";
6890 break;
6891 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6892 str = "ExternalASTSource: malloc'ed memory buffers";
6893 break;
6894 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6895 str = "ExternalASTSource: mmap'ed memory buffers";
6896 break;
6897 case CXTUResourceUsage_Preprocessor:
6898 str = "Preprocessor: malloc'ed memory";
6899 break;
6900 case CXTUResourceUsage_PreprocessingRecord:
6901 str = "Preprocessor: PreprocessingRecord";
6902 break;
6903 case CXTUResourceUsage_SourceManager_DataStructures:
6904 str = "SourceManager: data structures and tables";
6905 break;
6906 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6907 str = "Preprocessor: header search tables";
6908 break;
6909 }
6910 return str;
6911}
6912
6913CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006914 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006915 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006916 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006917 return usage;
6918 }
6919
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006920 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006921 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006922 ASTContext &astContext = astUnit->getASTContext();
6923
6924 // How much memory is used by AST nodes and types?
6925 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6926 (unsigned long) astContext.getASTAllocatedMemory());
6927
6928 // How much memory is used by identifiers?
6929 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6930 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6931
6932 // How much memory is used for selectors?
6933 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6934 (unsigned long) astContext.Selectors.getTotalMemory());
6935
6936 // How much memory is used by ASTContext's side tables?
6937 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6938 (unsigned long) astContext.getSideTableAllocatedMemory());
6939
6940 // How much memory is used for caching global code completion results?
6941 unsigned long completionBytes = 0;
6942 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006943 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006944 completionBytes = completionAllocator->getTotalMemory();
6945 }
6946 createCXTUResourceUsageEntry(*entries,
6947 CXTUResourceUsage_GlobalCompletionResults,
6948 completionBytes);
6949
6950 // How much memory is being used by SourceManager's content cache?
6951 createCXTUResourceUsageEntry(*entries,
6952 CXTUResourceUsage_SourceManagerContentCache,
6953 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6954
6955 // How much memory is being used by the MemoryBuffer's in SourceManager?
6956 const SourceManager::MemoryBufferSizes &srcBufs =
6957 astUnit->getSourceManager().getMemoryBufferSizes();
6958
6959 createCXTUResourceUsageEntry(*entries,
6960 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6961 (unsigned long) srcBufs.malloc_bytes);
6962 createCXTUResourceUsageEntry(*entries,
6963 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6964 (unsigned long) srcBufs.mmap_bytes);
6965 createCXTUResourceUsageEntry(*entries,
6966 CXTUResourceUsage_SourceManager_DataStructures,
6967 (unsigned long) astContext.getSourceManager()
6968 .getDataStructureSizes());
6969
6970 // How much memory is being used by the ExternalASTSource?
6971 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6972 const ExternalASTSource::MemoryBufferSizes &sizes =
6973 esrc->getMemoryBufferSizes();
6974
6975 createCXTUResourceUsageEntry(*entries,
6976 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6977 (unsigned long) sizes.malloc_bytes);
6978 createCXTUResourceUsageEntry(*entries,
6979 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6980 (unsigned long) sizes.mmap_bytes);
6981 }
6982
6983 // How much memory is being used by the Preprocessor?
6984 Preprocessor &pp = astUnit->getPreprocessor();
6985 createCXTUResourceUsageEntry(*entries,
6986 CXTUResourceUsage_Preprocessor,
6987 pp.getTotalMemory());
6988
6989 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6990 createCXTUResourceUsageEntry(*entries,
6991 CXTUResourceUsage_PreprocessingRecord,
6992 pRec->getTotalMemory());
6993 }
6994
6995 createCXTUResourceUsageEntry(*entries,
6996 CXTUResourceUsage_Preprocessor_HeaderSearch,
6997 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006998
Guy Benyei11169dd2012-12-18 14:30:41 +00006999 CXTUResourceUsage usage = { (void*) entries.get(),
7000 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007001 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007002 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007003 return usage;
7004}
7005
7006void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7007 if (usage.data)
7008 delete (MemUsageEntries*) usage.data;
7009}
7010
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007011CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7012 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007013 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007014 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007015
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007016 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007017 LOG_BAD_TU(TU);
7018 return skipped;
7019 }
7020
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007021 if (!file)
7022 return skipped;
7023
7024 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7025 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7026 if (!ppRec)
7027 return skipped;
7028
7029 ASTContext &Ctx = astUnit->getASTContext();
7030 SourceManager &sm = Ctx.getSourceManager();
7031 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7032 FileID wantedFileID = sm.translateFile(fileEntry);
7033
7034 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7035 std::vector<SourceRange> wantedRanges;
7036 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7037 i != ei; ++i) {
7038 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7039 wantedRanges.push_back(*i);
7040 }
7041
7042 skipped->count = wantedRanges.size();
7043 skipped->ranges = new CXSourceRange[skipped->count];
7044 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7045 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7046
7047 return skipped;
7048}
7049
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007050void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7051 if (ranges) {
7052 delete[] ranges->ranges;
7053 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007054 }
7055}
7056
Guy Benyei11169dd2012-12-18 14:30:41 +00007057} // end extern "C"
7058
7059void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7060 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7061 for (unsigned I = 0; I != Usage.numEntries; ++I)
7062 fprintf(stderr, " %s: %lu\n",
7063 clang_getTUResourceUsageName(Usage.entries[I].kind),
7064 Usage.entries[I].amount);
7065
7066 clang_disposeCXTUResourceUsage(Usage);
7067}
7068
7069//===----------------------------------------------------------------------===//
7070// Misc. utility functions.
7071//===----------------------------------------------------------------------===//
7072
7073/// Default to using an 8 MB stack size on "safety" threads.
7074static unsigned SafetyStackThreadSize = 8 << 20;
7075
7076namespace clang {
7077
7078bool RunSafely(llvm::CrashRecoveryContext &CRC,
7079 void (*Fn)(void*), void *UserData,
7080 unsigned Size) {
7081 if (!Size)
7082 Size = GetSafetyThreadStackSize();
7083 if (Size)
7084 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7085 return CRC.RunSafely(Fn, UserData);
7086}
7087
7088unsigned GetSafetyThreadStackSize() {
7089 return SafetyStackThreadSize;
7090}
7091
7092void SetSafetyThreadStackSize(unsigned Value) {
7093 SafetyStackThreadSize = Value;
7094}
7095
7096}
7097
7098void clang::setThreadBackgroundPriority() {
7099 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7100 return;
7101
Alp Toker1a86ad22014-07-06 06:24:00 +00007102#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007103 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7104#endif
7105}
7106
7107void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7108 if (!Unit)
7109 return;
7110
7111 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7112 DEnd = Unit->stored_diag_end();
7113 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007114 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007115 CXString Msg = clang_formatDiagnostic(&Diag,
7116 clang_defaultDiagnosticDisplayOptions());
7117 fprintf(stderr, "%s\n", clang_getCString(Msg));
7118 clang_disposeString(Msg);
7119 }
7120#ifdef LLVM_ON_WIN32
7121 // On Windows, force a flush, since there may be multiple copies of
7122 // stderr and stdout in the file system, all with different buffers
7123 // but writing to the same device.
7124 fflush(stderr);
7125#endif
7126}
7127
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007128MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7129 SourceLocation MacroDefLoc,
7130 CXTranslationUnit TU){
7131 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007132 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007133 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007134 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007135
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007136 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007137 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007138 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007139 if (MD) {
7140 for (MacroDirective::DefInfo
7141 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7142 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7143 return Def.getMacroInfo();
7144 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007145 }
7146
Craig Topper69186e72014-06-08 08:38:04 +00007147 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007148}
7149
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007150const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7151 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007152 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007153 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007154 const IdentifierInfo *II = MacroDef->getName();
7155 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007156 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007157
7158 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7159}
7160
7161MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7162 const Token &Tok,
7163 CXTranslationUnit TU) {
7164 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007165 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007166 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007167 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007168
7169 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007170 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007171 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7172 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007173 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007174
7175 // Check that the token is inside the definition and not its argument list.
7176 SourceManager &SM = Unit->getSourceManager();
7177 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007178 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007179 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007180 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007181
7182 Preprocessor &PP = Unit->getPreprocessor();
7183 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7184 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007185 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007186
Alp Toker2d57cea2014-05-17 04:53:25 +00007187 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007188 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007189 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007190
7191 // Check that the identifier is not one of the macro arguments.
7192 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007193 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007194
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007195 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7196 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007197 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007198
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007199 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007200}
7201
7202MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7203 SourceLocation Loc,
7204 CXTranslationUnit TU) {
7205 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007206 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007207
7208 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007209 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007210 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007211 Preprocessor &PP = Unit->getPreprocessor();
7212 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007213 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007214 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7215 Token Tok;
7216 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007217 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007218
7219 return checkForMacroInMacroDefinition(MI, Tok, TU);
7220}
7221
Guy Benyei11169dd2012-12-18 14:30:41 +00007222extern "C" {
7223
7224CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007225 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007226}
7227
7228} // end: extern "C"
7229
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007230Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7231 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007232 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007233 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007234 if (Unit->isMainFileAST())
7235 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007236 return *this;
7237 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007238 } else {
7239 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007240 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007241 return *this;
7242}
7243
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007244Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7245 *this << FE->getName();
7246 return *this;
7247}
7248
7249Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7250 CXString cursorName = clang_getCursorDisplayName(cursor);
7251 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7252 clang_disposeString(cursorName);
7253 return *this;
7254}
7255
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007256Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7257 CXFile File;
7258 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007259 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007260 CXString FileName = clang_getFileName(File);
7261 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7262 clang_disposeString(FileName);
7263 return *this;
7264}
7265
7266Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7267 CXSourceLocation BLoc = clang_getRangeStart(range);
7268 CXSourceLocation ELoc = clang_getRangeEnd(range);
7269
7270 CXFile BFile;
7271 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007272 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007273
7274 CXFile EFile;
7275 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007276 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007277
7278 CXString BFileName = clang_getFileName(BFile);
7279 if (BFile == EFile) {
7280 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7281 BLine, BColumn, ELine, EColumn);
7282 } else {
7283 CXString EFileName = clang_getFileName(EFile);
7284 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7285 BLine, BColumn)
7286 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7287 ELine, EColumn);
7288 clang_disposeString(EFileName);
7289 }
7290 clang_disposeString(BFileName);
7291 return *this;
7292}
7293
7294Logger &cxindex::Logger::operator<<(CXString Str) {
7295 *this << clang_getCString(Str);
7296 return *this;
7297}
7298
7299Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7300 LogOS << Fmt;
7301 return *this;
7302}
7303
Chandler Carruth37ad2582014-06-27 15:14:39 +00007304static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7305
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007306cxindex::Logger::~Logger() {
7307 LogOS.flush();
7308
Chandler Carruth37ad2582014-06-27 15:14:39 +00007309 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007310
7311 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7312
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007313 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007314 OS << "[libclang:" << Name << ':';
7315
Alp Toker1a86ad22014-07-06 06:24:00 +00007316#ifdef USE_DARWIN_THREADS
7317 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007318 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7319 OS << tid << ':';
7320#endif
7321
7322 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7323 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007324 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007325
7326 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007327 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007328 OS << "--------------------------------------------------\n";
7329 }
7330}