blob: 04344254942b10c5a8a9a52633ec1a897ff89d70 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000243 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
244 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000245 PPRec, FID);
246}
247
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000248bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000249 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000250 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000251
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000252 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000253 SourceManager &SM = Unit->getSourceManager();
254
255 std::pair<FileID, unsigned>
256 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
257 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
258
259 if (End.first != Begin.first) {
260 // If the end does not reside in the same file, try to recover by
261 // picking the end of the file of begin location.
262 End.first = Begin.first;
263 End.second = SM.getFileIDSize(Begin.first);
264 }
265
266 assert(Begin.first == End.first);
267 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000268 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
270 FileID File = Begin.first;
271 unsigned Offset = Begin.second;
272 unsigned Length = End.second - Begin.second;
273
274 if (!VisitDeclsOnly && !VisitPreprocessorLast)
275 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000278 if (visitDeclsFromFileRegion(File, Offset, Length))
279 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000280
281 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000282 return visitPreprocessedEntitiesInRegion();
283
284 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000285}
286
287static bool isInLexicalContext(Decl *D, DeclContext *DC) {
288 if (!DC)
289 return false;
290
291 for (DeclContext *DeclDC = D->getLexicalDeclContext();
292 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
293 if (DeclDC == DC)
294 return true;
295 }
296 return false;
297}
298
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000299bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000300 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000301 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000302 SourceManager &SM = Unit->getSourceManager();
303 SourceRange Range = RegionOfInterest;
304
305 SmallVector<Decl *, 16> Decls;
306 Unit->findFileRegionDecls(File, Offset, Length, Decls);
307
308 // If we didn't find any file level decls for the file, try looking at the
309 // file that it was included from.
310 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
311 bool Invalid = false;
312 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
313 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000314 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315
316 SourceLocation Outer;
317 if (SLEntry.isFile())
318 Outer = SLEntry.getFile().getIncludeLoc();
319 else
320 Outer = SLEntry.getExpansion().getExpansionLocStart();
321 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000322 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000323
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000324 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000325 Length = 0;
326 Unit->findFileRegionDecls(File, Offset, Length, Decls);
327 }
328
329 assert(!Decls.empty());
330
331 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000332 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000333 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
334 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000335 Decl *D = *DIt;
336 if (D->getSourceRange().isInvalid())
337 continue;
338
339 if (isInLexicalContext(D, CurDC))
340 continue;
341
342 CurDC = dyn_cast<DeclContext>(D);
343
344 if (TagDecl *TD = dyn_cast<TagDecl>(D))
345 if (!TD->isFreeStanding())
346 continue;
347
348 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
349 if (CompRes == RangeBefore)
350 continue;
351 if (CompRes == RangeAfter)
352 break;
353
354 assert(CompRes == RangeOverlap);
355 VisitedAtLeastOnce = true;
356
357 if (isa<ObjCContainerDecl>(D)) {
358 FileDI_current = &DIt;
359 FileDE_current = DE;
360 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000361 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000362 }
363
364 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000365 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000366 }
367
368 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000369 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000370
371 // No Decls overlapped with the range. Move up the lexical context until there
372 // is a context that contains the range or we reach the translation unit
373 // level.
374 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
375 : (*(DIt-1))->getLexicalDeclContext();
376
377 while (DC && !DC->isTranslationUnit()) {
378 Decl *D = cast<Decl>(DC);
379 SourceRange CurDeclRange = D->getSourceRange();
380 if (CurDeclRange.isInvalid())
381 break;
382
383 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000384 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
385 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000386 }
387
388 DC = D->getLexicalDeclContext();
389 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000390
391 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000392}
393
394bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
395 if (!AU->getPreprocessor().getPreprocessingRecord())
396 return false;
397
398 PreprocessingRecord &PPRec
399 = *AU->getPreprocessor().getPreprocessingRecord();
400 SourceManager &SM = AU->getSourceManager();
401
402 if (RegionOfInterest.isValid()) {
403 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
404 SourceLocation B = MappedRange.getBegin();
405 SourceLocation E = MappedRange.getEnd();
406
407 if (AU->isInPreambleFileID(B)) {
408 if (SM.isLoadedSourceLocation(E))
409 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
410 PPRec, *this);
411
412 // Beginning of range lies in the preamble but it also extends beyond
413 // it into the main file. Split the range into 2 parts, one covering
414 // the preamble and another covering the main file. This allows subsequent
415 // calls to visitPreprocessedEntitiesInRange to accept a source range that
416 // lies in the same FileID, allowing it to skip preprocessed entities that
417 // do not come from the same FileID.
418 bool breaked =
419 visitPreprocessedEntitiesInRange(
420 SourceRange(B, AU->getEndOfPreambleFileID()),
421 PPRec, *this);
422 if (breaked) return true;
423 return visitPreprocessedEntitiesInRange(
424 SourceRange(AU->getStartOfMainFileID(), E),
425 PPRec, *this);
426 }
427
428 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
429 }
430
431 bool OnlyLocalDecls
432 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
433
434 if (OnlyLocalDecls)
435 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
436 PPRec);
437
438 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
439}
440
441template<typename InputIterator>
442bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
443 InputIterator Last,
444 PreprocessingRecord &PPRec,
445 FileID FID) {
446 for (; First != Last; ++First) {
447 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
448 continue;
449
450 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000451 if (!PPE)
452 continue;
453
Guy Benyei11169dd2012-12-18 14:30:41 +0000454 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
455 if (Visit(MakeMacroExpansionCursor(ME, TU)))
456 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000457
Guy Benyei11169dd2012-12-18 14:30:41 +0000458 continue;
459 }
Richard Smith66a81862015-05-04 02:25:31 +0000460
461 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000462 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
463 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000464
Guy Benyei11169dd2012-12-18 14:30:41 +0000465 continue;
466 }
467
468 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
469 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
470 return true;
471
472 continue;
473 }
474 }
475
476 return false;
477}
478
479/// \brief Visit the children of the given cursor.
480///
481/// \returns true if the visitation should be aborted, false if it
482/// should continue.
483bool CursorVisitor::VisitChildren(CXCursor Cursor) {
484 if (clang_isReference(Cursor.kind) &&
485 Cursor.kind != CXCursor_CXXBaseSpecifier) {
486 // By definition, references have no children.
487 return false;
488 }
489
490 // Set the Parent field to Cursor, then back to its old value once we're
491 // done.
492 SetParentRAII SetParent(Parent, StmtParent, Cursor);
493
494 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000495 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000496 if (!D)
497 return false;
498
499 return VisitAttributes(D) || Visit(D);
500 }
501
502 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(S);
505
506 return false;
507 }
508
509 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000510 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000511 return Visit(E);
512
513 return false;
514 }
515
516 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000517 CXTranslationUnit TU = getCursorTU(Cursor);
518 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000519
520 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
521 for (unsigned I = 0; I != 2; ++I) {
522 if (VisitOrder[I]) {
523 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
524 RegionOfInterest.isInvalid()) {
525 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
526 TLEnd = CXXUnit->top_level_end();
527 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000528 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000529 return true;
530 }
531 } else if (VisitDeclContext(
532 CXXUnit->getASTContext().getTranslationUnitDecl()))
533 return true;
534 continue;
535 }
536
537 // Walk the preprocessing record.
538 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
539 visitPreprocessedEntitiesInRegion();
540 }
541
542 return false;
543 }
544
545 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000546 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
548 return Visit(BaseTSInfo->getTypeLoc());
549 }
550 }
551 }
552
553 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000554 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000555 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000556 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000557 return Visit(cxcursor::MakeCursorObjCClassRef(
558 ObjT->getInterface(),
559 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000560 }
561
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000562 // If pointing inside a macro definition, check if the token is an identifier
563 // that was ever defined as a macro. In such a case, create a "pseudo" macro
564 // expansion cursor for that token.
565 SourceLocation BeginLoc = RegionOfInterest.getBegin();
566 if (Cursor.kind == CXCursor_MacroDefinition &&
567 BeginLoc == RegionOfInterest.getEnd()) {
568 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000569 const MacroInfo *MI =
570 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000571 if (MacroDefinitionRecord *MacroDef =
572 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000573 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
574 }
575
Guy Benyei11169dd2012-12-18 14:30:41 +0000576 // Nothing to visit at the moment.
577 return false;
578}
579
580bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
581 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
582 if (Visit(TSInfo->getTypeLoc()))
583 return true;
584
585 if (Stmt *Body = B->getBody())
586 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
587
588 return false;
589}
590
Ted Kremenek03325582013-02-21 01:29:01 +0000591Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000592 if (RegionOfInterest.isValid()) {
593 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
594 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000595 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000596
597 switch (CompareRegionOfInterest(Range)) {
598 case RangeBefore:
599 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000600 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000601
602 case RangeAfter:
603 // This declaration comes after the region of interest; we're done.
604 return false;
605
606 case RangeOverlap:
607 // This declaration overlaps the region of interest; visit it.
608 break;
609 }
610 }
611 return true;
612}
613
614bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
615 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
616
617 // FIXME: Eventually remove. This part of a hack to support proper
618 // iteration over all Decls contained lexically within an ObjC container.
619 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
620 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
621
622 for ( ; I != E; ++I) {
623 Decl *D = *I;
624 if (D->getLexicalDeclContext() != DC)
625 continue;
626 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
627
628 // Ignore synthesized ivars here, otherwise if we have something like:
629 // @synthesize prop = _prop;
630 // and '_prop' is not declared, we will encounter a '_prop' ivar before
631 // encountering the 'prop' synthesize declaration and we will think that
632 // we passed the region-of-interest.
633 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
634 if (ivarD->getSynthesize())
635 continue;
636 }
637
638 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
639 // declarations is a mismatch with the compiler semantics.
640 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
641 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
642 if (!ID->isThisDeclarationADefinition())
643 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
644
645 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
646 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
647 if (!PD->isThisDeclarationADefinition())
648 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
649 }
650
Ted Kremenek03325582013-02-21 01:29:01 +0000651 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000652 if (!V.hasValue())
653 continue;
654 if (!V.getValue())
655 return false;
656 if (Visit(Cursor, true))
657 return true;
658 }
659 return false;
660}
661
662bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
663 llvm_unreachable("Translation units are visited directly by Visit()");
664}
665
666bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
674 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
675 return Visit(TSInfo->getTypeLoc());
676
677 return false;
678}
679
680bool CursorVisitor::VisitTagDecl(TagDecl *D) {
681 return VisitDeclContext(D);
682}
683
684bool CursorVisitor::VisitClassTemplateSpecializationDecl(
685 ClassTemplateSpecializationDecl *D) {
686 bool ShouldVisitBody = false;
687 switch (D->getSpecializationKind()) {
688 case TSK_Undeclared:
689 case TSK_ImplicitInstantiation:
690 // Nothing to visit
691 return false;
692
693 case TSK_ExplicitInstantiationDeclaration:
694 case TSK_ExplicitInstantiationDefinition:
695 break;
696
697 case TSK_ExplicitSpecialization:
698 ShouldVisitBody = true;
699 break;
700 }
701
702 // Visit the template arguments used in the specialization.
703 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
704 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000705 if (TemplateSpecializationTypeLoc TSTLoc =
706 TL.getAs<TemplateSpecializationTypeLoc>()) {
707 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
708 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000709 return true;
710 }
711 }
712
713 if (ShouldVisitBody && VisitCXXRecordDecl(D))
714 return true;
715
716 return false;
717}
718
719bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
720 ClassTemplatePartialSpecializationDecl *D) {
721 // FIXME: Visit the "outer" template parameter lists on the TagDecl
722 // before visiting these template parameters.
723 if (VisitTemplateParameters(D->getTemplateParameters()))
724 return true;
725
726 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000727 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
728 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
729 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000730 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
731 return true;
732
733 return VisitCXXRecordDecl(D);
734}
735
736bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
737 // Visit the default argument.
738 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
739 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
740 if (Visit(DefArg->getTypeLoc()))
741 return true;
742
743 return false;
744}
745
746bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
747 if (Expr *Init = D->getInitExpr())
748 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
749 return false;
750}
751
752bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000753 unsigned NumParamList = DD->getNumTemplateParameterLists();
754 for (unsigned i = 0; i < NumParamList; i++) {
755 TemplateParameterList* Params = DD->getTemplateParameterList(i);
756 if (VisitTemplateParameters(Params))
757 return true;
758 }
759
Guy Benyei11169dd2012-12-18 14:30:41 +0000760 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
761 if (Visit(TSInfo->getTypeLoc()))
762 return true;
763
764 // Visit the nested-name-specifier, if present.
765 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
766 if (VisitNestedNameSpecifierLoc(QualifierLoc))
767 return true;
768
769 return false;
770}
771
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000772/// \brief Compare two base or member initializers based on their source order.
773static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
774 CXXCtorInitializer *const *Y) {
775 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
776}
777
Guy Benyei11169dd2012-12-18 14:30:41 +0000778bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000779 unsigned NumParamList = ND->getNumTemplateParameterLists();
780 for (unsigned i = 0; i < NumParamList; i++) {
781 TemplateParameterList* Params = ND->getTemplateParameterList(i);
782 if (VisitTemplateParameters(Params))
783 return true;
784 }
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
787 // Visit the function declaration's syntactic components in the order
788 // written. This requires a bit of work.
789 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000790 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000791
792 // If we have a function declared directly (without the use of a typedef),
793 // visit just the return type. Otherwise, just visit the function's type
794 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000795 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000796 (!FTL && Visit(TL)))
797 return true;
798
799 // Visit the nested-name-specifier, if present.
800 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
801 if (VisitNestedNameSpecifierLoc(QualifierLoc))
802 return true;
803
804 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000805 if (!isa<CXXDestructorDecl>(ND))
806 if (VisitDeclarationNameInfo(ND->getNameInfo()))
807 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000808
809 // FIXME: Visit explicitly-specified template arguments!
810
811 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000812 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 return true;
814
Bill Wendling44426052012-12-20 19:22:21 +0000815 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000816 }
817
818 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
819 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
820 // Find the initializers that were written in the source.
821 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000822 for (auto *I : Constructor->inits()) {
823 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 continue;
825
Aaron Ballman0ad78302014-03-13 17:34:31 +0000826 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000827 }
828
829 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000830 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
831 &CompareCXXCtorInitializers);
832
Guy Benyei11169dd2012-12-18 14:30:41 +0000833 // Visit the initializers in source order
834 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
835 CXXCtorInitializer *Init = WrittenInits[I];
836 if (Init->isAnyMemberInitializer()) {
837 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
838 Init->getMemberLocation(), TU)))
839 return true;
840 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
841 if (Visit(TInfo->getTypeLoc()))
842 return true;
843 }
844
845 // Visit the initializer value.
846 if (Expr *Initializer = Init->getInit())
847 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
848 return true;
849 }
850 }
851
852 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
853 return true;
854 }
855
856 return false;
857}
858
859bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
860 if (VisitDeclaratorDecl(D))
861 return true;
862
863 if (Expr *BitWidth = D->getBitWidth())
864 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
865
866 return false;
867}
868
869bool CursorVisitor::VisitVarDecl(VarDecl *D) {
870 if (VisitDeclaratorDecl(D))
871 return true;
872
873 if (Expr *Init = D->getInit())
874 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
875
876 return false;
877}
878
879bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
880 if (VisitDeclaratorDecl(D))
881 return true;
882
883 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
884 if (Expr *DefArg = D->getDefaultArgument())
885 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
886
887 return false;
888}
889
890bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
891 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
892 // before visiting these template parameters.
893 if (VisitTemplateParameters(D->getTemplateParameters()))
894 return true;
895
896 return VisitFunctionDecl(D->getTemplatedDecl());
897}
898
899bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
900 // FIXME: Visit the "outer" template parameter lists on the TagDecl
901 // before visiting these template parameters.
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 return VisitCXXRecordDecl(D->getTemplatedDecl());
906}
907
908bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
909 if (VisitTemplateParameters(D->getTemplateParameters()))
910 return true;
911
912 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
913 VisitTemplateArgumentLoc(D->getDefaultArgument()))
914 return true;
915
916 return false;
917}
918
919bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000920 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000921 if (Visit(TSInfo->getTypeLoc()))
922 return true;
923
Aaron Ballman43b68be2014-03-07 17:50:17 +0000924 for (const auto *P : ND->params()) {
925 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000926 return true;
927 }
928
929 if (ND->isThisDeclarationADefinition() &&
930 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
931 return true;
932
933 return false;
934}
935
936template <typename DeclIt>
937static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
938 SourceManager &SM, SourceLocation EndLoc,
939 SmallVectorImpl<Decl *> &Decls) {
940 DeclIt next = *DI_current;
941 while (++next != DE_current) {
942 Decl *D_next = *next;
943 if (!D_next)
944 break;
945 SourceLocation L = D_next->getLocStart();
946 if (!L.isValid())
947 break;
948 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
949 *DI_current = next;
950 Decls.push_back(D_next);
951 continue;
952 }
953 break;
954 }
955}
956
Guy Benyei11169dd2012-12-18 14:30:41 +0000957bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
958 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
959 // an @implementation can lexically contain Decls that are not properly
960 // nested in the AST. When we identify such cases, we need to retrofit
961 // this nesting here.
962 if (!DI_current && !FileDI_current)
963 return VisitDeclContext(D);
964
965 // Scan the Decls that immediately come after the container
966 // in the current DeclContext. If any fall within the
967 // container's lexical region, stash them into a vector
968 // for later processing.
969 SmallVector<Decl *, 24> DeclsInContainer;
970 SourceLocation EndLoc = D->getSourceRange().getEnd();
971 SourceManager &SM = AU->getSourceManager();
972 if (EndLoc.isValid()) {
973 if (DI_current) {
974 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
975 DeclsInContainer);
976 } else {
977 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
978 DeclsInContainer);
979 }
980 }
981
982 // The common case.
983 if (DeclsInContainer.empty())
984 return VisitDeclContext(D);
985
986 // Get all the Decls in the DeclContext, and sort them with the
987 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000988 for (auto *SubDecl : D->decls()) {
989 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
990 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000991 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000992 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000993 }
994
995 // Now sort the Decls so that they appear in lexical order.
996 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000997 [&SM](Decl *A, Decl *B) {
998 SourceLocation L_A = A->getLocStart();
999 SourceLocation L_B = B->getLocStart();
1000 assert(L_A.isValid() && L_B.isValid());
1001 return SM.isBeforeInTranslationUnit(L_A, L_B);
1002 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001003
1004 // Now visit the decls.
1005 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1006 E = DeclsInContainer.end(); I != E; ++I) {
1007 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001008 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001009 if (!V.hasValue())
1010 continue;
1011 if (!V.getValue())
1012 return false;
1013 if (Visit(Cursor, true))
1014 return true;
1015 }
1016 return false;
1017}
1018
1019bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1020 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1021 TU)))
1022 return true;
1023
1024 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1025 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1026 E = ND->protocol_end(); I != E; ++I, ++PL)
1027 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1028 return true;
1029
1030 return VisitObjCContainerDecl(ND);
1031}
1032
1033bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1034 if (!PID->isThisDeclarationADefinition())
1035 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1036
1037 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1038 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1039 E = PID->protocol_end(); I != E; ++I, ++PL)
1040 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1041 return true;
1042
1043 return VisitObjCContainerDecl(PID);
1044}
1045
1046bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1047 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1048 return true;
1049
1050 // FIXME: This implements a workaround with @property declarations also being
1051 // installed in the DeclContext for the @interface. Eventually this code
1052 // should be removed.
1053 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1054 if (!CDecl || !CDecl->IsClassExtension())
1055 return false;
1056
1057 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1058 if (!ID)
1059 return false;
1060
1061 IdentifierInfo *PropertyId = PD->getIdentifier();
1062 ObjCPropertyDecl *prevDecl =
1063 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1064
1065 if (!prevDecl)
1066 return false;
1067
1068 // Visit synthesized methods since they will be skipped when visiting
1069 // the @interface.
1070 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1071 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1072 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1073 return true;
1074
1075 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1076 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1077 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1078 return true;
1079
1080 return false;
1081}
1082
1083bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1084 if (!D->isThisDeclarationADefinition()) {
1085 // Forward declaration is treated like a reference.
1086 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1087 }
1088
1089 // Issue callbacks for super class.
1090 if (D->getSuperClass() &&
1091 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1092 D->getSuperClassLoc(),
1093 TU)))
1094 return true;
1095
1096 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1097 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1098 E = D->protocol_end(); I != E; ++I, ++PL)
1099 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1100 return true;
1101
1102 return VisitObjCContainerDecl(D);
1103}
1104
1105bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1106 return VisitObjCContainerDecl(D);
1107}
1108
1109bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1110 // 'ID' could be null when dealing with invalid code.
1111 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1112 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1113 return true;
1114
1115 return VisitObjCImplDecl(D);
1116}
1117
1118bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1119#if 0
1120 // Issue callbacks for super class.
1121 // FIXME: No source location information!
1122 if (D->getSuperClass() &&
1123 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1124 D->getSuperClassLoc(),
1125 TU)))
1126 return true;
1127#endif
1128
1129 return VisitObjCImplDecl(D);
1130}
1131
1132bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1133 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1134 if (PD->isIvarNameSpecified())
1135 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1136
1137 return false;
1138}
1139
1140bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1141 return VisitDeclContext(D);
1142}
1143
1144bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1145 // Visit nested-name-specifier.
1146 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1147 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1148 return true;
1149
1150 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1151 D->getTargetNameLoc(), TU));
1152}
1153
1154bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1155 // Visit nested-name-specifier.
1156 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1157 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1158 return true;
1159 }
1160
1161 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1162 return true;
1163
1164 return VisitDeclarationNameInfo(D->getNameInfo());
1165}
1166
1167bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1168 // Visit nested-name-specifier.
1169 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1170 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1171 return true;
1172
1173 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1174 D->getIdentLocation(), TU));
1175}
1176
1177bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1178 // Visit nested-name-specifier.
1179 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1180 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1181 return true;
1182 }
1183
1184 return VisitDeclarationNameInfo(D->getNameInfo());
1185}
1186
1187bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1188 UnresolvedUsingTypenameDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return false;
1195}
1196
1197bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1198 switch (Name.getName().getNameKind()) {
1199 case clang::DeclarationName::Identifier:
1200 case clang::DeclarationName::CXXLiteralOperatorName:
1201 case clang::DeclarationName::CXXOperatorName:
1202 case clang::DeclarationName::CXXUsingDirective:
1203 return false;
1204
1205 case clang::DeclarationName::CXXConstructorName:
1206 case clang::DeclarationName::CXXDestructorName:
1207 case clang::DeclarationName::CXXConversionFunctionName:
1208 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1209 return Visit(TSInfo->getTypeLoc());
1210 return false;
1211
1212 case clang::DeclarationName::ObjCZeroArgSelector:
1213 case clang::DeclarationName::ObjCOneArgSelector:
1214 case clang::DeclarationName::ObjCMultiArgSelector:
1215 // FIXME: Per-identifier location info?
1216 return false;
1217 }
1218
1219 llvm_unreachable("Invalid DeclarationName::Kind!");
1220}
1221
1222bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1223 SourceRange Range) {
1224 // FIXME: This whole routine is a hack to work around the lack of proper
1225 // source information in nested-name-specifiers (PR5791). Since we do have
1226 // a beginning source location, we can visit the first component of the
1227 // nested-name-specifier, if it's a single-token component.
1228 if (!NNS)
1229 return false;
1230
1231 // Get the first component in the nested-name-specifier.
1232 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1233 NNS = Prefix;
1234
1235 switch (NNS->getKind()) {
1236 case NestedNameSpecifier::Namespace:
1237 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1238 TU));
1239
1240 case NestedNameSpecifier::NamespaceAlias:
1241 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1242 Range.getBegin(), TU));
1243
1244 case NestedNameSpecifier::TypeSpec: {
1245 // If the type has a form where we know that the beginning of the source
1246 // range matches up with a reference cursor. Visit the appropriate reference
1247 // cursor.
1248 const Type *T = NNS->getAsType();
1249 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1250 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1251 if (const TagType *Tag = dyn_cast<TagType>(T))
1252 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1253 if (const TemplateSpecializationType *TST
1254 = dyn_cast<TemplateSpecializationType>(T))
1255 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1256 break;
1257 }
1258
1259 case NestedNameSpecifier::TypeSpecWithTemplate:
1260 case NestedNameSpecifier::Global:
1261 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001262 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001263 break;
1264 }
1265
1266 return false;
1267}
1268
1269bool
1270CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1271 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1272 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1273 Qualifiers.push_back(Qualifier);
1274
1275 while (!Qualifiers.empty()) {
1276 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1277 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1278 switch (NNS->getKind()) {
1279 case NestedNameSpecifier::Namespace:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::NamespaceAlias:
1288 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1289 Q.getLocalBeginLoc(),
1290 TU)))
1291 return true;
1292
1293 break;
1294
1295 case NestedNameSpecifier::TypeSpec:
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 if (Visit(Q.getTypeLoc()))
1298 return true;
1299
1300 break;
1301
1302 case NestedNameSpecifier::Global:
1303 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001304 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001305 break;
1306 }
1307 }
1308
1309 return false;
1310}
1311
1312bool CursorVisitor::VisitTemplateParameters(
1313 const TemplateParameterList *Params) {
1314 if (!Params)
1315 return false;
1316
1317 for (TemplateParameterList::const_iterator P = Params->begin(),
1318 PEnd = Params->end();
1319 P != PEnd; ++P) {
1320 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1321 return true;
1322 }
1323
1324 return false;
1325}
1326
1327bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1328 switch (Name.getKind()) {
1329 case TemplateName::Template:
1330 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1331
1332 case TemplateName::OverloadedTemplate:
1333 // Visit the overloaded template set.
1334 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1335 return true;
1336
1337 return false;
1338
1339 case TemplateName::DependentTemplate:
1340 // FIXME: Visit nested-name-specifier.
1341 return false;
1342
1343 case TemplateName::QualifiedTemplate:
1344 // FIXME: Visit nested-name-specifier.
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsQualifiedTemplateName()->getDecl(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParm:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1352 Loc, TU));
1353
1354 case TemplateName::SubstTemplateTemplateParmPack:
1355 return Visit(MakeCursorTemplateRef(
1356 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1357 Loc, TU));
1358 }
1359
1360 llvm_unreachable("Invalid TemplateName::Kind!");
1361}
1362
1363bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1364 switch (TAL.getArgument().getKind()) {
1365 case TemplateArgument::Null:
1366 case TemplateArgument::Integral:
1367 case TemplateArgument::Pack:
1368 return false;
1369
1370 case TemplateArgument::Type:
1371 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1372 return Visit(TSInfo->getTypeLoc());
1373 return false;
1374
1375 case TemplateArgument::Declaration:
1376 if (Expr *E = TAL.getSourceDeclExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::NullPtr:
1381 if (Expr *E = TAL.getSourceNullPtrExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Expression:
1386 if (Expr *E = TAL.getSourceExpression())
1387 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1388 return false;
1389
1390 case TemplateArgument::Template:
1391 case TemplateArgument::TemplateExpansion:
1392 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1393 return true;
1394
1395 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1396 TAL.getTemplateNameLoc());
1397 }
1398
1399 llvm_unreachable("Invalid TemplateArgument::Kind!");
1400}
1401
1402bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1403 return VisitDeclContext(D);
1404}
1405
1406bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1407 return Visit(TL.getUnqualifiedLoc());
1408}
1409
1410bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1411 ASTContext &Context = AU->getASTContext();
1412
1413 // Some builtin types (such as Objective-C's "id", "sel", and
1414 // "Class") have associated declarations. Create cursors for those.
1415 QualType VisitType;
1416 switch (TL.getTypePtr()->getKind()) {
1417
1418 case BuiltinType::Void:
1419 case BuiltinType::NullPtr:
1420 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001421 case BuiltinType::OCLImage1d:
1422 case BuiltinType::OCLImage1dArray:
1423 case BuiltinType::OCLImage1dBuffer:
1424 case BuiltinType::OCLImage2d:
1425 case BuiltinType::OCLImage2dArray:
1426 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001427 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001428 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001429#define BUILTIN_TYPE(Id, SingletonId)
1430#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1434#include "clang/AST/BuiltinTypes.def"
1435 break;
1436
1437 case BuiltinType::ObjCId:
1438 VisitType = Context.getObjCIdType();
1439 break;
1440
1441 case BuiltinType::ObjCClass:
1442 VisitType = Context.getObjCClassType();
1443 break;
1444
1445 case BuiltinType::ObjCSel:
1446 VisitType = Context.getObjCSelType();
1447 break;
1448 }
1449
1450 if (!VisitType.isNull()) {
1451 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1452 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1453 TU));
1454 }
1455
1456 return false;
1457}
1458
1459bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1460 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1468 if (TL.isDefinition())
1469 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1470
1471 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1472}
1473
1474bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1475 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1476}
1477
1478bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1479 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1480 return true;
1481
1482 return false;
1483}
1484
1485bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1486 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1487 return true;
1488
1489 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1490 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1491 TU)))
1492 return true;
1493 }
1494
1495 return false;
1496}
1497
1498bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1499 return Visit(TL.getPointeeLoc());
1500}
1501
1502bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1503 return Visit(TL.getInnerLoc());
1504}
1505
1506bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1507 return Visit(TL.getPointeeLoc());
1508}
1509
1510bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1511 return Visit(TL.getPointeeLoc());
1512}
1513
1514bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1515 return Visit(TL.getPointeeLoc());
1516}
1517
1518bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1519 return Visit(TL.getPointeeLoc());
1520}
1521
1522bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1523 return Visit(TL.getPointeeLoc());
1524}
1525
1526bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1527 return Visit(TL.getModifiedLoc());
1528}
1529
1530bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1531 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001532 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001533 return true;
1534
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001535 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1536 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001537 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1538 return true;
1539
1540 return false;
1541}
1542
1543bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1544 if (Visit(TL.getElementLoc()))
1545 return true;
1546
1547 if (Expr *Size = TL.getSizeExpr())
1548 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1549
1550 return false;
1551}
1552
Reid Kleckner8a365022013-06-24 17:51:48 +00001553bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1554 return Visit(TL.getOriginalLoc());
1555}
1556
Reid Kleckner0503a872013-12-05 01:23:43 +00001557bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1558 return Visit(TL.getOriginalLoc());
1559}
1560
Guy Benyei11169dd2012-12-18 14:30:41 +00001561bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1562 TemplateSpecializationTypeLoc TL) {
1563 // Visit the template name.
1564 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1565 TL.getTemplateNameLoc()))
1566 return true;
1567
1568 // Visit the template arguments.
1569 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1570 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1571 return true;
1572
1573 return false;
1574}
1575
1576bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1577 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1578}
1579
1580bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1581 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1582 return Visit(TSInfo->getTypeLoc());
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1588 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1589 return Visit(TSInfo->getTypeLoc());
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1595 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1596 return true;
1597
1598 return false;
1599}
1600
1601bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1602 DependentTemplateSpecializationTypeLoc TL) {
1603 // Visit the nested-name-specifier, if there is one.
1604 if (TL.getQualifierLoc() &&
1605 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1606 return true;
1607
1608 // Visit the template arguments.
1609 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1610 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1611 return true;
1612
1613 return false;
1614}
1615
1616bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1617 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1618 return true;
1619
1620 return Visit(TL.getNamedTypeLoc());
1621}
1622
1623bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1624 return Visit(TL.getPatternLoc());
1625}
1626
1627bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1628 if (Expr *E = TL.getUnderlyingExpr())
1629 return Visit(MakeCXCursor(E, StmtParent, TU));
1630
1631 return false;
1632}
1633
1634bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1635 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1636}
1637
1638bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1639 return Visit(TL.getValueLoc());
1640}
1641
1642#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1643bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1644 return Visit##PARENT##Loc(TL); \
1645}
1646
1647DEFAULT_TYPELOC_IMPL(Complex, Type)
1648DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1652DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1653DEFAULT_TYPELOC_IMPL(Vector, Type)
1654DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1655DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1656DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1657DEFAULT_TYPELOC_IMPL(Record, TagType)
1658DEFAULT_TYPELOC_IMPL(Enum, TagType)
1659DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1660DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1661DEFAULT_TYPELOC_IMPL(Auto, Type)
1662
1663bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1664 // Visit the nested-name-specifier, if present.
1665 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1666 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1667 return true;
1668
1669 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001670 for (const auto &I : D->bases()) {
1671 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001672 return true;
1673 }
1674 }
1675
1676 return VisitTagDecl(D);
1677}
1678
1679bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001680 for (const auto *I : D->attrs())
1681 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001682 return true;
1683
1684 return false;
1685}
1686
1687//===----------------------------------------------------------------------===//
1688// Data-recursive visitor methods.
1689//===----------------------------------------------------------------------===//
1690
1691namespace {
1692#define DEF_JOB(NAME, DATA, KIND)\
1693class NAME : public VisitorJob {\
1694public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001695 NAME(const DATA *d, CXCursor parent) : \
1696 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001697 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001698 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001699};
1700
1701DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1702DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1703DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1704DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1705DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1706 ExplicitTemplateArgsVisitKind)
1707DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1708DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1709DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1710#undef DEF_JOB
1711
1712class DeclVisit : public VisitorJob {
1713public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001714 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001715 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001716 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001717 static bool classof(const VisitorJob *VJ) {
1718 return VJ->getKind() == DeclVisitKind;
1719 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001720 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001721 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001722};
1723class TypeLocVisit : public VisitorJob {
1724public:
1725 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1726 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1727 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1728
1729 static bool classof(const VisitorJob *VJ) {
1730 return VJ->getKind() == TypeLocVisitKind;
1731 }
1732
1733 TypeLoc get() const {
1734 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001735 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001736 }
1737};
1738
1739class LabelRefVisit : public VisitorJob {
1740public:
1741 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1742 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1743 labelLoc.getPtrEncoding()) {}
1744
1745 static bool classof(const VisitorJob *VJ) {
1746 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1747 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 const LabelDecl *get() const {
1749 return static_cast<const LabelDecl *>(data[0]);
1750 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001751 SourceLocation getLoc() const {
1752 return SourceLocation::getFromPtrEncoding(data[1]); }
1753};
1754
1755class NestedNameSpecifierLocVisit : public VisitorJob {
1756public:
1757 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1758 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1759 Qualifier.getNestedNameSpecifier(),
1760 Qualifier.getOpaqueData()) { }
1761
1762 static bool classof(const VisitorJob *VJ) {
1763 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1764 }
1765
1766 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 return NestedNameSpecifierLoc(
1768 const_cast<NestedNameSpecifier *>(
1769 static_cast<const NestedNameSpecifier *>(data[0])),
1770 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001771 }
1772};
1773
1774class DeclarationNameInfoVisit : public VisitorJob {
1775public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001776 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001777 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 static bool classof(const VisitorJob *VJ) {
1779 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1780 }
1781 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001782 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001783 switch (S->getStmtClass()) {
1784 default:
1785 llvm_unreachable("Unhandled Stmt");
1786 case clang::Stmt::MSDependentExistsStmtClass:
1787 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1788 case Stmt::CXXDependentScopeMemberExprClass:
1789 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1790 case Stmt::DependentScopeDeclRefExprClass:
1791 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001792 case Stmt::OMPCriticalDirectiveClass:
1793 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001794 }
1795 }
1796};
1797class MemberRefVisit : public VisitorJob {
1798public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001799 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1801 L.getPtrEncoding()) {}
1802 static bool classof(const VisitorJob *VJ) {
1803 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1804 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001805 const FieldDecl *get() const {
1806 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001807 }
1808 SourceLocation getLoc() const {
1809 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1810 }
1811};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001812class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001813 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001814 VisitorWorkList &WL;
1815 CXCursor Parent;
1816public:
1817 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1818 : WL(wl), Parent(parent) {}
1819
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001820 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1821 void VisitBlockExpr(const BlockExpr *B);
1822 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1823 void VisitCompoundStmt(const CompoundStmt *S);
1824 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1825 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1826 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1827 void VisitCXXNewExpr(const CXXNewExpr *E);
1828 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1829 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1830 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1831 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1832 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1833 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1834 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1835 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001836 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001837 void VisitDeclRefExpr(const DeclRefExpr *D);
1838 void VisitDeclStmt(const DeclStmt *S);
1839 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1840 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1841 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1842 void VisitForStmt(const ForStmt *FS);
1843 void VisitGotoStmt(const GotoStmt *GS);
1844 void VisitIfStmt(const IfStmt *If);
1845 void VisitInitListExpr(const InitListExpr *IE);
1846 void VisitMemberExpr(const MemberExpr *M);
1847 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1848 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1849 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1850 void VisitOverloadExpr(const OverloadExpr *E);
1851 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1852 void VisitStmt(const Stmt *S);
1853 void VisitSwitchStmt(const SwitchStmt *S);
1854 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1856 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1857 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1858 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1859 void VisitVAArgExpr(const VAArgExpr *E);
1860 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1861 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1862 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1863 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001865 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001867 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001868 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001869 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001870 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001871 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001872 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001873 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001874 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001875 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001876 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001877 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001878 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001879 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001880 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001881 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001882 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001883 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001884 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001885 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001886 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887
Guy Benyei11169dd2012-12-18 14:30:41 +00001888private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1891 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1893 void AddStmt(const Stmt *S);
1894 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001897 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001898};
1899} // end anonyous namespace
1900
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 // 'S' should always be non-null, since it comes from the
1903 // statement we are visiting.
1904 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1905}
1906
1907void
1908EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1909 if (Qualifier)
1910 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1911}
1912
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 if (S)
1915 WL.push_back(StmtVisit(S, Parent));
1916}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001918 if (D)
1919 WL.push_back(DeclVisit(D, Parent, isFirst));
1920}
1921void EnqueueVisitor::
1922 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1923 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001924 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001925}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001926void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001927 if (D)
1928 WL.push_back(MemberRefVisit(D, L, Parent));
1929}
1930void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1931 if (TI)
1932 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1933 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001934void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001935 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001936 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 AddStmt(*Child);
1938 }
1939 if (size == WL.size())
1940 return;
1941 // Now reverse the entries we just added. This will match the DFS
1942 // ordering performed by the worklist.
1943 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1944 std::reverse(I, E);
1945}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946namespace {
1947class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1948 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001949 /// \brief Process clauses with list of variables.
1950 template <typename T>
1951 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001952public:
1953 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1954#define OPENMP_CLAUSE(Name, Class) \
1955 void Visit##Class(const Class *C);
1956#include "clang/Basic/OpenMPKinds.def"
1957};
1958
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001959void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1960 Visitor->AddStmt(C->getCondition());
1961}
1962
Alexey Bataev3778b602014-07-17 07:32:53 +00001963void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1964 Visitor->AddStmt(C->getCondition());
1965}
1966
Alexey Bataev568a8332014-03-06 06:15:19 +00001967void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1968 Visitor->AddStmt(C->getNumThreads());
1969}
1970
Alexey Bataev62c87d22014-03-21 04:51:18 +00001971void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1972 Visitor->AddStmt(C->getSafelen());
1973}
1974
Alexander Musman8bd31e62014-05-27 15:12:19 +00001975void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1976 Visitor->AddStmt(C->getNumForLoops());
1977}
1978
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001979void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001980
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001981void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1982
Alexey Bataev56dafe82014-06-20 07:16:17 +00001983void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1984 Visitor->AddStmt(C->getChunkSize());
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);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002073 for (auto *E : C->source_exprs()) {
2074 Visitor->AddStmt(E);
2075 }
2076 for (auto *E : C->destination_exprs()) {
2077 Visitor->AddStmt(E);
2078 }
2079 for (auto *E : C->assignment_ops()) {
2080 Visitor->AddStmt(E);
2081 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002082}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002083void
2084OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2085 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002086 for (auto *E : C->source_exprs()) {
2087 Visitor->AddStmt(E);
2088 }
2089 for (auto *E : C->destination_exprs()) {
2090 Visitor->AddStmt(E);
2091 }
2092 for (auto *E : C->assignment_ops()) {
2093 Visitor->AddStmt(E);
2094 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002095}
Alexey Bataev6125da92014-07-21 11:26:11 +00002096void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2097 VisitOMPClauseList(C);
2098}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002099}
Alexey Bataev756c1962013-09-24 03:17:45 +00002100
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002101void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2102 unsigned size = WL.size();
2103 OMPClauseEnqueue Visitor(this);
2104 Visitor.Visit(S);
2105 if (size == WL.size())
2106 return;
2107 // Now reverse the entries we just added. This will match the DFS
2108 // ordering performed by the worklist.
2109 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2110 std::reverse(I, E);
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 AddDecl(B->getBlockDecl());
2117}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 EnqueueChildren(E);
2120 AddTypeLoc(E->getTypeSourceInfo());
2121}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2123 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 E = S->body_rend(); I != E; ++I) {
2125 AddStmt(*I);
2126 }
2127}
2128void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 AddStmt(S->getSubStmt());
2131 AddDeclarationNameInfo(S);
2132 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2133 AddNestedNameSpecifierLoc(QualifierLoc);
2134}
2135
2136void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2139 AddDeclarationNameInfo(E);
2140 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2141 AddNestedNameSpecifierLoc(QualifierLoc);
2142 if (!E->isImplicitAccess())
2143 AddStmt(E->getBase());
2144}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002145void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002146 // Enqueue the initializer , if any.
2147 AddStmt(E->getInitializer());
2148 // Enqueue the array size, if any.
2149 AddStmt(E->getArraySize());
2150 // Enqueue the allocated type.
2151 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2152 // Enqueue the placement arguments.
2153 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2154 AddStmt(E->getPlacementArg(I-1));
2155}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002157 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2158 AddStmt(CE->getArg(I-1));
2159 AddStmt(CE->getCallee());
2160 AddStmt(CE->getArg(0));
2161}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002162void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2163 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 // Visit the name of the type being destroyed.
2165 AddTypeLoc(E->getDestroyedTypeInfo());
2166 // Visit the scope type that looks disturbingly like the nested-name-specifier
2167 // but isn't.
2168 AddTypeLoc(E->getScopeTypeInfo());
2169 // Visit the nested-name-specifier.
2170 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2171 AddNestedNameSpecifierLoc(QualifierLoc);
2172 // Visit base expression.
2173 AddStmt(E->getBase());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2176 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002177 AddTypeLoc(E->getTypeSourceInfo());
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2180 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 EnqueueChildren(E);
2182 AddTypeLoc(E->getTypeSourceInfo());
2183}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 EnqueueChildren(E);
2186 if (E->isTypeOperand())
2187 AddTypeLoc(E->getTypeOperandSourceInfo());
2188}
2189
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2191 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 EnqueueChildren(E);
2193 AddTypeLoc(E->getTypeSourceInfo());
2194}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002196 EnqueueChildren(E);
2197 if (E->isTypeOperand())
2198 AddTypeLoc(E->getTypeOperandSourceInfo());
2199}
2200
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002201void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002202 EnqueueChildren(S);
2203 AddDecl(S->getExceptionDecl());
2204}
2205
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002206void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002207 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002208 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002209 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002210}
2211
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 if (DR->hasExplicitTemplateArgs()) {
2214 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2215 }
2216 WL.push_back(DeclRefExprParts(DR, Parent));
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2219 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2221 AddDeclarationNameInfo(E);
2222 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 unsigned size = WL.size();
2226 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002227 for (const auto *D : S->decls()) {
2228 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 isFirst = false;
2230 }
2231 if (size == WL.size())
2232 return;
2233 // Now reverse the entries we just added. This will match the DFS
2234 // ordering performed by the worklist.
2235 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2236 std::reverse(I, E);
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002240 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 D = E->designators_rbegin(), DEnd = E->designators_rend();
2242 D != DEnd; ++D) {
2243 if (D->isFieldDesignator()) {
2244 if (FieldDecl *Field = D->getField())
2245 AddMemberRef(Field, D->getFieldLoc());
2246 continue;
2247 }
2248 if (D->isArrayDesignator()) {
2249 AddStmt(E->getArrayIndex(*D));
2250 continue;
2251 }
2252 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2253 AddStmt(E->getArrayRangeEnd(*D));
2254 AddStmt(E->getArrayRangeStart(*D));
2255 }
2256}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 EnqueueChildren(E);
2259 AddTypeLoc(E->getTypeInfoAsWritten());
2260}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 AddStmt(FS->getBody());
2263 AddStmt(FS->getInc());
2264 AddStmt(FS->getCond());
2265 AddDecl(FS->getConditionVariable());
2266 AddStmt(FS->getInit());
2267}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 AddStmt(If->getElse());
2273 AddStmt(If->getThen());
2274 AddStmt(If->getCond());
2275 AddDecl(If->getConditionVariable());
2276}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 // We care about the syntactic form of the initializer list, only.
2279 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2280 IE = Syntactic;
2281 EnqueueChildren(IE);
2282}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002283void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 WL.push_back(MemberExprParts(M, Parent));
2285
2286 // If the base of the member access expression is an implicit 'this', don't
2287 // visit it.
2288 // FIXME: If we ever want to show these implicit accesses, this will be
2289 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002290 if (M->isImplicitAccess())
2291 return;
2292
2293 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2294 // real field that that we are interested in.
2295 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2296 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2297 if (FD->isAnonymousStructOrUnion()) {
2298 AddStmt(SubME->getBase());
2299 return;
2300 }
2301 }
2302 }
2303
2304 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002305}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002306void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002307 AddTypeLoc(E->getEncodedTypeSourceInfo());
2308}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 EnqueueChildren(M);
2311 AddTypeLoc(M->getClassReceiverTypeInfo());
2312}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 // Visit the components of the offsetof expression.
2315 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2316 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2317 const OffsetOfNode &Node = E->getComponent(I-1);
2318 switch (Node.getKind()) {
2319 case OffsetOfNode::Array:
2320 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2321 break;
2322 case OffsetOfNode::Field:
2323 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2324 break;
2325 case OffsetOfNode::Identifier:
2326 case OffsetOfNode::Base:
2327 continue;
2328 }
2329 }
2330 // Visit the type into which we're computing the offset.
2331 AddTypeLoc(E->getTypeSourceInfo());
2332}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002333void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002334 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2335 WL.push_back(OverloadExprParts(E, Parent));
2336}
2337void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002338 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002339 EnqueueChildren(E);
2340 if (E->isArgumentType())
2341 AddTypeLoc(E->getArgumentTypeInfo());
2342}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002343void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002344 EnqueueChildren(S);
2345}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002346void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002347 AddStmt(S->getBody());
2348 AddStmt(S->getCond());
2349 AddDecl(S->getConditionVariable());
2350}
2351
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002352void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002353 AddStmt(W->getBody());
2354 AddStmt(W->getCond());
2355 AddDecl(W->getConditionVariable());
2356}
2357
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002358void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002359 for (unsigned I = E->getNumArgs(); I > 0; --I)
2360 AddTypeLoc(E->getArg(I-1));
2361}
2362
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002363void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002364 AddTypeLoc(E->getQueriedTypeSourceInfo());
2365}
2366
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002367void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002368 EnqueueChildren(E);
2369}
2370
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002371void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002372 VisitOverloadExpr(U);
2373 if (!U->isImplicitAccess())
2374 AddStmt(U->getBase());
2375}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002376void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 AddStmt(E->getSubExpr());
2378 AddTypeLoc(E->getWrittenTypeInfo());
2379}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002380void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002381 WL.push_back(SizeOfPackExprParts(E, Parent));
2382}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 // If the opaque value has a source expression, just transparently
2385 // visit that. This is useful for (e.g.) pseudo-object expressions.
2386 if (Expr *SourceExpr = E->getSourceExpr())
2387 return Visit(SourceExpr);
2388}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002389void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002390 AddStmt(E->getBody());
2391 WL.push_back(LambdaExprParts(E, Parent));
2392}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002393void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002394 // Treat the expression like its syntactic form.
2395 Visit(E->getSyntacticForm());
2396}
2397
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002398void EnqueueVisitor::VisitOMPExecutableDirective(
2399 const OMPExecutableDirective *D) {
2400 EnqueueChildren(D);
2401 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2402 E = D->clauses().end();
2403 I != E; ++I)
2404 EnqueueChildren(*I);
2405}
2406
Alexander Musman3aaab662014-08-19 11:27:13 +00002407void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2408 VisitOMPExecutableDirective(D);
2409}
2410
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002411void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2412 VisitOMPExecutableDirective(D);
2413}
2414
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002415void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002416 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002417}
2418
Alexey Bataevf29276e2014-06-18 04:14:57 +00002419void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002420 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002421}
2422
Alexander Musmanf82886e2014-09-18 05:12:34 +00002423void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2424 VisitOMPLoopDirective(D);
2425}
2426
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002427void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2428 VisitOMPExecutableDirective(D);
2429}
2430
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002431void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2432 VisitOMPExecutableDirective(D);
2433}
2434
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002435void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2436 VisitOMPExecutableDirective(D);
2437}
2438
Alexander Musman80c22892014-07-17 08:54:58 +00002439void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2440 VisitOMPExecutableDirective(D);
2441}
2442
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002443void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2444 VisitOMPExecutableDirective(D);
2445 AddDeclarationNameInfo(D);
2446}
2447
Alexey Bataev4acb8592014-07-07 13:01:15 +00002448void
2449EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002450 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002451}
2452
Alexander Musmane4e893b2014-09-23 09:33:00 +00002453void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2454 const OMPParallelForSimdDirective *D) {
2455 VisitOMPLoopDirective(D);
2456}
2457
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002458void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2459 const OMPParallelSectionsDirective *D) {
2460 VisitOMPExecutableDirective(D);
2461}
2462
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002463void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2464 VisitOMPExecutableDirective(D);
2465}
2466
Alexey Bataev68446b72014-07-18 07:47:19 +00002467void
2468EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2469 VisitOMPExecutableDirective(D);
2470}
2471
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002472void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2473 VisitOMPExecutableDirective(D);
2474}
2475
Alexey Bataev2df347a2014-07-18 10:17:07 +00002476void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2477 VisitOMPExecutableDirective(D);
2478}
2479
Alexey Bataev6125da92014-07-21 11:26:11 +00002480void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2481 VisitOMPExecutableDirective(D);
2482}
2483
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002484void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2485 VisitOMPExecutableDirective(D);
2486}
2487
Alexey Bataev0162e452014-07-22 10:10:35 +00002488void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2489 VisitOMPExecutableDirective(D);
2490}
2491
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002492void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2493 VisitOMPExecutableDirective(D);
2494}
2495
Alexey Bataev13314bf2014-10-09 04:18:56 +00002496void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2497 VisitOMPExecutableDirective(D);
2498}
2499
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002500void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002501 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2502}
2503
2504bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2505 if (RegionOfInterest.isValid()) {
2506 SourceRange Range = getRawCursorExtent(C);
2507 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2508 return false;
2509 }
2510 return true;
2511}
2512
2513bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2514 while (!WL.empty()) {
2515 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002516 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002517
2518 // Set the Parent field, then back to its old value once we're done.
2519 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2520
2521 switch (LI.getKind()) {
2522 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002523 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002524 if (!D)
2525 continue;
2526
2527 // For now, perform default visitation for Decls.
2528 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2529 cast<DeclVisit>(&LI)->isFirst())))
2530 return true;
2531
2532 continue;
2533 }
2534 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2535 const ASTTemplateArgumentListInfo *ArgList =
2536 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2537 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2538 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2539 Arg != ArgEnd; ++Arg) {
2540 if (VisitTemplateArgumentLoc(*Arg))
2541 return true;
2542 }
2543 continue;
2544 }
2545 case VisitorJob::TypeLocVisitKind: {
2546 // Perform default visitation for TypeLocs.
2547 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2548 return true;
2549 continue;
2550 }
2551 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002552 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002553 if (LabelStmt *stmt = LS->getStmt()) {
2554 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2555 TU))) {
2556 return true;
2557 }
2558 }
2559 continue;
2560 }
2561
2562 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2563 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2564 if (VisitNestedNameSpecifierLoc(V->get()))
2565 return true;
2566 continue;
2567 }
2568
2569 case VisitorJob::DeclarationNameInfoVisitKind: {
2570 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2571 ->get()))
2572 return true;
2573 continue;
2574 }
2575 case VisitorJob::MemberRefVisitKind: {
2576 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2577 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2578 return true;
2579 continue;
2580 }
2581 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002582 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002583 if (!S)
2584 continue;
2585
2586 // Update the current cursor.
2587 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2588 if (!IsInRegionOfInterest(Cursor))
2589 continue;
2590 switch (Visitor(Cursor, Parent, ClientData)) {
2591 case CXChildVisit_Break: return true;
2592 case CXChildVisit_Continue: break;
2593 case CXChildVisit_Recurse:
2594 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002595 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002596 EnqueueWorkList(WL, S);
2597 break;
2598 }
2599 continue;
2600 }
2601 case VisitorJob::MemberExprPartsKind: {
2602 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002603 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002604
2605 // Visit the nested-name-specifier
2606 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2607 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2608 return true;
2609
2610 // Visit the declaration name.
2611 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2612 return true;
2613
2614 // Visit the explicitly-specified template arguments, if any.
2615 if (M->hasExplicitTemplateArgs()) {
2616 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2617 *ArgEnd = Arg + M->getNumTemplateArgs();
2618 Arg != ArgEnd; ++Arg) {
2619 if (VisitTemplateArgumentLoc(*Arg))
2620 return true;
2621 }
2622 }
2623 continue;
2624 }
2625 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002626 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002627 // Visit nested-name-specifier, if present.
2628 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2629 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2630 return true;
2631 // Visit declaration name.
2632 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2633 return true;
2634 continue;
2635 }
2636 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002637 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002638 // Visit the nested-name-specifier.
2639 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2640 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2641 return true;
2642 // Visit the declaration name.
2643 if (VisitDeclarationNameInfo(O->getNameInfo()))
2644 return true;
2645 // Visit the overloaded declaration reference.
2646 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2647 return true;
2648 continue;
2649 }
2650 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002651 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002652 NamedDecl *Pack = E->getPack();
2653 if (isa<TemplateTypeParmDecl>(Pack)) {
2654 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2655 E->getPackLoc(), TU)))
2656 return true;
2657
2658 continue;
2659 }
2660
2661 if (isa<TemplateTemplateParmDecl>(Pack)) {
2662 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2663 E->getPackLoc(), TU)))
2664 return true;
2665
2666 continue;
2667 }
2668
2669 // Non-type template parameter packs and function parameter packs are
2670 // treated like DeclRefExpr cursors.
2671 continue;
2672 }
2673
2674 case VisitorJob::LambdaExprPartsKind: {
2675 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002676 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002677 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2678 CEnd = E->explicit_capture_end();
2679 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002680 // FIXME: Lambda init-captures.
2681 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002682 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002683
Guy Benyei11169dd2012-12-18 14:30:41 +00002684 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2685 C->getLocation(),
2686 TU)))
2687 return true;
2688 }
2689
2690 // Visit parameters and return type, if present.
2691 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2692 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2693 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2694 // Visit the whole type.
2695 if (Visit(TL))
2696 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002697 } else if (FunctionProtoTypeLoc Proto =
2698 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002699 if (E->hasExplicitParameters()) {
2700 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002701 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2702 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002703 return true;
2704 } else {
2705 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002706 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002707 return true;
2708 }
2709 }
2710 }
2711 break;
2712 }
2713
2714 case VisitorJob::PostChildrenVisitKind:
2715 if (PostChildrenVisitor(Parent, ClientData))
2716 return true;
2717 break;
2718 }
2719 }
2720 return false;
2721}
2722
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002723bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002724 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002725 if (!WorkListFreeList.empty()) {
2726 WL = WorkListFreeList.back();
2727 WL->clear();
2728 WorkListFreeList.pop_back();
2729 }
2730 else {
2731 WL = new VisitorWorkList();
2732 WorkListCache.push_back(WL);
2733 }
2734 EnqueueWorkList(*WL, S);
2735 bool result = RunVisitorWorkList(*WL);
2736 WorkListFreeList.push_back(WL);
2737 return result;
2738}
2739
2740namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002741typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002742RefNamePieces
2743buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2744 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2745 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002746 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2747 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2748 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2749
2750 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2751
2752 RefNamePieces Pieces;
2753
2754 if (WantQualifier && QLoc.isValid())
2755 Pieces.push_back(QLoc);
2756
2757 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2758 Pieces.push_back(NI.getLoc());
2759
2760 if (WantTemplateArgs && TemplateArgs)
2761 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2762 TemplateArgs->RAngleLoc));
2763
2764 if (Kind == DeclarationName::CXXOperatorName) {
2765 Pieces.push_back(SourceLocation::getFromRawEncoding(
2766 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2767 Pieces.push_back(SourceLocation::getFromRawEncoding(
2768 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2769 }
2770
2771 if (WantSinglePiece) {
2772 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2773 Pieces.clear();
2774 Pieces.push_back(R);
2775 }
2776
2777 return Pieces;
2778}
2779}
2780
2781//===----------------------------------------------------------------------===//
2782// Misc. API hooks.
2783//===----------------------------------------------------------------------===//
2784
Chad Rosier05c71aa2013-03-27 18:28:23 +00002785static void fatal_error_handler(void *user_data, const std::string& reason,
2786 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002787 // Write the result out to stderr avoiding errs() because raw_ostreams can
2788 // call report_fatal_error.
2789 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2790 ::abort();
2791}
2792
Chandler Carruth66660742014-06-27 16:37:27 +00002793namespace {
2794struct RegisterFatalErrorHandler {
2795 RegisterFatalErrorHandler() {
2796 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2797 }
2798};
2799}
2800
2801static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2802
Guy Benyei11169dd2012-12-18 14:30:41 +00002803extern "C" {
2804CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2805 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002806 // We use crash recovery to make some of our APIs more reliable, implicitly
2807 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002808 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2809 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002810
Chandler Carruth66660742014-06-27 16:37:27 +00002811 // Look through the managed static to trigger construction of the managed
2812 // static which registers our fatal error handler. This ensures it is only
2813 // registered once.
2814 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002815
2816 CIndexer *CIdxr = new CIndexer();
2817 if (excludeDeclarationsFromPCH)
2818 CIdxr->setOnlyLocalDecls();
2819 if (displayDiagnostics)
2820 CIdxr->setDisplayDiagnostics();
2821
2822 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2823 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2824 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2825 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2826 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2827 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2828
2829 return CIdxr;
2830}
2831
2832void clang_disposeIndex(CXIndex CIdx) {
2833 if (CIdx)
2834 delete static_cast<CIndexer *>(CIdx);
2835}
2836
2837void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2838 if (CIdx)
2839 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2840}
2841
2842unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2843 if (CIdx)
2844 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2845 return 0;
2846}
2847
2848void clang_toggleCrashRecovery(unsigned isEnabled) {
2849 if (isEnabled)
2850 llvm::CrashRecoveryContext::Enable();
2851 else
2852 llvm::CrashRecoveryContext::Disable();
2853}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002854
Guy Benyei11169dd2012-12-18 14:30:41 +00002855CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2856 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002857 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002858 enum CXErrorCode Result =
2859 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002860 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002861 assert((TU && Result == CXError_Success) ||
2862 (!TU && Result != CXError_Success));
2863 return TU;
2864}
2865
2866enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2867 const char *ast_filename,
2868 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002869 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002870 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002871
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002872 if (!CIdx || !ast_filename || !out_TU)
2873 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002874
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002875 LOG_FUNC_SECTION {
2876 *Log << ast_filename;
2877 }
2878
Guy Benyei11169dd2012-12-18 14:30:41 +00002879 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2880 FileSystemOptions FileSystemOpts;
2881
Justin Bognerd512c1e2014-10-15 00:33:06 +00002882 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2883 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002884 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2885 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2886 /*CaptureDiagnostics=*/true,
2887 /*AllowPCHWithCompilerErrors=*/true,
2888 /*UserFilesAreVolatile=*/true);
2889 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002890 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002891}
2892
2893unsigned clang_defaultEditingTranslationUnitOptions() {
2894 return CXTranslationUnit_PrecompiledPreamble |
2895 CXTranslationUnit_CacheCompletionResults;
2896}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002897
Guy Benyei11169dd2012-12-18 14:30:41 +00002898CXTranslationUnit
2899clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2900 const char *source_filename,
2901 int num_command_line_args,
2902 const char * const *command_line_args,
2903 unsigned num_unsaved_files,
2904 struct CXUnsavedFile *unsaved_files) {
2905 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2906 return clang_parseTranslationUnit(CIdx, source_filename,
2907 command_line_args, num_command_line_args,
2908 unsaved_files, num_unsaved_files,
2909 Options);
2910}
2911
2912struct ParseTranslationUnitInfo {
2913 CXIndex CIdx;
2914 const char *source_filename;
2915 const char *const *command_line_args;
2916 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002917 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002918 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002919 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002920 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002921};
2922static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002923 const ParseTranslationUnitInfo *PTUI =
2924 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002925 CXIndex CIdx = PTUI->CIdx;
2926 const char *source_filename = PTUI->source_filename;
2927 const char * const *command_line_args = PTUI->command_line_args;
2928 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002929 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002930 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002931
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002932 // Set up the initial return values.
2933 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002934 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002935
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002936 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002937 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002938 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002939 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002940 }
2941
Guy Benyei11169dd2012-12-18 14:30:41 +00002942 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2943
2944 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2945 setThreadBackgroundPriority();
2946
2947 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2948 // FIXME: Add a flag for modules.
2949 TranslationUnitKind TUKind
2950 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002951 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002952 = options & CXTranslationUnit_CacheCompletionResults;
2953 bool IncludeBriefCommentsInCodeCompletion
2954 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2955 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2956 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2957
2958 // Configure the diagnostics.
2959 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002960 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002961
2962 // Recover resources if we crash before exiting this function.
2963 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2964 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002965 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002966
Ahmed Charlesb8984322014-03-07 20:03:18 +00002967 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2968 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002969
2970 // Recover resources if we crash before exiting this function.
2971 llvm::CrashRecoveryContextCleanupRegistrar<
2972 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2973
Alp Toker9d85b182014-07-07 01:23:14 +00002974 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002975 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002976 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002977 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002978 }
2979
Ahmed Charlesb8984322014-03-07 20:03:18 +00002980 std::unique_ptr<std::vector<const char *>> Args(
2981 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002982
2983 // Recover resources if we crash before exiting this method.
2984 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2985 ArgsCleanup(Args.get());
2986
2987 // Since the Clang C library is primarily used by batch tools dealing with
2988 // (often very broken) source code, where spell-checking can have a
2989 // significant negative impact on performance (particularly when
2990 // precompiled headers are involved), we disable it by default.
2991 // Only do this if we haven't found a spell-checking-related argument.
2992 bool FoundSpellCheckingArgument = false;
2993 for (int I = 0; I != num_command_line_args; ++I) {
2994 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2995 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2996 FoundSpellCheckingArgument = true;
2997 break;
2998 }
2999 }
3000 if (!FoundSpellCheckingArgument)
3001 Args->push_back("-fno-spell-checking");
3002
3003 Args->insert(Args->end(), command_line_args,
3004 command_line_args + num_command_line_args);
3005
3006 // The 'source_filename' argument is optional. If the caller does not
3007 // specify it then it is assumed that the source file is specified
3008 // in the actual argument list.
3009 // Put the source file after command_line_args otherwise if '-x' flag is
3010 // present it will be unused.
3011 if (source_filename)
3012 Args->push_back(source_filename);
3013
3014 // Do we need the detailed preprocessing record?
3015 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3016 Args->push_back("-Xclang");
3017 Args->push_back("-detailed-preprocessing-record");
3018 }
3019
3020 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003021 std::unique_ptr<ASTUnit> ErrUnit;
3022 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00003023 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003024 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3025 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3026 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3027 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3028 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3029 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003030
3031 if (NumErrors != Diags->getClient()->getNumErrors()) {
3032 // Make sure to check that 'Unit' is non-NULL.
3033 if (CXXIdx->getDisplayDiagnostics())
3034 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3035 }
3036
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003037 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3038 PTUI->result = CXError_ASTReadError;
3039 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003040 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003041 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3042 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003043}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003044
3045CXTranslationUnit
3046clang_parseTranslationUnit(CXIndex CIdx,
3047 const char *source_filename,
3048 const char *const *command_line_args,
3049 int num_command_line_args,
3050 struct CXUnsavedFile *unsaved_files,
3051 unsigned num_unsaved_files,
3052 unsigned options) {
3053 CXTranslationUnit TU;
3054 enum CXErrorCode Result = clang_parseTranslationUnit2(
3055 CIdx, source_filename, command_line_args, num_command_line_args,
3056 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003057 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003058 assert((TU && Result == CXError_Success) ||
3059 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003060 return TU;
3061}
3062
3063enum CXErrorCode clang_parseTranslationUnit2(
3064 CXIndex CIdx,
3065 const char *source_filename,
3066 const char *const *command_line_args,
3067 int num_command_line_args,
3068 struct CXUnsavedFile *unsaved_files,
3069 unsigned num_unsaved_files,
3070 unsigned options,
3071 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003072 LOG_FUNC_SECTION {
3073 *Log << source_filename << ": ";
3074 for (int i = 0; i != num_command_line_args; ++i)
3075 *Log << command_line_args[i] << " ";
3076 }
3077
Alp Toker9d85b182014-07-07 01:23:14 +00003078 if (num_unsaved_files && !unsaved_files)
3079 return CXError_InvalidArguments;
3080
Alp Toker5c532982014-07-07 22:42:03 +00003081 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003082 ParseTranslationUnitInfo PTUI = {
3083 CIdx,
3084 source_filename,
3085 command_line_args,
3086 num_command_line_args,
3087 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3088 options,
3089 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003090 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003091 llvm::CrashRecoveryContext CRC;
3092
3093 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3094 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3095 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3096 fprintf(stderr, " 'command_line_args' : [");
3097 for (int i = 0; i != num_command_line_args; ++i) {
3098 if (i)
3099 fprintf(stderr, ", ");
3100 fprintf(stderr, "'%s'", command_line_args[i]);
3101 }
3102 fprintf(stderr, "],\n");
3103 fprintf(stderr, " 'unsaved_files' : [");
3104 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3105 if (i)
3106 fprintf(stderr, ", ");
3107 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3108 unsaved_files[i].Length);
3109 }
3110 fprintf(stderr, "],\n");
3111 fprintf(stderr, " 'options' : %d,\n", options);
3112 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003113
3114 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003115 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003116 if (CXTranslationUnit *TU = PTUI.out_TU)
3117 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003118 }
Alp Toker5c532982014-07-07 22:42:03 +00003119
3120 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003121}
3122
3123unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3124 return CXSaveTranslationUnit_None;
3125}
3126
3127namespace {
3128
3129struct SaveTranslationUnitInfo {
3130 CXTranslationUnit TU;
3131 const char *FileName;
3132 unsigned options;
3133 CXSaveError result;
3134};
3135
3136}
3137
3138static void clang_saveTranslationUnit_Impl(void *UserData) {
3139 SaveTranslationUnitInfo *STUI =
3140 static_cast<SaveTranslationUnitInfo*>(UserData);
3141
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003142 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003143 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3144 setThreadBackgroundPriority();
3145
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003146 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003147 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3148}
3149
3150int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3151 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003152 LOG_FUNC_SECTION {
3153 *Log << TU << ' ' << FileName;
3154 }
3155
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003156 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003157 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003159 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003160
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003161 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003162 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3163 if (!CXXUnit->hasSema())
3164 return CXSaveError_InvalidTU;
3165
3166 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3167
3168 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3169 getenv("LIBCLANG_NOTHREADS")) {
3170 clang_saveTranslationUnit_Impl(&STUI);
3171
3172 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3173 PrintLibclangResourceUsage(TU);
3174
3175 return STUI.result;
3176 }
3177
3178 // We have an AST that has invalid nodes due to compiler errors.
3179 // Use a crash recovery thread for protection.
3180
3181 llvm::CrashRecoveryContext CRC;
3182
3183 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3184 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3185 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3186 fprintf(stderr, " 'options' : %d,\n", options);
3187 fprintf(stderr, "}\n");
3188
3189 return CXSaveError_Unknown;
3190
3191 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3192 PrintLibclangResourceUsage(TU);
3193 }
3194
3195 return STUI.result;
3196}
3197
3198void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3199 if (CTUnit) {
3200 // If the translation unit has been marked as unsafe to free, just discard
3201 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003202 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3203 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 return;
3205
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003206 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003207 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3209 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003210 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 delete CTUnit;
3212 }
3213}
3214
3215unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3216 return CXReparse_None;
3217}
3218
3219struct ReparseTranslationUnitInfo {
3220 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003221 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003222 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003223 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003224};
3225
3226static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003227 const ReparseTranslationUnitInfo *RTUI =
3228 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003230 unsigned options = RTUI->options;
3231 (void) options;
3232
3233 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003234 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003235 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003236 RTUI->result = CXError_InvalidArguments;
3237 return;
3238 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003239
3240 // Reset the associated diagnostics.
3241 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003242 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003243
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003244 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003245 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3246 setThreadBackgroundPriority();
3247
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003248 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003249 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003250
3251 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3252 new std::vector<ASTUnit::RemappedFile>());
3253
Guy Benyei11169dd2012-12-18 14:30:41 +00003254 // Recover resources if we crash before exiting this function.
3255 llvm::CrashRecoveryContextCleanupRegistrar<
3256 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003257
3258 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003259 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003260 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003261 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003262 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003263
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003264 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003265 RTUI->result = CXError_Success;
3266 else if (isASTReadError(CXXUnit))
3267 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003268}
3269
3270int clang_reparseTranslationUnit(CXTranslationUnit TU,
3271 unsigned num_unsaved_files,
3272 struct CXUnsavedFile *unsaved_files,
3273 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003274 LOG_FUNC_SECTION {
3275 *Log << TU;
3276 }
3277
Alp Toker9d85b182014-07-07 01:23:14 +00003278 if (num_unsaved_files && !unsaved_files)
3279 return CXError_InvalidArguments;
3280
Alp Toker5c532982014-07-07 22:42:03 +00003281 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003282 ReparseTranslationUnitInfo RTUI = {
3283 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003284 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003285
3286 if (getenv("LIBCLANG_NOTHREADS")) {
3287 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003288 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 }
3290
3291 llvm::CrashRecoveryContext CRC;
3292
3293 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3294 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003295 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003296 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3298 PrintLibclangResourceUsage(TU);
3299
Alp Toker5c532982014-07-07 22:42:03 +00003300 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003301}
3302
3303
3304CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003305 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003306 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003307 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003308 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003309
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003310 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003311 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003312}
3313
3314CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003315 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003316 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003317 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003318 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003319
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003320 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3322}
3323
3324} // end: extern "C"
3325
3326//===----------------------------------------------------------------------===//
3327// CXFile Operations.
3328//===----------------------------------------------------------------------===//
3329
3330extern "C" {
3331CXString clang_getFileName(CXFile SFile) {
3332 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003333 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003334
3335 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003336 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003337}
3338
3339time_t clang_getFileTime(CXFile SFile) {
3340 if (!SFile)
3341 return 0;
3342
3343 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3344 return FEnt->getModificationTime();
3345}
3346
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003347CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003348 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003349 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003350 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003351 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003352
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003353 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003354
3355 FileManager &FMgr = CXXUnit->getFileManager();
3356 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3357}
3358
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003359unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3360 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003361 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003362 LOG_BAD_TU(TU);
3363 return 0;
3364 }
3365
3366 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 return 0;
3368
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003369 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 FileEntry *FEnt = static_cast<FileEntry *>(file);
3371 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3372 .isFileMultipleIncludeGuarded(FEnt);
3373}
3374
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003375int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3376 if (!file || !outID)
3377 return 1;
3378
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003379 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003380 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3381 outID->data[0] = ID.getDevice();
3382 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003383 outID->data[2] = FEnt->getModificationTime();
3384 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003385}
3386
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003387int clang_File_isEqual(CXFile file1, CXFile file2) {
3388 if (file1 == file2)
3389 return true;
3390
3391 if (!file1 || !file2)
3392 return false;
3393
3394 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3395 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3396 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3397}
3398
Guy Benyei11169dd2012-12-18 14:30:41 +00003399} // end: extern "C"
3400
3401//===----------------------------------------------------------------------===//
3402// CXCursor Operations.
3403//===----------------------------------------------------------------------===//
3404
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003405static const Decl *getDeclFromExpr(const Stmt *E) {
3406 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 return getDeclFromExpr(CE->getSubExpr());
3408
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003409 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003410 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003411 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003413 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003414 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003415 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 if (PRE->isExplicitProperty())
3417 return PRE->getExplicitProperty();
3418 // It could be messaging both getter and setter as in:
3419 // ++myobj.myprop;
3420 // in which case prefer to associate the setter since it is less obvious
3421 // from inspecting the source that the setter is going to get called.
3422 if (PRE->isMessagingSetter())
3423 return PRE->getImplicitPropertySetter();
3424 return PRE->getImplicitPropertyGetter();
3425 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003426 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003428 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 if (Expr *Src = OVE->getSourceExpr())
3430 return getDeclFromExpr(Src);
3431
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003432 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003433 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003434 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 if (!CE->isElidable())
3436 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003437 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 return OME->getMethodDecl();
3439
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003440 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003442 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3444 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003445 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3447 isa<ParmVarDecl>(SizeOfPack->getPack()))
3448 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003449
3450 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003451}
3452
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003453static SourceLocation getLocationFromExpr(const Expr *E) {
3454 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 return getLocationFromExpr(CE->getSubExpr());
3456
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003457 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003459 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003461 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003463 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003465 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003467 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 return PropRef->getLocation();
3469
3470 return E->getLocStart();
3471}
3472
3473extern "C" {
3474
3475unsigned clang_visitChildren(CXCursor parent,
3476 CXCursorVisitor visitor,
3477 CXClientData client_data) {
3478 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3479 /*VisitPreprocessorLast=*/false);
3480 return CursorVis.VisitChildren(parent);
3481}
3482
3483#ifndef __has_feature
3484#define __has_feature(x) 0
3485#endif
3486#if __has_feature(blocks)
3487typedef enum CXChildVisitResult
3488 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3489
3490static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3491 CXClientData client_data) {
3492 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3493 return block(cursor, parent);
3494}
3495#else
3496// If we are compiled with a compiler that doesn't have native blocks support,
3497// define and call the block manually, so the
3498typedef struct _CXChildVisitResult
3499{
3500 void *isa;
3501 int flags;
3502 int reserved;
3503 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3504 CXCursor);
3505} *CXCursorVisitorBlock;
3506
3507static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3508 CXClientData client_data) {
3509 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3510 return block->invoke(block, cursor, parent);
3511}
3512#endif
3513
3514
3515unsigned clang_visitChildrenWithBlock(CXCursor parent,
3516 CXCursorVisitorBlock block) {
3517 return clang_visitChildren(parent, visitWithBlock, block);
3518}
3519
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003520static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003522 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003523
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003524 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003526 if (const ObjCPropertyImplDecl *PropImpl =
3527 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003529 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003530
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003533 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003534
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003535 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 }
3537
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003538 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003539 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003540
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003541 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3543 // and returns different names. NamedDecl returns the class name and
3544 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003545 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003546
3547 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003548 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003549
3550 SmallString<1024> S;
3551 llvm::raw_svector_ostream os(S);
3552 ND->printName(os);
3553
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003554 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003555}
3556
3557CXString clang_getCursorSpelling(CXCursor C) {
3558 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003559 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003560
3561 if (clang_isReference(C.kind)) {
3562 switch (C.kind) {
3563 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003564 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003565 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 }
3567 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003568 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003569 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 }
3571 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003572 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003574 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 }
3576 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003577 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003578 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 }
3580 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003581 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 assert(Type && "Missing type decl");
3583
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003584 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 getAsString());
3586 }
3587 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003588 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 assert(Template && "Missing template decl");
3590
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003591 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 }
3593
3594 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003595 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 assert(NS && "Missing namespace decl");
3597
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003598 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 }
3600
3601 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003602 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 assert(Field && "Missing member decl");
3604
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003605 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 }
3607
3608 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003609 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 assert(Label && "Missing label");
3611
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003612 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 }
3614
3615 case CXCursor_OverloadedDeclRef: {
3616 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003617 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3618 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003619 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003620 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003622 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003623 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 OverloadedTemplateStorage *Ovl
3625 = Storage.get<OverloadedTemplateStorage*>();
3626 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003627 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003628 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 }
3630
3631 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003632 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 assert(Var && "Missing variable decl");
3634
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003635 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 }
3637
3638 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 }
3641 }
3642
3643 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003644 const Expr *E = getCursorExpr(C);
3645
3646 if (C.kind == CXCursor_ObjCStringLiteral ||
3647 C.kind == CXCursor_StringLiteral) {
3648 const StringLiteral *SLit;
3649 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3650 SLit = OSL->getString();
3651 } else {
3652 SLit = cast<StringLiteral>(E);
3653 }
3654 SmallString<256> Buf;
3655 llvm::raw_svector_ostream OS(Buf);
3656 SLit->outputString(OS);
3657 return cxstring::createDup(OS.str());
3658 }
3659
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003660 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 if (D)
3662 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003663 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 }
3665
3666 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003667 const Stmt *S = getCursorStmt(C);
3668 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003670
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003671 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 }
3673
3674 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 ->getNameStart());
3677
3678 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 ->getNameStart());
3681
3682 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003683 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003684
3685 if (clang_isDeclaration(C.kind))
3686 return getDeclSpelling(getCursorDecl(C));
3687
3688 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003689 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003690 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 }
3692
3693 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003694 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003695 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 }
3697
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003698 if (C.kind == CXCursor_PackedAttr) {
3699 return cxstring::createRef("packed");
3700 }
3701
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003702 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003703}
3704
3705CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3706 unsigned pieceIndex,
3707 unsigned options) {
3708 if (clang_Cursor_isNull(C))
3709 return clang_getNullRange();
3710
3711 ASTContext &Ctx = getCursorContext(C);
3712
3713 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003714 const Stmt *S = getCursorStmt(C);
3715 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 if (pieceIndex > 0)
3717 return clang_getNullRange();
3718 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3719 }
3720
3721 return clang_getNullRange();
3722 }
3723
3724 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003725 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3727 if (pieceIndex >= ME->getNumSelectorLocs())
3728 return clang_getNullRange();
3729 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3730 }
3731 }
3732
3733 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3734 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003735 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3737 if (pieceIndex >= MD->getNumSelectorLocs())
3738 return clang_getNullRange();
3739 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3740 }
3741 }
3742
3743 if (C.kind == CXCursor_ObjCCategoryDecl ||
3744 C.kind == CXCursor_ObjCCategoryImplDecl) {
3745 if (pieceIndex > 0)
3746 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003747 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3749 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003750 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3752 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3753 }
3754
3755 if (C.kind == CXCursor_ModuleImportDecl) {
3756 if (pieceIndex > 0)
3757 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003758 if (const ImportDecl *ImportD =
3759 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3761 if (!Locs.empty())
3762 return cxloc::translateSourceRange(Ctx,
3763 SourceRange(Locs.front(), Locs.back()));
3764 }
3765 return clang_getNullRange();
3766 }
3767
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003768 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3769 C.kind == CXCursor_ConversionFunction) {
3770 if (pieceIndex > 0)
3771 return clang_getNullRange();
3772 if (const FunctionDecl *FD =
3773 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3774 DeclarationNameInfo FunctionName = FD->getNameInfo();
3775 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3776 }
3777 return clang_getNullRange();
3778 }
3779
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 // FIXME: A CXCursor_InclusionDirective should give the location of the
3781 // filename, but we don't keep track of this.
3782
3783 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3784 // but we don't keep track of this.
3785
3786 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3787 // but we don't keep track of this.
3788
3789 // Default handling, give the location of the cursor.
3790
3791 if (pieceIndex > 0)
3792 return clang_getNullRange();
3793
3794 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3795 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3796 return cxloc::translateSourceRange(Ctx, Loc);
3797}
3798
Eli Bendersky44a206f2014-07-31 18:04:56 +00003799CXString clang_Cursor_getMangling(CXCursor C) {
3800 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3801 return cxstring::createEmpty();
3802
Eli Bendersky44a206f2014-07-31 18:04:56 +00003803 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003804 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003805 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3806 return cxstring::createEmpty();
3807
Eli Bendersky79759592014-08-01 15:01:10 +00003808 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003809 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003810 ASTContext &Ctx = ND->getASTContext();
3811 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003812
Eli Bendersky79759592014-08-01 15:01:10 +00003813 std::string FrontendBuf;
3814 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3815 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003816
Eli Bendersky79759592014-08-01 15:01:10 +00003817 // Now apply backend mangling.
3818 std::unique_ptr<llvm::DataLayout> DL(
3819 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3820 llvm::Mangler BackendMangler(DL.get());
3821
3822 std::string FinalBuf;
3823 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3824 BackendMangler.getNameWithPrefix(FinalBufOS,
3825 llvm::Twine(FrontendBufOS.str()));
3826
3827 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003828}
3829
Guy Benyei11169dd2012-12-18 14:30:41 +00003830CXString clang_getCursorDisplayName(CXCursor C) {
3831 if (!clang_isDeclaration(C.kind))
3832 return clang_getCursorSpelling(C);
3833
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003834 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003836 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003837
3838 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003839 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 D = FunTmpl->getTemplatedDecl();
3841
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003842 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 SmallString<64> Str;
3844 llvm::raw_svector_ostream OS(Str);
3845 OS << *Function;
3846 if (Function->getPrimaryTemplate())
3847 OS << "<>";
3848 OS << "(";
3849 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3850 if (I)
3851 OS << ", ";
3852 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3853 }
3854
3855 if (Function->isVariadic()) {
3856 if (Function->getNumParams())
3857 OS << ", ";
3858 OS << "...";
3859 }
3860 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003861 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 }
3863
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003864 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 SmallString<64> Str;
3866 llvm::raw_svector_ostream OS(Str);
3867 OS << *ClassTemplate;
3868 OS << "<";
3869 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3870 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3871 if (I)
3872 OS << ", ";
3873
3874 NamedDecl *Param = Params->getParam(I);
3875 if (Param->getIdentifier()) {
3876 OS << Param->getIdentifier()->getName();
3877 continue;
3878 }
3879
3880 // There is no parameter name, which makes this tricky. Try to come up
3881 // with something useful that isn't too long.
3882 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3883 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3884 else if (NonTypeTemplateParmDecl *NTTP
3885 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3886 OS << NTTP->getType().getAsString(Policy);
3887 else
3888 OS << "template<...> class";
3889 }
3890
3891 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003892 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 }
3894
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003895 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3897 // If the type was explicitly written, use that.
3898 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003899 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003900
Benjamin Kramer9170e912013-02-22 15:46:01 +00003901 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 llvm::raw_svector_ostream OS(Str);
3903 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003904 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 ClassSpec->getTemplateArgs().data(),
3906 ClassSpec->getTemplateArgs().size(),
3907 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003908 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 }
3910
3911 return clang_getCursorSpelling(C);
3912}
3913
3914CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3915 switch (Kind) {
3916 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004044 case CXCursor_ObjCSelfExpr:
4045 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004134 case CXCursor_SEHLeaveStmt:
4135 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004164 case CXCursor_PackedAttr:
4165 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004166 case CXCursor_PureAttr:
4167 return cxstring::createRef("attribute(pure)");
4168 case CXCursor_ConstAttr:
4169 return cxstring::createRef("attribute(const)");
4170 case CXCursor_NoDuplicateAttr:
4171 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004172 case CXCursor_CUDAConstantAttr:
4173 return cxstring::createRef("attribute(constant)");
4174 case CXCursor_CUDADeviceAttr:
4175 return cxstring::createRef("attribute(device)");
4176 case CXCursor_CUDAGlobalAttr:
4177 return cxstring::createRef("attribute(global)");
4178 case CXCursor_CUDAHostAttr:
4179 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004180 case CXCursor_CUDASharedAttr:
4181 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004203 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004207 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004209 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004211 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004213 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004215 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004217 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004219 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004221 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004223 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004225 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004227 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004229 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004230 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004231 return cxstring::createRef("OMPParallelDirective");
4232 case CXCursor_OMPSimdDirective:
4233 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004234 case CXCursor_OMPForDirective:
4235 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004236 case CXCursor_OMPForSimdDirective:
4237 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004238 case CXCursor_OMPSectionsDirective:
4239 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004240 case CXCursor_OMPSectionDirective:
4241 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004242 case CXCursor_OMPSingleDirective:
4243 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004244 case CXCursor_OMPMasterDirective:
4245 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004246 case CXCursor_OMPCriticalDirective:
4247 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004248 case CXCursor_OMPParallelForDirective:
4249 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004250 case CXCursor_OMPParallelForSimdDirective:
4251 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004252 case CXCursor_OMPParallelSectionsDirective:
4253 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004254 case CXCursor_OMPTaskDirective:
4255 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004256 case CXCursor_OMPTaskyieldDirective:
4257 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004258 case CXCursor_OMPBarrierDirective:
4259 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004260 case CXCursor_OMPTaskwaitDirective:
4261 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004262 case CXCursor_OMPFlushDirective:
4263 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004264 case CXCursor_OMPOrderedDirective:
4265 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004266 case CXCursor_OMPAtomicDirective:
4267 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004268 case CXCursor_OMPTargetDirective:
4269 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004270 case CXCursor_OMPTeamsDirective:
4271 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004272 case CXCursor_OverloadCandidate:
4273 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 }
4275
4276 llvm_unreachable("Unhandled CXCursorKind");
4277}
4278
4279struct GetCursorData {
4280 SourceLocation TokenBeginLoc;
4281 bool PointsAtMacroArgExpansion;
4282 bool VisitedObjCPropertyImplDecl;
4283 SourceLocation VisitedDeclaratorDeclStartLoc;
4284 CXCursor &BestCursor;
4285
4286 GetCursorData(SourceManager &SM,
4287 SourceLocation tokenBegin, CXCursor &outputCursor)
4288 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4289 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4290 VisitedObjCPropertyImplDecl = false;
4291 }
4292};
4293
4294static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4295 CXCursor parent,
4296 CXClientData client_data) {
4297 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4298 CXCursor *BestCursor = &Data->BestCursor;
4299
4300 // If we point inside a macro argument we should provide info of what the
4301 // token is so use the actual cursor, don't replace it with a macro expansion
4302 // cursor.
4303 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4304 return CXChildVisit_Recurse;
4305
4306 if (clang_isDeclaration(cursor.kind)) {
4307 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004308 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4310 if (MD->isImplicit())
4311 return CXChildVisit_Break;
4312
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004313 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004314 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4315 // Check that when we have multiple @class references in the same line,
4316 // that later ones do not override the previous ones.
4317 // If we have:
4318 // @class Foo, Bar;
4319 // source ranges for both start at '@', so 'Bar' will end up overriding
4320 // 'Foo' even though the cursor location was at 'Foo'.
4321 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4322 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004323 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4325 if (PrevID != ID &&
4326 !PrevID->isThisDeclarationADefinition() &&
4327 !ID->isThisDeclarationADefinition())
4328 return CXChildVisit_Break;
4329 }
4330
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004331 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4333 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4334 // Check that when we have multiple declarators in the same line,
4335 // that later ones do not override the previous ones.
4336 // If we have:
4337 // int Foo, Bar;
4338 // source ranges for both start at 'int', so 'Bar' will end up overriding
4339 // 'Foo' even though the cursor location was at 'Foo'.
4340 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4341 return CXChildVisit_Break;
4342 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4343
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004344 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004345 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4346 (void)PropImp;
4347 // Check that when we have multiple @synthesize in the same line,
4348 // that later ones do not override the previous ones.
4349 // If we have:
4350 // @synthesize Foo, Bar;
4351 // source ranges for both start at '@', so 'Bar' will end up overriding
4352 // 'Foo' even though the cursor location was at 'Foo'.
4353 if (Data->VisitedObjCPropertyImplDecl)
4354 return CXChildVisit_Break;
4355 Data->VisitedObjCPropertyImplDecl = true;
4356 }
4357 }
4358
4359 if (clang_isExpression(cursor.kind) &&
4360 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004361 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 // Avoid having the cursor of an expression replace the declaration cursor
4363 // when the expression source range overlaps the declaration range.
4364 // This can happen for C++ constructor expressions whose range generally
4365 // include the variable declaration, e.g.:
4366 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4367 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4368 D->getLocation() == Data->TokenBeginLoc)
4369 return CXChildVisit_Break;
4370 }
4371 }
4372
4373 // If our current best cursor is the construction of a temporary object,
4374 // don't replace that cursor with a type reference, because we want
4375 // clang_getCursor() to point at the constructor.
4376 if (clang_isExpression(BestCursor->kind) &&
4377 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4378 cursor.kind == CXCursor_TypeRef) {
4379 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4380 // as having the actual point on the type reference.
4381 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4382 return CXChildVisit_Recurse;
4383 }
4384
4385 *BestCursor = cursor;
4386 return CXChildVisit_Recurse;
4387}
4388
4389CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004390 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004391 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004392 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004393 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004394
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004395 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004396 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4397
4398 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4399 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4400
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004401 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 CXFile SearchFile;
4403 unsigned SearchLine, SearchColumn;
4404 CXFile ResultFile;
4405 unsigned ResultLine, ResultColumn;
4406 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4407 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4408 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004409
4410 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4411 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004412 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004413 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 SearchFileName = clang_getFileName(SearchFile);
4415 ResultFileName = clang_getFileName(ResultFile);
4416 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4417 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004418 *Log << llvm::format("(%s:%d:%d) = %s",
4419 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4420 clang_getCString(KindSpelling))
4421 << llvm::format("(%s:%d:%d):%s%s",
4422 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4423 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 clang_disposeString(SearchFileName);
4425 clang_disposeString(ResultFileName);
4426 clang_disposeString(KindSpelling);
4427 clang_disposeString(USR);
4428
4429 CXCursor Definition = clang_getCursorDefinition(Result);
4430 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4431 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4432 CXString DefinitionKindSpelling
4433 = clang_getCursorKindSpelling(Definition.kind);
4434 CXFile DefinitionFile;
4435 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004436 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004437 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004439 *Log << llvm::format(" -> %s(%s:%d:%d)",
4440 clang_getCString(DefinitionKindSpelling),
4441 clang_getCString(DefinitionFileName),
4442 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 clang_disposeString(DefinitionFileName);
4444 clang_disposeString(DefinitionKindSpelling);
4445 }
4446 }
4447
4448 return Result;
4449}
4450
4451CXCursor clang_getNullCursor(void) {
4452 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4453}
4454
4455unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004456 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4457 // can't set consistently. For example, when visiting a DeclStmt we will set
4458 // it but we don't set it on the result of clang_getCursorDefinition for
4459 // a reference of the same declaration.
4460 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4461 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4462 // to provide that kind of info.
4463 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004464 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004465 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004466 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004467
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 return X == Y;
4469}
4470
4471unsigned clang_hashCursor(CXCursor C) {
4472 unsigned Index = 0;
4473 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4474 Index = 1;
4475
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004476 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 std::make_pair(C.kind, C.data[Index]));
4478}
4479
4480unsigned clang_isInvalid(enum CXCursorKind K) {
4481 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4482}
4483
4484unsigned clang_isDeclaration(enum CXCursorKind K) {
4485 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4486 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4487}
4488
4489unsigned clang_isReference(enum CXCursorKind K) {
4490 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4491}
4492
4493unsigned clang_isExpression(enum CXCursorKind K) {
4494 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4495}
4496
4497unsigned clang_isStatement(enum CXCursorKind K) {
4498 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4499}
4500
4501unsigned clang_isAttribute(enum CXCursorKind K) {
4502 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4503}
4504
4505unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4506 return K == CXCursor_TranslationUnit;
4507}
4508
4509unsigned clang_isPreprocessing(enum CXCursorKind K) {
4510 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4511}
4512
4513unsigned clang_isUnexposed(enum CXCursorKind K) {
4514 switch (K) {
4515 case CXCursor_UnexposedDecl:
4516 case CXCursor_UnexposedExpr:
4517 case CXCursor_UnexposedStmt:
4518 case CXCursor_UnexposedAttr:
4519 return true;
4520 default:
4521 return false;
4522 }
4523}
4524
4525CXCursorKind clang_getCursorKind(CXCursor C) {
4526 return C.kind;
4527}
4528
4529CXSourceLocation clang_getCursorLocation(CXCursor C) {
4530 if (clang_isReference(C.kind)) {
4531 switch (C.kind) {
4532 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004533 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 = getCursorObjCSuperClassRef(C);
4535 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4536 }
4537
4538 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004539 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004540 = getCursorObjCProtocolRef(C);
4541 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4542 }
4543
4544 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004545 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 = getCursorObjCClassRef(C);
4547 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4548 }
4549
4550 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004551 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4553 }
4554
4555 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004556 std::pair<const TemplateDecl *, SourceLocation> P =
4557 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4559 }
4560
4561 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004562 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4564 }
4565
4566 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004567 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4569 }
4570
4571 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004572 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4574 }
4575
4576 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004577 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 if (!BaseSpec)
4579 return clang_getNullLocation();
4580
4581 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4582 return cxloc::translateSourceLocation(getCursorContext(C),
4583 TSInfo->getTypeLoc().getBeginLoc());
4584
4585 return cxloc::translateSourceLocation(getCursorContext(C),
4586 BaseSpec->getLocStart());
4587 }
4588
4589 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004590 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4592 }
4593
4594 case CXCursor_OverloadedDeclRef:
4595 return cxloc::translateSourceLocation(getCursorContext(C),
4596 getCursorOverloadedDeclRef(C).second);
4597
4598 default:
4599 // FIXME: Need a way to enumerate all non-reference cases.
4600 llvm_unreachable("Missed a reference kind");
4601 }
4602 }
4603
4604 if (clang_isExpression(C.kind))
4605 return cxloc::translateSourceLocation(getCursorContext(C),
4606 getLocationFromExpr(getCursorExpr(C)));
4607
4608 if (clang_isStatement(C.kind))
4609 return cxloc::translateSourceLocation(getCursorContext(C),
4610 getCursorStmt(C)->getLocStart());
4611
4612 if (C.kind == CXCursor_PreprocessingDirective) {
4613 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4614 return cxloc::translateSourceLocation(getCursorContext(C), L);
4615 }
4616
4617 if (C.kind == CXCursor_MacroExpansion) {
4618 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004619 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 return cxloc::translateSourceLocation(getCursorContext(C), L);
4621 }
4622
4623 if (C.kind == CXCursor_MacroDefinition) {
4624 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4625 return cxloc::translateSourceLocation(getCursorContext(C), L);
4626 }
4627
4628 if (C.kind == CXCursor_InclusionDirective) {
4629 SourceLocation L
4630 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4631 return cxloc::translateSourceLocation(getCursorContext(C), L);
4632 }
4633
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004634 if (clang_isAttribute(C.kind)) {
4635 SourceLocation L
4636 = cxcursor::getCursorAttr(C)->getLocation();
4637 return cxloc::translateSourceLocation(getCursorContext(C), L);
4638 }
4639
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 if (!clang_isDeclaration(C.kind))
4641 return clang_getNullLocation();
4642
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004643 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 if (!D)
4645 return clang_getNullLocation();
4646
4647 SourceLocation Loc = D->getLocation();
4648 // FIXME: Multiple variables declared in a single declaration
4649 // currently lack the information needed to correctly determine their
4650 // ranges when accounting for the type-specifier. We use context
4651 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4652 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004653 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 if (!cxcursor::isFirstInDeclGroup(C))
4655 Loc = VD->getLocation();
4656 }
4657
4658 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004659 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004660 Loc = MD->getSelectorStartLoc();
4661
4662 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4663}
4664
4665} // end extern "C"
4666
4667CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4668 assert(TU);
4669
4670 // Guard against an invalid SourceLocation, or we may assert in one
4671 // of the following calls.
4672 if (SLoc.isInvalid())
4673 return clang_getNullCursor();
4674
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004675 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004676
4677 // Translate the given source location to make it point at the beginning of
4678 // the token under the cursor.
4679 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4680 CXXUnit->getASTContext().getLangOpts());
4681
4682 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4683 if (SLoc.isValid()) {
4684 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4685 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4686 /*VisitPreprocessorLast=*/true,
4687 /*VisitIncludedEntities=*/false,
4688 SourceLocation(SLoc));
4689 CursorVis.visitFileRegion();
4690 }
4691
4692 return Result;
4693}
4694
4695static SourceRange getRawCursorExtent(CXCursor C) {
4696 if (clang_isReference(C.kind)) {
4697 switch (C.kind) {
4698 case CXCursor_ObjCSuperClassRef:
4699 return getCursorObjCSuperClassRef(C).second;
4700
4701 case CXCursor_ObjCProtocolRef:
4702 return getCursorObjCProtocolRef(C).second;
4703
4704 case CXCursor_ObjCClassRef:
4705 return getCursorObjCClassRef(C).second;
4706
4707 case CXCursor_TypeRef:
4708 return getCursorTypeRef(C).second;
4709
4710 case CXCursor_TemplateRef:
4711 return getCursorTemplateRef(C).second;
4712
4713 case CXCursor_NamespaceRef:
4714 return getCursorNamespaceRef(C).second;
4715
4716 case CXCursor_MemberRef:
4717 return getCursorMemberRef(C).second;
4718
4719 case CXCursor_CXXBaseSpecifier:
4720 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4721
4722 case CXCursor_LabelRef:
4723 return getCursorLabelRef(C).second;
4724
4725 case CXCursor_OverloadedDeclRef:
4726 return getCursorOverloadedDeclRef(C).second;
4727
4728 case CXCursor_VariableRef:
4729 return getCursorVariableRef(C).second;
4730
4731 default:
4732 // FIXME: Need a way to enumerate all non-reference cases.
4733 llvm_unreachable("Missed a reference kind");
4734 }
4735 }
4736
4737 if (clang_isExpression(C.kind))
4738 return getCursorExpr(C)->getSourceRange();
4739
4740 if (clang_isStatement(C.kind))
4741 return getCursorStmt(C)->getSourceRange();
4742
4743 if (clang_isAttribute(C.kind))
4744 return getCursorAttr(C)->getRange();
4745
4746 if (C.kind == CXCursor_PreprocessingDirective)
4747 return cxcursor::getCursorPreprocessingDirective(C);
4748
4749 if (C.kind == CXCursor_MacroExpansion) {
4750 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004751 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004752 return TU->mapRangeFromPreamble(Range);
4753 }
4754
4755 if (C.kind == CXCursor_MacroDefinition) {
4756 ASTUnit *TU = getCursorASTUnit(C);
4757 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4758 return TU->mapRangeFromPreamble(Range);
4759 }
4760
4761 if (C.kind == CXCursor_InclusionDirective) {
4762 ASTUnit *TU = getCursorASTUnit(C);
4763 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4764 return TU->mapRangeFromPreamble(Range);
4765 }
4766
4767 if (C.kind == CXCursor_TranslationUnit) {
4768 ASTUnit *TU = getCursorASTUnit(C);
4769 FileID MainID = TU->getSourceManager().getMainFileID();
4770 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4771 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4772 return SourceRange(Start, End);
4773 }
4774
4775 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004776 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 if (!D)
4778 return SourceRange();
4779
4780 SourceRange R = D->getSourceRange();
4781 // FIXME: Multiple variables declared in a single declaration
4782 // currently lack the information needed to correctly determine their
4783 // ranges when accounting for the type-specifier. We use context
4784 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4785 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004786 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 if (!cxcursor::isFirstInDeclGroup(C))
4788 R.setBegin(VD->getLocation());
4789 }
4790 return R;
4791 }
4792 return SourceRange();
4793}
4794
4795/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4796/// the decl-specifier-seq for declarations.
4797static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4798 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004799 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004800 if (!D)
4801 return SourceRange();
4802
4803 SourceRange R = D->getSourceRange();
4804
4805 // Adjust the start of the location for declarations preceded by
4806 // declaration specifiers.
4807 SourceLocation StartLoc;
4808 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4809 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4810 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004811 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004812 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4813 StartLoc = TI->getTypeLoc().getLocStart();
4814 }
4815
4816 if (StartLoc.isValid() && R.getBegin().isValid() &&
4817 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4818 R.setBegin(StartLoc);
4819
4820 // FIXME: Multiple variables declared in a single declaration
4821 // currently lack the information needed to correctly determine their
4822 // ranges when accounting for the type-specifier. We use context
4823 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4824 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004825 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004826 if (!cxcursor::isFirstInDeclGroup(C))
4827 R.setBegin(VD->getLocation());
4828 }
4829
4830 return R;
4831 }
4832
4833 return getRawCursorExtent(C);
4834}
4835
4836extern "C" {
4837
4838CXSourceRange clang_getCursorExtent(CXCursor C) {
4839 SourceRange R = getRawCursorExtent(C);
4840 if (R.isInvalid())
4841 return clang_getNullRange();
4842
4843 return cxloc::translateSourceRange(getCursorContext(C), R);
4844}
4845
4846CXCursor clang_getCursorReferenced(CXCursor C) {
4847 if (clang_isInvalid(C.kind))
4848 return clang_getNullCursor();
4849
4850 CXTranslationUnit tu = getCursorTU(C);
4851 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004852 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 if (!D)
4854 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004855 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004856 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004857 if (const ObjCPropertyImplDecl *PropImpl =
4858 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4860 return MakeCXCursor(Property, tu);
4861
4862 return C;
4863 }
4864
4865 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004866 const Expr *E = getCursorExpr(C);
4867 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004868 if (D) {
4869 CXCursor declCursor = MakeCXCursor(D, tu);
4870 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4871 declCursor);
4872 return declCursor;
4873 }
4874
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 return MakeCursorOverloadedDeclRef(Ovl, tu);
4877
4878 return clang_getNullCursor();
4879 }
4880
4881 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004882 const Stmt *S = getCursorStmt(C);
4883 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 if (LabelDecl *label = Goto->getLabel())
4885 if (LabelStmt *labelS = label->getStmt())
4886 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4887
4888 return clang_getNullCursor();
4889 }
Richard Smith66a81862015-05-04 02:25:31 +00004890
Guy Benyei11169dd2012-12-18 14:30:41 +00004891 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004892 if (const MacroDefinitionRecord *Def =
4893 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 return MakeMacroDefinitionCursor(Def, tu);
4895 }
4896
4897 if (!clang_isReference(C.kind))
4898 return clang_getNullCursor();
4899
4900 switch (C.kind) {
4901 case CXCursor_ObjCSuperClassRef:
4902 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4903
4904 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004905 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4906 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004907 return MakeCXCursor(Def, tu);
4908
4909 return MakeCXCursor(Prot, tu);
4910 }
4911
4912 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004913 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4914 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 return MakeCXCursor(Def, tu);
4916
4917 return MakeCXCursor(Class, tu);
4918 }
4919
4920 case CXCursor_TypeRef:
4921 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4922
4923 case CXCursor_TemplateRef:
4924 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4925
4926 case CXCursor_NamespaceRef:
4927 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4928
4929 case CXCursor_MemberRef:
4930 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4931
4932 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004933 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004934 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4935 tu ));
4936 }
4937
4938 case CXCursor_LabelRef:
4939 // FIXME: We end up faking the "parent" declaration here because we
4940 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004941 return MakeCXCursor(getCursorLabelRef(C).first,
4942 cxtu::getASTUnit(tu)->getASTContext()
4943 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004944 tu);
4945
4946 case CXCursor_OverloadedDeclRef:
4947 return C;
4948
4949 case CXCursor_VariableRef:
4950 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4951
4952 default:
4953 // We would prefer to enumerate all non-reference cursor kinds here.
4954 llvm_unreachable("Unhandled reference cursor kind");
4955 }
4956}
4957
4958CXCursor clang_getCursorDefinition(CXCursor C) {
4959 if (clang_isInvalid(C.kind))
4960 return clang_getNullCursor();
4961
4962 CXTranslationUnit TU = getCursorTU(C);
4963
4964 bool WasReference = false;
4965 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4966 C = clang_getCursorReferenced(C);
4967 WasReference = true;
4968 }
4969
4970 if (C.kind == CXCursor_MacroExpansion)
4971 return clang_getCursorReferenced(C);
4972
4973 if (!clang_isDeclaration(C.kind))
4974 return clang_getNullCursor();
4975
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004976 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004977 if (!D)
4978 return clang_getNullCursor();
4979
4980 switch (D->getKind()) {
4981 // Declaration kinds that don't really separate the notions of
4982 // declaration and definition.
4983 case Decl::Namespace:
4984 case Decl::Typedef:
4985 case Decl::TypeAlias:
4986 case Decl::TypeAliasTemplate:
4987 case Decl::TemplateTypeParm:
4988 case Decl::EnumConstant:
4989 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004990 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 case Decl::IndirectField:
4992 case Decl::ObjCIvar:
4993 case Decl::ObjCAtDefsField:
4994 case Decl::ImplicitParam:
4995 case Decl::ParmVar:
4996 case Decl::NonTypeTemplateParm:
4997 case Decl::TemplateTemplateParm:
4998 case Decl::ObjCCategoryImpl:
4999 case Decl::ObjCImplementation:
5000 case Decl::AccessSpec:
5001 case Decl::LinkageSpec:
5002 case Decl::ObjCPropertyImpl:
5003 case Decl::FileScopeAsm:
5004 case Decl::StaticAssert:
5005 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005006 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 case Decl::Label: // FIXME: Is this right??
5008 case Decl::ClassScopeFunctionSpecialization:
5009 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005010 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005011 return C;
5012
5013 // Declaration kinds that don't make any sense here, but are
5014 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005015 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005016 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005017 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 break;
5019
5020 // Declaration kinds for which the definition is not resolvable.
5021 case Decl::UnresolvedUsingTypename:
5022 case Decl::UnresolvedUsingValue:
5023 break;
5024
5025 case Decl::UsingDirective:
5026 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5027 TU);
5028
5029 case Decl::NamespaceAlias:
5030 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5031
5032 case Decl::Enum:
5033 case Decl::Record:
5034 case Decl::CXXRecord:
5035 case Decl::ClassTemplateSpecialization:
5036 case Decl::ClassTemplatePartialSpecialization:
5037 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5038 return MakeCXCursor(Def, TU);
5039 return clang_getNullCursor();
5040
5041 case Decl::Function:
5042 case Decl::CXXMethod:
5043 case Decl::CXXConstructor:
5044 case Decl::CXXDestructor:
5045 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005046 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005048 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 return clang_getNullCursor();
5050 }
5051
Larisse Voufo39a1e502013-08-06 01:03:05 +00005052 case Decl::Var:
5053 case Decl::VarTemplateSpecialization:
5054 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005055 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005056 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005057 return MakeCXCursor(Def, TU);
5058 return clang_getNullCursor();
5059 }
5060
5061 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005062 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005063 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5064 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5065 return clang_getNullCursor();
5066 }
5067
5068 case Decl::ClassTemplate: {
5069 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5070 ->getDefinition())
5071 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5072 TU);
5073 return clang_getNullCursor();
5074 }
5075
Larisse Voufo39a1e502013-08-06 01:03:05 +00005076 case Decl::VarTemplate: {
5077 if (VarDecl *Def =
5078 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5079 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5080 return clang_getNullCursor();
5081 }
5082
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 case Decl::Using:
5084 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5085 D->getLocation(), TU);
5086
5087 case Decl::UsingShadow:
5088 return clang_getCursorDefinition(
5089 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5090 TU));
5091
5092 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005093 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 if (Method->isThisDeclarationADefinition())
5095 return C;
5096
5097 // Dig out the method definition in the associated
5098 // @implementation, if we have it.
5099 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005100 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005101 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5102 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5103 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5104 Method->isInstanceMethod()))
5105 if (Def->isThisDeclarationADefinition())
5106 return MakeCXCursor(Def, TU);
5107
5108 return clang_getNullCursor();
5109 }
5110
5111 case Decl::ObjCCategory:
5112 if (ObjCCategoryImplDecl *Impl
5113 = cast<ObjCCategoryDecl>(D)->getImplementation())
5114 return MakeCXCursor(Impl, TU);
5115 return clang_getNullCursor();
5116
5117 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005118 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 return MakeCXCursor(Def, TU);
5120 return clang_getNullCursor();
5121
5122 case Decl::ObjCInterface: {
5123 // There are two notions of a "definition" for an Objective-C
5124 // class: the interface and its implementation. When we resolved a
5125 // reference to an Objective-C class, produce the @interface as
5126 // the definition; when we were provided with the interface,
5127 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005128 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005129 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005130 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 return MakeCXCursor(Def, TU);
5132 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5133 return MakeCXCursor(Impl, TU);
5134 return clang_getNullCursor();
5135 }
5136
5137 case Decl::ObjCProperty:
5138 // FIXME: We don't really know where to find the
5139 // ObjCPropertyImplDecls that implement this property.
5140 return clang_getNullCursor();
5141
5142 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005143 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005145 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 return MakeCXCursor(Def, TU);
5147
5148 return clang_getNullCursor();
5149
5150 case Decl::Friend:
5151 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5152 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5153 return clang_getNullCursor();
5154
5155 case Decl::FriendTemplate:
5156 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5157 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5158 return clang_getNullCursor();
5159 }
5160
5161 return clang_getNullCursor();
5162}
5163
5164unsigned clang_isCursorDefinition(CXCursor C) {
5165 if (!clang_isDeclaration(C.kind))
5166 return 0;
5167
5168 return clang_getCursorDefinition(C) == C;
5169}
5170
5171CXCursor clang_getCanonicalCursor(CXCursor C) {
5172 if (!clang_isDeclaration(C.kind))
5173 return C;
5174
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005175 if (const Decl *D = getCursorDecl(C)) {
5176 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5178 return MakeCXCursor(CatD, getCursorTU(C));
5179
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005180 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5181 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 return MakeCXCursor(IFD, getCursorTU(C));
5183
5184 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5185 }
5186
5187 return C;
5188}
5189
5190int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5191 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5192}
5193
5194unsigned clang_getNumOverloadedDecls(CXCursor C) {
5195 if (C.kind != CXCursor_OverloadedDeclRef)
5196 return 0;
5197
5198 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005199 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 return E->getNumDecls();
5201
5202 if (OverloadedTemplateStorage *S
5203 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5204 return S->size();
5205
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005206 const Decl *D = Storage.get<const Decl *>();
5207 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 return Using->shadow_size();
5209
5210 return 0;
5211}
5212
5213CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5214 if (cursor.kind != CXCursor_OverloadedDeclRef)
5215 return clang_getNullCursor();
5216
5217 if (index >= clang_getNumOverloadedDecls(cursor))
5218 return clang_getNullCursor();
5219
5220 CXTranslationUnit TU = getCursorTU(cursor);
5221 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005222 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005223 return MakeCXCursor(E->decls_begin()[index], TU);
5224
5225 if (OverloadedTemplateStorage *S
5226 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5227 return MakeCXCursor(S->begin()[index], TU);
5228
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005229 const Decl *D = Storage.get<const Decl *>();
5230 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005231 // FIXME: This is, unfortunately, linear time.
5232 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5233 std::advance(Pos, index);
5234 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5235 }
5236
5237 return clang_getNullCursor();
5238}
5239
5240void clang_getDefinitionSpellingAndExtent(CXCursor C,
5241 const char **startBuf,
5242 const char **endBuf,
5243 unsigned *startLine,
5244 unsigned *startColumn,
5245 unsigned *endLine,
5246 unsigned *endColumn) {
5247 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005248 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005249 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5250
5251 SourceManager &SM = FD->getASTContext().getSourceManager();
5252 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5253 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5254 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5255 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5256 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5257 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5258}
5259
5260
5261CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5262 unsigned PieceIndex) {
5263 RefNamePieces Pieces;
5264
5265 switch (C.kind) {
5266 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005267 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5269 E->getQualifierLoc().getSourceRange());
5270 break;
5271
5272 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005273 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5275 E->getQualifierLoc().getSourceRange(),
5276 E->getOptionalExplicitTemplateArgs());
5277 break;
5278
5279 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005280 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005281 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005282 const Expr *Callee = OCE->getCallee();
5283 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 Callee = ICE->getSubExpr();
5285
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005286 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005287 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5288 DRE->getQualifierLoc().getSourceRange());
5289 }
5290 break;
5291
5292 default:
5293 break;
5294 }
5295
5296 if (Pieces.empty()) {
5297 if (PieceIndex == 0)
5298 return clang_getCursorExtent(C);
5299 } else if (PieceIndex < Pieces.size()) {
5300 SourceRange R = Pieces[PieceIndex];
5301 if (R.isValid())
5302 return cxloc::translateSourceRange(getCursorContext(C), R);
5303 }
5304
5305 return clang_getNullRange();
5306}
5307
5308void clang_enableStackTraces(void) {
5309 llvm::sys::PrintStackTraceOnErrorSignal();
5310}
5311
5312void clang_executeOnThread(void (*fn)(void*), void *user_data,
5313 unsigned stack_size) {
5314 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5315}
5316
5317} // end: extern "C"
5318
5319//===----------------------------------------------------------------------===//
5320// Token-based Operations.
5321//===----------------------------------------------------------------------===//
5322
5323/* CXToken layout:
5324 * int_data[0]: a CXTokenKind
5325 * int_data[1]: starting token location
5326 * int_data[2]: token length
5327 * int_data[3]: reserved
5328 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5329 * otherwise unused.
5330 */
5331extern "C" {
5332
5333CXTokenKind clang_getTokenKind(CXToken CXTok) {
5334 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5335}
5336
5337CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5338 switch (clang_getTokenKind(CXTok)) {
5339 case CXToken_Identifier:
5340 case CXToken_Keyword:
5341 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005342 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 ->getNameStart());
5344
5345 case CXToken_Literal: {
5346 // We have stashed the starting pointer in the ptr_data field. Use it.
5347 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005348 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 }
5350
5351 case CXToken_Punctuation:
5352 case CXToken_Comment:
5353 break;
5354 }
5355
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005356 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005357 LOG_BAD_TU(TU);
5358 return cxstring::createEmpty();
5359 }
5360
Guy Benyei11169dd2012-12-18 14:30:41 +00005361 // We have to find the starting buffer pointer the hard way, by
5362 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005363 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005365 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005366
5367 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5368 std::pair<FileID, unsigned> LocInfo
5369 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5370 bool Invalid = false;
5371 StringRef Buffer
5372 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5373 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005374 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005375
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005376 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005377}
5378
5379CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005380 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005381 LOG_BAD_TU(TU);
5382 return clang_getNullLocation();
5383 }
5384
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005385 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005386 if (!CXXUnit)
5387 return clang_getNullLocation();
5388
5389 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5390 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5391}
5392
5393CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005394 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005395 LOG_BAD_TU(TU);
5396 return clang_getNullRange();
5397 }
5398
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005399 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005400 if (!CXXUnit)
5401 return clang_getNullRange();
5402
5403 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5404 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5405}
5406
5407static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5408 SmallVectorImpl<CXToken> &CXTokens) {
5409 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5410 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005411 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005412 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005413 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005414
5415 // Cannot tokenize across files.
5416 if (BeginLocInfo.first != EndLocInfo.first)
5417 return;
5418
5419 // Create a lexer
5420 bool Invalid = false;
5421 StringRef Buffer
5422 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5423 if (Invalid)
5424 return;
5425
5426 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5427 CXXUnit->getASTContext().getLangOpts(),
5428 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5429 Lex.SetCommentRetentionState(true);
5430
5431 // Lex tokens until we hit the end of the range.
5432 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5433 Token Tok;
5434 bool previousWasAt = false;
5435 do {
5436 // Lex the next token
5437 Lex.LexFromRawLexer(Tok);
5438 if (Tok.is(tok::eof))
5439 break;
5440
5441 // Initialize the CXToken.
5442 CXToken CXTok;
5443
5444 // - Common fields
5445 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5446 CXTok.int_data[2] = Tok.getLength();
5447 CXTok.int_data[3] = 0;
5448
5449 // - Kind-specific fields
5450 if (Tok.isLiteral()) {
5451 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005452 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 } else if (Tok.is(tok::raw_identifier)) {
5454 // Lookup the identifier to determine whether we have a keyword.
5455 IdentifierInfo *II
5456 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5457
5458 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5459 CXTok.int_data[0] = CXToken_Keyword;
5460 }
5461 else {
5462 CXTok.int_data[0] = Tok.is(tok::identifier)
5463 ? CXToken_Identifier
5464 : CXToken_Keyword;
5465 }
5466 CXTok.ptr_data = II;
5467 } else if (Tok.is(tok::comment)) {
5468 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005469 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005470 } else {
5471 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005472 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 }
5474 CXTokens.push_back(CXTok);
5475 previousWasAt = Tok.is(tok::at);
5476 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5477}
5478
5479void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5480 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005481 LOG_FUNC_SECTION {
5482 *Log << TU << ' ' << Range;
5483 }
5484
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005486 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 if (NumTokens)
5488 *NumTokens = 0;
5489
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005490 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005491 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005492 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005493 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005494
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005495 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005496 if (!CXXUnit || !Tokens || !NumTokens)
5497 return;
5498
5499 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5500
5501 SourceRange R = cxloc::translateCXSourceRange(Range);
5502 if (R.isInvalid())
5503 return;
5504
5505 SmallVector<CXToken, 32> CXTokens;
5506 getTokens(CXXUnit, R, CXTokens);
5507
5508 if (CXTokens.empty())
5509 return;
5510
5511 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5512 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5513 *NumTokens = CXTokens.size();
5514}
5515
5516void clang_disposeTokens(CXTranslationUnit TU,
5517 CXToken *Tokens, unsigned NumTokens) {
5518 free(Tokens);
5519}
5520
5521} // end: extern "C"
5522
5523//===----------------------------------------------------------------------===//
5524// Token annotation APIs.
5525//===----------------------------------------------------------------------===//
5526
Guy Benyei11169dd2012-12-18 14:30:41 +00005527static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5528 CXCursor parent,
5529 CXClientData client_data);
5530static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5531 CXClientData client_data);
5532
5533namespace {
5534class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005535 CXToken *Tokens;
5536 CXCursor *Cursors;
5537 unsigned NumTokens;
5538 unsigned TokIdx;
5539 unsigned PreprocessingTokIdx;
5540 CursorVisitor AnnotateVis;
5541 SourceManager &SrcMgr;
5542 bool HasContextSensitiveKeywords;
5543
5544 struct PostChildrenInfo {
5545 CXCursor Cursor;
5546 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005547 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005548 unsigned BeforeChildrenTokenIdx;
5549 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005550 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005551
5552 CXToken &getTok(unsigned Idx) {
5553 assert(Idx < NumTokens);
5554 return Tokens[Idx];
5555 }
5556 const CXToken &getTok(unsigned Idx) const {
5557 assert(Idx < NumTokens);
5558 return Tokens[Idx];
5559 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005560 bool MoreTokens() const { return TokIdx < NumTokens; }
5561 unsigned NextToken() const { return TokIdx; }
5562 void AdvanceToken() { ++TokIdx; }
5563 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005564 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 }
5566 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005567 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005568 }
5569 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005570 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005571 }
5572
5573 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005574 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005575 SourceRange);
5576
5577public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005578 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005579 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005580 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005581 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005582 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005583 AnnotateTokensVisitor, this,
5584 /*VisitPreprocessorLast=*/true,
5585 /*VisitIncludedEntities=*/false,
5586 RegionOfInterest,
5587 /*VisitDeclsOnly=*/false,
5588 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005589 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005590 HasContextSensitiveKeywords(false) { }
5591
5592 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5593 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5594 bool postVisitChildren(CXCursor cursor);
5595 void AnnotateTokens();
5596
5597 /// \brief Determine whether the annotator saw any cursors that have
5598 /// context-sensitive keywords.
5599 bool hasContextSensitiveKeywords() const {
5600 return HasContextSensitiveKeywords;
5601 }
5602
5603 ~AnnotateTokensWorker() {
5604 assert(PostChildrenInfos.empty());
5605 }
5606};
5607}
5608
5609void AnnotateTokensWorker::AnnotateTokens() {
5610 // Walk the AST within the region of interest, annotating tokens
5611 // along the way.
5612 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005613}
Guy Benyei11169dd2012-12-18 14:30:41 +00005614
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005615static inline void updateCursorAnnotation(CXCursor &Cursor,
5616 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005617 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005618 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005619 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005620}
5621
5622/// \brief It annotates and advances tokens with a cursor until the comparison
5623//// between the cursor location and the source range is the same as
5624/// \arg compResult.
5625///
5626/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5627/// Pass RangeOverlap to annotate tokens inside a range.
5628void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5629 RangeComparisonResult compResult,
5630 SourceRange range) {
5631 while (MoreTokens()) {
5632 const unsigned I = NextToken();
5633 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005634 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5635 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005636
5637 SourceLocation TokLoc = GetTokenLoc(I);
5638 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005639 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 AdvanceToken();
5641 continue;
5642 }
5643 break;
5644 }
5645}
5646
5647/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005648/// \returns true if it advanced beyond all macro tokens, false otherwise.
5649bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005650 CXCursor updateC,
5651 RangeComparisonResult compResult,
5652 SourceRange range) {
5653 assert(MoreTokens());
5654 assert(isFunctionMacroToken(NextToken()) &&
5655 "Should be called only for macro arg tokens");
5656
5657 // This works differently than annotateAndAdvanceTokens; because expanded
5658 // macro arguments can have arbitrary translation-unit source order, we do not
5659 // advance the token index one by one until a token fails the range test.
5660 // We only advance once past all of the macro arg tokens if all of them
5661 // pass the range test. If one of them fails we keep the token index pointing
5662 // at the start of the macro arg tokens so that the failing token will be
5663 // annotated by a subsequent annotation try.
5664
5665 bool atLeastOneCompFail = false;
5666
5667 unsigned I = NextToken();
5668 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5669 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5670 if (TokLoc.isFileID())
5671 continue; // not macro arg token, it's parens or comma.
5672 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5673 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5674 Cursors[I] = updateC;
5675 } else
5676 atLeastOneCompFail = true;
5677 }
5678
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005679 if (atLeastOneCompFail)
5680 return false;
5681
5682 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5683 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005684}
5685
5686enum CXChildVisitResult
5687AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 SourceRange cursorRange = getRawCursorExtent(cursor);
5689 if (cursorRange.isInvalid())
5690 return CXChildVisit_Recurse;
5691
5692 if (!HasContextSensitiveKeywords) {
5693 // Objective-C properties can have context-sensitive keywords.
5694 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005695 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005696 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5697 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5698 }
5699 // Objective-C methods can have context-sensitive keywords.
5700 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5701 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005702 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005703 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5704 if (Method->getObjCDeclQualifier())
5705 HasContextSensitiveKeywords = true;
5706 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005707 for (const auto *P : Method->params()) {
5708 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005709 HasContextSensitiveKeywords = true;
5710 break;
5711 }
5712 }
5713 }
5714 }
5715 }
5716 // C++ methods can have context-sensitive keywords.
5717 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005718 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005719 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5720 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5721 HasContextSensitiveKeywords = true;
5722 }
5723 }
5724 // C++ classes can have context-sensitive keywords.
5725 else if (cursor.kind == CXCursor_StructDecl ||
5726 cursor.kind == CXCursor_ClassDecl ||
5727 cursor.kind == CXCursor_ClassTemplate ||
5728 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005729 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005730 if (D->hasAttr<FinalAttr>())
5731 HasContextSensitiveKeywords = true;
5732 }
5733 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005734
5735 // Don't override a property annotation with its getter/setter method.
5736 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5737 parent.kind == CXCursor_ObjCPropertyDecl)
5738 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005739
5740 if (clang_isPreprocessing(cursor.kind)) {
5741 // Items in the preprocessing record are kept separate from items in
5742 // declarations, so we keep a separate token index.
5743 unsigned SavedTokIdx = TokIdx;
5744 TokIdx = PreprocessingTokIdx;
5745
5746 // Skip tokens up until we catch up to the beginning of the preprocessing
5747 // entry.
5748 while (MoreTokens()) {
5749 const unsigned I = NextToken();
5750 SourceLocation TokLoc = GetTokenLoc(I);
5751 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5752 case RangeBefore:
5753 AdvanceToken();
5754 continue;
5755 case RangeAfter:
5756 case RangeOverlap:
5757 break;
5758 }
5759 break;
5760 }
5761
5762 // Look at all of the tokens within this range.
5763 while (MoreTokens()) {
5764 const unsigned I = NextToken();
5765 SourceLocation TokLoc = GetTokenLoc(I);
5766 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5767 case RangeBefore:
5768 llvm_unreachable("Infeasible");
5769 case RangeAfter:
5770 break;
5771 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005772 // For macro expansions, just note where the beginning of the macro
5773 // expansion occurs.
5774 if (cursor.kind == CXCursor_MacroExpansion) {
5775 if (TokLoc == cursorRange.getBegin())
5776 Cursors[I] = cursor;
5777 AdvanceToken();
5778 break;
5779 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005780 // We may have already annotated macro names inside macro definitions.
5781 if (Cursors[I].kind != CXCursor_MacroExpansion)
5782 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005783 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005784 continue;
5785 }
5786 break;
5787 }
5788
5789 // Save the preprocessing token index; restore the non-preprocessing
5790 // token index.
5791 PreprocessingTokIdx = TokIdx;
5792 TokIdx = SavedTokIdx;
5793 return CXChildVisit_Recurse;
5794 }
5795
5796 if (cursorRange.isInvalid())
5797 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005798
5799 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005800 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005801 const enum CXCursorKind K = clang_getCursorKind(parent);
5802 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005803 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5804 // Attributes are annotated out-of-order, skip tokens until we reach it.
5805 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005806 ? clang_getNullCursor() : parent;
5807
5808 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5809
5810 // Avoid having the cursor of an expression "overwrite" the annotation of the
5811 // variable declaration that it belongs to.
5812 // This can happen for C++ constructor expressions whose range generally
5813 // include the variable declaration, e.g.:
5814 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005815 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005816 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005817 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 const unsigned I = NextToken();
5819 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5820 E->getLocStart() == D->getLocation() &&
5821 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005822 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005823 AdvanceToken();
5824 }
5825 }
5826 }
5827
5828 // Before recursing into the children keep some state that we are going
5829 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5830 // extra work after the child nodes are visited.
5831 // Note that we don't call VisitChildren here to avoid traversing statements
5832 // code-recursively which can blow the stack.
5833
5834 PostChildrenInfo Info;
5835 Info.Cursor = cursor;
5836 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005837 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005838 Info.BeforeChildrenTokenIdx = NextToken();
5839 PostChildrenInfos.push_back(Info);
5840
5841 return CXChildVisit_Recurse;
5842}
5843
5844bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5845 if (PostChildrenInfos.empty())
5846 return false;
5847 const PostChildrenInfo &Info = PostChildrenInfos.back();
5848 if (!clang_equalCursors(Info.Cursor, cursor))
5849 return false;
5850
5851 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5852 const unsigned AfterChildren = NextToken();
5853 SourceRange cursorRange = Info.CursorRange;
5854
5855 // Scan the tokens that are at the end of the cursor, but are not captured
5856 // but the child cursors.
5857 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5858
5859 // Scan the tokens that are at the beginning of the cursor, but are not
5860 // capture by the child cursors.
5861 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5862 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5863 break;
5864
5865 Cursors[I] = cursor;
5866 }
5867
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005868 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5869 // encountered the attribute cursor.
5870 if (clang_isAttribute(cursor.kind))
5871 TokIdx = Info.BeforeReachingCursorIdx;
5872
Guy Benyei11169dd2012-12-18 14:30:41 +00005873 PostChildrenInfos.pop_back();
5874 return false;
5875}
5876
5877static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5878 CXCursor parent,
5879 CXClientData client_data) {
5880 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5881}
5882
5883static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5884 CXClientData client_data) {
5885 return static_cast<AnnotateTokensWorker*>(client_data)->
5886 postVisitChildren(cursor);
5887}
5888
5889namespace {
5890
5891/// \brief Uses the macro expansions in the preprocessing record to find
5892/// and mark tokens that are macro arguments. This info is used by the
5893/// AnnotateTokensWorker.
5894class MarkMacroArgTokensVisitor {
5895 SourceManager &SM;
5896 CXToken *Tokens;
5897 unsigned NumTokens;
5898 unsigned CurIdx;
5899
5900public:
5901 MarkMacroArgTokensVisitor(SourceManager &SM,
5902 CXToken *tokens, unsigned numTokens)
5903 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5904
5905 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5906 if (cursor.kind != CXCursor_MacroExpansion)
5907 return CXChildVisit_Continue;
5908
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005909 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005910 if (macroRange.getBegin() == macroRange.getEnd())
5911 return CXChildVisit_Continue; // it's not a function macro.
5912
5913 for (; CurIdx < NumTokens; ++CurIdx) {
5914 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5915 macroRange.getBegin()))
5916 break;
5917 }
5918
5919 if (CurIdx == NumTokens)
5920 return CXChildVisit_Break;
5921
5922 for (; CurIdx < NumTokens; ++CurIdx) {
5923 SourceLocation tokLoc = getTokenLoc(CurIdx);
5924 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5925 break;
5926
5927 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5928 }
5929
5930 if (CurIdx == NumTokens)
5931 return CXChildVisit_Break;
5932
5933 return CXChildVisit_Continue;
5934 }
5935
5936private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005937 CXToken &getTok(unsigned Idx) {
5938 assert(Idx < NumTokens);
5939 return Tokens[Idx];
5940 }
5941 const CXToken &getTok(unsigned Idx) const {
5942 assert(Idx < NumTokens);
5943 return Tokens[Idx];
5944 }
5945
Guy Benyei11169dd2012-12-18 14:30:41 +00005946 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005947 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005948 }
5949
5950 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5951 // The third field is reserved and currently not used. Use it here
5952 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005953 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005954 }
5955};
5956
5957} // end anonymous namespace
5958
5959static CXChildVisitResult
5960MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5961 CXClientData client_data) {
5962 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5963 parent);
5964}
5965
5966namespace {
5967 struct clang_annotateTokens_Data {
5968 CXTranslationUnit TU;
5969 ASTUnit *CXXUnit;
5970 CXToken *Tokens;
5971 unsigned NumTokens;
5972 CXCursor *Cursors;
5973 };
5974}
5975
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005976/// \brief Used by \c annotatePreprocessorTokens.
5977/// \returns true if lexing was finished, false otherwise.
5978static bool lexNext(Lexer &Lex, Token &Tok,
5979 unsigned &NextIdx, unsigned NumTokens) {
5980 if (NextIdx >= NumTokens)
5981 return true;
5982
5983 ++NextIdx;
5984 Lex.LexFromRawLexer(Tok);
5985 if (Tok.is(tok::eof))
5986 return true;
5987
5988 return false;
5989}
5990
Guy Benyei11169dd2012-12-18 14:30:41 +00005991static void annotatePreprocessorTokens(CXTranslationUnit TU,
5992 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005993 CXCursor *Cursors,
5994 CXToken *Tokens,
5995 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005996 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005997
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005998 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005999 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6000 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006001 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006002 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006003 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006004
6005 if (BeginLocInfo.first != EndLocInfo.first)
6006 return;
6007
6008 StringRef Buffer;
6009 bool Invalid = false;
6010 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6011 if (Buffer.empty() || Invalid)
6012 return;
6013
6014 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6015 CXXUnit->getASTContext().getLangOpts(),
6016 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6017 Buffer.end());
6018 Lex.SetCommentRetentionState(true);
6019
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006020 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006021 // Lex tokens in raw mode until we hit the end of the range, to avoid
6022 // entering #includes or expanding macros.
6023 while (true) {
6024 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006025 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6026 break;
6027 unsigned TokIdx = NextIdx-1;
6028 assert(Tok.getLocation() ==
6029 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006030
6031 reprocess:
6032 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006033 // We have found a preprocessing directive. Annotate the tokens
6034 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006035 //
6036 // FIXME: Some simple tests here could identify macro definitions and
6037 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006038
6039 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006040 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6041 break;
6042
Craig Topper69186e72014-06-08 08:38:04 +00006043 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006044 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006045 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6046 break;
6047
6048 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006049 IdentifierInfo &II =
6050 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006051 SourceLocation MappedTokLoc =
6052 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6053 MI = getMacroInfo(II, MappedTokLoc, TU);
6054 }
6055 }
6056
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006057 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006058 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006059 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6060 finished = true;
6061 break;
6062 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006063 // If we are in a macro definition, check if the token was ever a
6064 // macro name and annotate it if that's the case.
6065 if (MI) {
6066 SourceLocation SaveLoc = Tok.getLocation();
6067 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006068 MacroDefinitionRecord *MacroDef =
6069 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006070 Tok.setLocation(SaveLoc);
6071 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006072 Cursors[NextIdx - 1] =
6073 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006074 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006075 } while (!Tok.isAtStartOfLine());
6076
6077 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6078 assert(TokIdx <= LastIdx);
6079 SourceLocation EndLoc =
6080 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6081 CXCursor Cursor =
6082 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6083
6084 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006085 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006086
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006087 if (finished)
6088 break;
6089 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006090 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006091 }
6092}
6093
6094// This gets run a separate thread to avoid stack blowout.
6095static void clang_annotateTokensImpl(void *UserData) {
6096 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6097 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6098 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6099 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6100 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6101
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006102 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006103 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6104 setThreadBackgroundPriority();
6105
6106 // Determine the region of interest, which contains all of the tokens.
6107 SourceRange RegionOfInterest;
6108 RegionOfInterest.setBegin(
6109 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6110 RegionOfInterest.setEnd(
6111 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6112 Tokens[NumTokens-1])));
6113
Guy Benyei11169dd2012-12-18 14:30:41 +00006114 // Relex the tokens within the source range to look for preprocessing
6115 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006116 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006117
6118 // If begin location points inside a macro argument, set it to the expansion
6119 // location so we can have the full context when annotating semantically.
6120 {
6121 SourceManager &SM = CXXUnit->getSourceManager();
6122 SourceLocation Loc =
6123 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6124 if (Loc.isMacroID())
6125 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6126 }
6127
Guy Benyei11169dd2012-12-18 14:30:41 +00006128 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6129 // Search and mark tokens that are macro argument expansions.
6130 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6131 Tokens, NumTokens);
6132 CursorVisitor MacroArgMarker(TU,
6133 MarkMacroArgTokensVisitorDelegate, &Visitor,
6134 /*VisitPreprocessorLast=*/true,
6135 /*VisitIncludedEntities=*/false,
6136 RegionOfInterest);
6137 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6138 }
6139
6140 // Annotate all of the source locations in the region of interest that map to
6141 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006142 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006143
6144 // FIXME: We use a ridiculous stack size here because the data-recursion
6145 // algorithm uses a large stack frame than the non-data recursive version,
6146 // and AnnotationTokensWorker currently transforms the data-recursion
6147 // algorithm back into a traditional recursion by explicitly calling
6148 // VisitChildren(). We will need to remove this explicit recursive call.
6149 W.AnnotateTokens();
6150
6151 // If we ran into any entities that involve context-sensitive keywords,
6152 // take another pass through the tokens to mark them as such.
6153 if (W.hasContextSensitiveKeywords()) {
6154 for (unsigned I = 0; I != NumTokens; ++I) {
6155 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6156 continue;
6157
6158 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6159 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006160 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006161 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6162 if (Property->getPropertyAttributesAsWritten() != 0 &&
6163 llvm::StringSwitch<bool>(II->getName())
6164 .Case("readonly", true)
6165 .Case("assign", true)
6166 .Case("unsafe_unretained", true)
6167 .Case("readwrite", true)
6168 .Case("retain", true)
6169 .Case("copy", true)
6170 .Case("nonatomic", true)
6171 .Case("atomic", true)
6172 .Case("getter", true)
6173 .Case("setter", true)
6174 .Case("strong", true)
6175 .Case("weak", true)
6176 .Default(false))
6177 Tokens[I].int_data[0] = CXToken_Keyword;
6178 }
6179 continue;
6180 }
6181
6182 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6183 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6184 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6185 if (llvm::StringSwitch<bool>(II->getName())
6186 .Case("in", true)
6187 .Case("out", true)
6188 .Case("inout", true)
6189 .Case("oneway", true)
6190 .Case("bycopy", true)
6191 .Case("byref", true)
6192 .Default(false))
6193 Tokens[I].int_data[0] = CXToken_Keyword;
6194 continue;
6195 }
6196
6197 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6198 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6199 Tokens[I].int_data[0] = CXToken_Keyword;
6200 continue;
6201 }
6202 }
6203 }
6204}
6205
6206extern "C" {
6207
6208void clang_annotateTokens(CXTranslationUnit TU,
6209 CXToken *Tokens, unsigned NumTokens,
6210 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006211 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006212 LOG_BAD_TU(TU);
6213 return;
6214 }
6215 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006216 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006217 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006218 }
6219
6220 LOG_FUNC_SECTION {
6221 *Log << TU << ' ';
6222 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6223 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6224 *Log << clang_getRange(bloc, eloc);
6225 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006226
6227 // Any token we don't specifically annotate will have a NULL cursor.
6228 CXCursor C = clang_getNullCursor();
6229 for (unsigned I = 0; I != NumTokens; ++I)
6230 Cursors[I] = C;
6231
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006232 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006233 if (!CXXUnit)
6234 return;
6235
6236 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6237
6238 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6239 llvm::CrashRecoveryContext CRC;
6240 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6241 GetSafetyThreadStackSize() * 2)) {
6242 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6243 }
6244}
6245
6246} // end: extern "C"
6247
6248//===----------------------------------------------------------------------===//
6249// Operations for querying linkage of a cursor.
6250//===----------------------------------------------------------------------===//
6251
6252extern "C" {
6253CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6254 if (!clang_isDeclaration(cursor.kind))
6255 return CXLinkage_Invalid;
6256
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006257 const Decl *D = cxcursor::getCursorDecl(cursor);
6258 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006259 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006260 case NoLinkage:
6261 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006262 case InternalLinkage: return CXLinkage_Internal;
6263 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6264 case ExternalLinkage: return CXLinkage_External;
6265 };
6266
6267 return CXLinkage_Invalid;
6268}
6269} // end: extern "C"
6270
6271//===----------------------------------------------------------------------===//
6272// Operations for querying language of a cursor.
6273//===----------------------------------------------------------------------===//
6274
6275static CXLanguageKind getDeclLanguage(const Decl *D) {
6276 if (!D)
6277 return CXLanguage_C;
6278
6279 switch (D->getKind()) {
6280 default:
6281 break;
6282 case Decl::ImplicitParam:
6283 case Decl::ObjCAtDefsField:
6284 case Decl::ObjCCategory:
6285 case Decl::ObjCCategoryImpl:
6286 case Decl::ObjCCompatibleAlias:
6287 case Decl::ObjCImplementation:
6288 case Decl::ObjCInterface:
6289 case Decl::ObjCIvar:
6290 case Decl::ObjCMethod:
6291 case Decl::ObjCProperty:
6292 case Decl::ObjCPropertyImpl:
6293 case Decl::ObjCProtocol:
6294 return CXLanguage_ObjC;
6295 case Decl::CXXConstructor:
6296 case Decl::CXXConversion:
6297 case Decl::CXXDestructor:
6298 case Decl::CXXMethod:
6299 case Decl::CXXRecord:
6300 case Decl::ClassTemplate:
6301 case Decl::ClassTemplatePartialSpecialization:
6302 case Decl::ClassTemplateSpecialization:
6303 case Decl::Friend:
6304 case Decl::FriendTemplate:
6305 case Decl::FunctionTemplate:
6306 case Decl::LinkageSpec:
6307 case Decl::Namespace:
6308 case Decl::NamespaceAlias:
6309 case Decl::NonTypeTemplateParm:
6310 case Decl::StaticAssert:
6311 case Decl::TemplateTemplateParm:
6312 case Decl::TemplateTypeParm:
6313 case Decl::UnresolvedUsingTypename:
6314 case Decl::UnresolvedUsingValue:
6315 case Decl::Using:
6316 case Decl::UsingDirective:
6317 case Decl::UsingShadow:
6318 return CXLanguage_CPlusPlus;
6319 }
6320
6321 return CXLanguage_C;
6322}
6323
6324extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006325
6326static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6327 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6328 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006329
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006330 switch (D->getAvailability()) {
6331 case AR_Available:
6332 case AR_NotYetIntroduced:
6333 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006334 return getCursorAvailabilityForDecl(
6335 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006336 return CXAvailability_Available;
6337
6338 case AR_Deprecated:
6339 return CXAvailability_Deprecated;
6340
6341 case AR_Unavailable:
6342 return CXAvailability_NotAvailable;
6343 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006344
6345 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006346}
6347
Guy Benyei11169dd2012-12-18 14:30:41 +00006348enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6349 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006350 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6351 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006352
6353 return CXAvailability_Available;
6354}
6355
6356static CXVersion convertVersion(VersionTuple In) {
6357 CXVersion Out = { -1, -1, -1 };
6358 if (In.empty())
6359 return Out;
6360
6361 Out.Major = In.getMajor();
6362
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006363 Optional<unsigned> Minor = In.getMinor();
6364 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 Out.Minor = *Minor;
6366 else
6367 return Out;
6368
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006369 Optional<unsigned> Subminor = In.getSubminor();
6370 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006371 Out.Subminor = *Subminor;
6372
6373 return Out;
6374}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006375
6376static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6377 int *always_deprecated,
6378 CXString *deprecated_message,
6379 int *always_unavailable,
6380 CXString *unavailable_message,
6381 CXPlatformAvailability *availability,
6382 int availability_size) {
6383 bool HadAvailAttr = false;
6384 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006385 for (auto A : D->attrs()) {
6386 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006387 HadAvailAttr = true;
6388 if (always_deprecated)
6389 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006390 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006391 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006392 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006393 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006394 continue;
6395 }
6396
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006397 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006398 HadAvailAttr = true;
6399 if (always_unavailable)
6400 *always_unavailable = 1;
6401 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006402 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006403 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6404 }
6405 continue;
6406 }
6407
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006408 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006409 HadAvailAttr = true;
6410 if (N < availability_size) {
6411 availability[N].Platform
6412 = cxstring::createDup(Avail->getPlatform()->getName());
6413 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6414 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6415 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6416 availability[N].Unavailable = Avail->getUnavailable();
6417 availability[N].Message = cxstring::createDup(Avail->getMessage());
6418 }
6419 ++N;
6420 }
6421 }
6422
6423 if (!HadAvailAttr)
6424 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6425 return getCursorPlatformAvailabilityForDecl(
6426 cast<Decl>(EnumConst->getDeclContext()),
6427 always_deprecated,
6428 deprecated_message,
6429 always_unavailable,
6430 unavailable_message,
6431 availability,
6432 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006433
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006434 return N;
6435}
6436
Guy Benyei11169dd2012-12-18 14:30:41 +00006437int clang_getCursorPlatformAvailability(CXCursor cursor,
6438 int *always_deprecated,
6439 CXString *deprecated_message,
6440 int *always_unavailable,
6441 CXString *unavailable_message,
6442 CXPlatformAvailability *availability,
6443 int availability_size) {
6444 if (always_deprecated)
6445 *always_deprecated = 0;
6446 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006447 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006448 if (always_unavailable)
6449 *always_unavailable = 0;
6450 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006451 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006452
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 if (!clang_isDeclaration(cursor.kind))
6454 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006455
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006456 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006457 if (!D)
6458 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006459
6460 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6461 deprecated_message,
6462 always_unavailable,
6463 unavailable_message,
6464 availability,
6465 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006466}
6467
6468void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6469 clang_disposeString(availability->Platform);
6470 clang_disposeString(availability->Message);
6471}
6472
6473CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6474 if (clang_isDeclaration(cursor.kind))
6475 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6476
6477 return CXLanguage_Invalid;
6478}
6479
6480 /// \brief If the given cursor is the "templated" declaration
6481 /// descibing a class or function template, return the class or
6482 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006483static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006484 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006485 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006486
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006487 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006488 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6489 return FunTmpl;
6490
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006491 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006492 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6493 return ClassTmpl;
6494
6495 return D;
6496}
6497
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006498
6499enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6500 StorageClass sc = SC_None;
6501 const Decl *D = getCursorDecl(C);
6502 if (D) {
6503 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6504 sc = FD->getStorageClass();
6505 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6506 sc = VD->getStorageClass();
6507 } else {
6508 return CX_SC_Invalid;
6509 }
6510 } else {
6511 return CX_SC_Invalid;
6512 }
6513 switch (sc) {
6514 case SC_None:
6515 return CX_SC_None;
6516 case SC_Extern:
6517 return CX_SC_Extern;
6518 case SC_Static:
6519 return CX_SC_Static;
6520 case SC_PrivateExtern:
6521 return CX_SC_PrivateExtern;
6522 case SC_OpenCLWorkGroupLocal:
6523 return CX_SC_OpenCLWorkGroupLocal;
6524 case SC_Auto:
6525 return CX_SC_Auto;
6526 case SC_Register:
6527 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006528 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006529 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006530}
6531
Guy Benyei11169dd2012-12-18 14:30:41 +00006532CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6533 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006534 if (const Decl *D = getCursorDecl(cursor)) {
6535 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006536 if (!DC)
6537 return clang_getNullCursor();
6538
6539 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6540 getCursorTU(cursor));
6541 }
6542 }
6543
6544 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006545 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006546 return MakeCXCursor(D, getCursorTU(cursor));
6547 }
6548
6549 return clang_getNullCursor();
6550}
6551
6552CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6553 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006554 if (const Decl *D = getCursorDecl(cursor)) {
6555 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006556 if (!DC)
6557 return clang_getNullCursor();
6558
6559 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6560 getCursorTU(cursor));
6561 }
6562 }
6563
6564 // FIXME: Note that we can't easily compute the lexical context of a
6565 // statement or expression, so we return nothing.
6566 return clang_getNullCursor();
6567}
6568
6569CXFile clang_getIncludedFile(CXCursor cursor) {
6570 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006571 return nullptr;
6572
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006573 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006574 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006575}
6576
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006577unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6578 if (C.kind != CXCursor_ObjCPropertyDecl)
6579 return CXObjCPropertyAttr_noattr;
6580
6581 unsigned Result = CXObjCPropertyAttr_noattr;
6582 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6583 ObjCPropertyDecl::PropertyAttributeKind Attr =
6584 PD->getPropertyAttributesAsWritten();
6585
6586#define SET_CXOBJCPROP_ATTR(A) \
6587 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6588 Result |= CXObjCPropertyAttr_##A
6589 SET_CXOBJCPROP_ATTR(readonly);
6590 SET_CXOBJCPROP_ATTR(getter);
6591 SET_CXOBJCPROP_ATTR(assign);
6592 SET_CXOBJCPROP_ATTR(readwrite);
6593 SET_CXOBJCPROP_ATTR(retain);
6594 SET_CXOBJCPROP_ATTR(copy);
6595 SET_CXOBJCPROP_ATTR(nonatomic);
6596 SET_CXOBJCPROP_ATTR(setter);
6597 SET_CXOBJCPROP_ATTR(atomic);
6598 SET_CXOBJCPROP_ATTR(weak);
6599 SET_CXOBJCPROP_ATTR(strong);
6600 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6601#undef SET_CXOBJCPROP_ATTR
6602
6603 return Result;
6604}
6605
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006606unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6607 if (!clang_isDeclaration(C.kind))
6608 return CXObjCDeclQualifier_None;
6609
6610 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6611 const Decl *D = getCursorDecl(C);
6612 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6613 QT = MD->getObjCDeclQualifier();
6614 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6615 QT = PD->getObjCDeclQualifier();
6616 if (QT == Decl::OBJC_TQ_None)
6617 return CXObjCDeclQualifier_None;
6618
6619 unsigned Result = CXObjCDeclQualifier_None;
6620 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6621 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6622 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6623 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6624 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6625 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6626
6627 return Result;
6628}
6629
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006630unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6631 if (!clang_isDeclaration(C.kind))
6632 return 0;
6633
6634 const Decl *D = getCursorDecl(C);
6635 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6636 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6637 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6638 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6639
6640 return 0;
6641}
6642
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006643unsigned clang_Cursor_isVariadic(CXCursor C) {
6644 if (!clang_isDeclaration(C.kind))
6645 return 0;
6646
6647 const Decl *D = getCursorDecl(C);
6648 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6649 return FD->isVariadic();
6650 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6651 return MD->isVariadic();
6652
6653 return 0;
6654}
6655
Guy Benyei11169dd2012-12-18 14:30:41 +00006656CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6657 if (!clang_isDeclaration(C.kind))
6658 return clang_getNullRange();
6659
6660 const Decl *D = getCursorDecl(C);
6661 ASTContext &Context = getCursorContext(C);
6662 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6663 if (!RC)
6664 return clang_getNullRange();
6665
6666 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6667}
6668
6669CXString clang_Cursor_getRawCommentText(CXCursor C) {
6670 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006671 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006672
6673 const Decl *D = getCursorDecl(C);
6674 ASTContext &Context = getCursorContext(C);
6675 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6676 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6677 StringRef();
6678
6679 // Don't duplicate the string because RawText points directly into source
6680 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006681 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006682}
6683
6684CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6685 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006686 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006687
6688 const Decl *D = getCursorDecl(C);
6689 const ASTContext &Context = getCursorContext(C);
6690 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6691
6692 if (RC) {
6693 StringRef BriefText = RC->getBriefText(Context);
6694
6695 // Don't duplicate the string because RawComment ensures that this memory
6696 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006697 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006698 }
6699
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006700 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006701}
6702
Guy Benyei11169dd2012-12-18 14:30:41 +00006703CXModule clang_Cursor_getModule(CXCursor C) {
6704 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006705 if (const ImportDecl *ImportD =
6706 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006707 return ImportD->getImportedModule();
6708 }
6709
Craig Topper69186e72014-06-08 08:38:04 +00006710 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006711}
6712
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006713CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6714 if (isNotUsableTU(TU)) {
6715 LOG_BAD_TU(TU);
6716 return nullptr;
6717 }
6718 if (!File)
6719 return nullptr;
6720 FileEntry *FE = static_cast<FileEntry *>(File);
6721
6722 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6723 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6724 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6725
Richard Smithfeb54b62014-10-23 02:01:19 +00006726 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006727}
6728
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006729CXFile clang_Module_getASTFile(CXModule CXMod) {
6730 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006731 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006732 Module *Mod = static_cast<Module*>(CXMod);
6733 return const_cast<FileEntry *>(Mod->getASTFile());
6734}
6735
Guy Benyei11169dd2012-12-18 14:30:41 +00006736CXModule clang_Module_getParent(CXModule CXMod) {
6737 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006738 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006739 Module *Mod = static_cast<Module*>(CXMod);
6740 return Mod->Parent;
6741}
6742
6743CXString clang_Module_getName(CXModule CXMod) {
6744 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006745 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006746 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006747 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006748}
6749
6750CXString clang_Module_getFullName(CXModule CXMod) {
6751 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006752 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006753 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006754 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006755}
6756
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006757int clang_Module_isSystem(CXModule CXMod) {
6758 if (!CXMod)
6759 return 0;
6760 Module *Mod = static_cast<Module*>(CXMod);
6761 return Mod->IsSystem;
6762}
6763
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006764unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6765 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006766 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006767 LOG_BAD_TU(TU);
6768 return 0;
6769 }
6770 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006771 return 0;
6772 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006773 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6774 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6775 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006776}
6777
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006778CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6779 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006780 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006781 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006782 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006783 }
6784 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006785 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006786 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006787 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006788
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006789 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6790 if (Index < TopHeaders.size())
6791 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006792
Craig Topper69186e72014-06-08 08:38:04 +00006793 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006794}
6795
6796} // end: extern "C"
6797
6798//===----------------------------------------------------------------------===//
6799// C++ AST instrospection.
6800//===----------------------------------------------------------------------===//
6801
6802extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006803unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6804 if (!clang_isDeclaration(C.kind))
6805 return 0;
6806
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006807 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006808 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006809 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006810 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6811}
6812
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006813unsigned clang_CXXMethod_isConst(CXCursor C) {
6814 if (!clang_isDeclaration(C.kind))
6815 return 0;
6816
6817 const Decl *D = cxcursor::getCursorDecl(C);
6818 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006819 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006820 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6821}
6822
Guy Benyei11169dd2012-12-18 14:30:41 +00006823unsigned clang_CXXMethod_isStatic(CXCursor C) {
6824 if (!clang_isDeclaration(C.kind))
6825 return 0;
6826
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006827 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006828 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006829 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006830 return (Method && Method->isStatic()) ? 1 : 0;
6831}
6832
6833unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6834 if (!clang_isDeclaration(C.kind))
6835 return 0;
6836
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006837 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006838 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006839 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006840 return (Method && Method->isVirtual()) ? 1 : 0;
6841}
6842} // end: extern "C"
6843
6844//===----------------------------------------------------------------------===//
6845// Attribute introspection.
6846//===----------------------------------------------------------------------===//
6847
6848extern "C" {
6849CXType clang_getIBOutletCollectionType(CXCursor C) {
6850 if (C.kind != CXCursor_IBOutletCollectionAttr)
6851 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6852
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006853 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006854 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6855
6856 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6857}
6858} // end: extern "C"
6859
6860//===----------------------------------------------------------------------===//
6861// Inspecting memory usage.
6862//===----------------------------------------------------------------------===//
6863
6864typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6865
6866static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6867 enum CXTUResourceUsageKind k,
6868 unsigned long amount) {
6869 CXTUResourceUsageEntry entry = { k, amount };
6870 entries.push_back(entry);
6871}
6872
6873extern "C" {
6874
6875const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6876 const char *str = "";
6877 switch (kind) {
6878 case CXTUResourceUsage_AST:
6879 str = "ASTContext: expressions, declarations, and types";
6880 break;
6881 case CXTUResourceUsage_Identifiers:
6882 str = "ASTContext: identifiers";
6883 break;
6884 case CXTUResourceUsage_Selectors:
6885 str = "ASTContext: selectors";
6886 break;
6887 case CXTUResourceUsage_GlobalCompletionResults:
6888 str = "Code completion: cached global results";
6889 break;
6890 case CXTUResourceUsage_SourceManagerContentCache:
6891 str = "SourceManager: content cache allocator";
6892 break;
6893 case CXTUResourceUsage_AST_SideTables:
6894 str = "ASTContext: side tables";
6895 break;
6896 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6897 str = "SourceManager: malloc'ed memory buffers";
6898 break;
6899 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6900 str = "SourceManager: mmap'ed memory buffers";
6901 break;
6902 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6903 str = "ExternalASTSource: malloc'ed memory buffers";
6904 break;
6905 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6906 str = "ExternalASTSource: mmap'ed memory buffers";
6907 break;
6908 case CXTUResourceUsage_Preprocessor:
6909 str = "Preprocessor: malloc'ed memory";
6910 break;
6911 case CXTUResourceUsage_PreprocessingRecord:
6912 str = "Preprocessor: PreprocessingRecord";
6913 break;
6914 case CXTUResourceUsage_SourceManager_DataStructures:
6915 str = "SourceManager: data structures and tables";
6916 break;
6917 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6918 str = "Preprocessor: header search tables";
6919 break;
6920 }
6921 return str;
6922}
6923
6924CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006925 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006926 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006927 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006928 return usage;
6929 }
6930
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006931 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006932 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006933 ASTContext &astContext = astUnit->getASTContext();
6934
6935 // How much memory is used by AST nodes and types?
6936 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6937 (unsigned long) astContext.getASTAllocatedMemory());
6938
6939 // How much memory is used by identifiers?
6940 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6941 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6942
6943 // How much memory is used for selectors?
6944 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6945 (unsigned long) astContext.Selectors.getTotalMemory());
6946
6947 // How much memory is used by ASTContext's side tables?
6948 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6949 (unsigned long) astContext.getSideTableAllocatedMemory());
6950
6951 // How much memory is used for caching global code completion results?
6952 unsigned long completionBytes = 0;
6953 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006954 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006955 completionBytes = completionAllocator->getTotalMemory();
6956 }
6957 createCXTUResourceUsageEntry(*entries,
6958 CXTUResourceUsage_GlobalCompletionResults,
6959 completionBytes);
6960
6961 // How much memory is being used by SourceManager's content cache?
6962 createCXTUResourceUsageEntry(*entries,
6963 CXTUResourceUsage_SourceManagerContentCache,
6964 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6965
6966 // How much memory is being used by the MemoryBuffer's in SourceManager?
6967 const SourceManager::MemoryBufferSizes &srcBufs =
6968 astUnit->getSourceManager().getMemoryBufferSizes();
6969
6970 createCXTUResourceUsageEntry(*entries,
6971 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6972 (unsigned long) srcBufs.malloc_bytes);
6973 createCXTUResourceUsageEntry(*entries,
6974 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6975 (unsigned long) srcBufs.mmap_bytes);
6976 createCXTUResourceUsageEntry(*entries,
6977 CXTUResourceUsage_SourceManager_DataStructures,
6978 (unsigned long) astContext.getSourceManager()
6979 .getDataStructureSizes());
6980
6981 // How much memory is being used by the ExternalASTSource?
6982 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6983 const ExternalASTSource::MemoryBufferSizes &sizes =
6984 esrc->getMemoryBufferSizes();
6985
6986 createCXTUResourceUsageEntry(*entries,
6987 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6988 (unsigned long) sizes.malloc_bytes);
6989 createCXTUResourceUsageEntry(*entries,
6990 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6991 (unsigned long) sizes.mmap_bytes);
6992 }
6993
6994 // How much memory is being used by the Preprocessor?
6995 Preprocessor &pp = astUnit->getPreprocessor();
6996 createCXTUResourceUsageEntry(*entries,
6997 CXTUResourceUsage_Preprocessor,
6998 pp.getTotalMemory());
6999
7000 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7001 createCXTUResourceUsageEntry(*entries,
7002 CXTUResourceUsage_PreprocessingRecord,
7003 pRec->getTotalMemory());
7004 }
7005
7006 createCXTUResourceUsageEntry(*entries,
7007 CXTUResourceUsage_Preprocessor_HeaderSearch,
7008 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007009
Guy Benyei11169dd2012-12-18 14:30:41 +00007010 CXTUResourceUsage usage = { (void*) entries.get(),
7011 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007012 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007013 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007014 return usage;
7015}
7016
7017void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7018 if (usage.data)
7019 delete (MemUsageEntries*) usage.data;
7020}
7021
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007022CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7023 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007024 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007025 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007026
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007027 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007028 LOG_BAD_TU(TU);
7029 return skipped;
7030 }
7031
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007032 if (!file)
7033 return skipped;
7034
7035 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7036 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7037 if (!ppRec)
7038 return skipped;
7039
7040 ASTContext &Ctx = astUnit->getASTContext();
7041 SourceManager &sm = Ctx.getSourceManager();
7042 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7043 FileID wantedFileID = sm.translateFile(fileEntry);
7044
7045 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7046 std::vector<SourceRange> wantedRanges;
7047 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7048 i != ei; ++i) {
7049 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7050 wantedRanges.push_back(*i);
7051 }
7052
7053 skipped->count = wantedRanges.size();
7054 skipped->ranges = new CXSourceRange[skipped->count];
7055 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7056 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7057
7058 return skipped;
7059}
7060
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007061void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7062 if (ranges) {
7063 delete[] ranges->ranges;
7064 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007065 }
7066}
7067
Guy Benyei11169dd2012-12-18 14:30:41 +00007068} // end extern "C"
7069
7070void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7071 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7072 for (unsigned I = 0; I != Usage.numEntries; ++I)
7073 fprintf(stderr, " %s: %lu\n",
7074 clang_getTUResourceUsageName(Usage.entries[I].kind),
7075 Usage.entries[I].amount);
7076
7077 clang_disposeCXTUResourceUsage(Usage);
7078}
7079
7080//===----------------------------------------------------------------------===//
7081// Misc. utility functions.
7082//===----------------------------------------------------------------------===//
7083
7084/// Default to using an 8 MB stack size on "safety" threads.
7085static unsigned SafetyStackThreadSize = 8 << 20;
7086
7087namespace clang {
7088
7089bool RunSafely(llvm::CrashRecoveryContext &CRC,
7090 void (*Fn)(void*), void *UserData,
7091 unsigned Size) {
7092 if (!Size)
7093 Size = GetSafetyThreadStackSize();
7094 if (Size)
7095 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7096 return CRC.RunSafely(Fn, UserData);
7097}
7098
7099unsigned GetSafetyThreadStackSize() {
7100 return SafetyStackThreadSize;
7101}
7102
7103void SetSafetyThreadStackSize(unsigned Value) {
7104 SafetyStackThreadSize = Value;
7105}
7106
7107}
7108
7109void clang::setThreadBackgroundPriority() {
7110 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7111 return;
7112
Alp Toker1a86ad22014-07-06 06:24:00 +00007113#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007114 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7115#endif
7116}
7117
7118void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7119 if (!Unit)
7120 return;
7121
7122 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7123 DEnd = Unit->stored_diag_end();
7124 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007125 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007126 CXString Msg = clang_formatDiagnostic(&Diag,
7127 clang_defaultDiagnosticDisplayOptions());
7128 fprintf(stderr, "%s\n", clang_getCString(Msg));
7129 clang_disposeString(Msg);
7130 }
7131#ifdef LLVM_ON_WIN32
7132 // On Windows, force a flush, since there may be multiple copies of
7133 // stderr and stdout in the file system, all with different buffers
7134 // but writing to the same device.
7135 fflush(stderr);
7136#endif
7137}
7138
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007139MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7140 SourceLocation MacroDefLoc,
7141 CXTranslationUnit TU){
7142 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007143 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007144 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007145 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007146
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007147 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007148 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007149 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007150 if (MD) {
7151 for (MacroDirective::DefInfo
7152 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7153 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7154 return Def.getMacroInfo();
7155 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007156 }
7157
Craig Topper69186e72014-06-08 08:38:04 +00007158 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007159}
7160
Richard Smith66a81862015-05-04 02:25:31 +00007161const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007162 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007163 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007164 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007165 const IdentifierInfo *II = MacroDef->getName();
7166 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007167 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007168
7169 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7170}
7171
Richard Smith66a81862015-05-04 02:25:31 +00007172MacroDefinitionRecord *
7173cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7174 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007175 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007176 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007177 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007178 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007179
7180 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007181 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007182 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7183 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007184 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007185
7186 // Check that the token is inside the definition and not its argument list.
7187 SourceManager &SM = Unit->getSourceManager();
7188 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007189 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007190 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007191 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007192
7193 Preprocessor &PP = Unit->getPreprocessor();
7194 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7195 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007196 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007197
Alp Toker2d57cea2014-05-17 04:53:25 +00007198 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007199 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007200 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007201
7202 // Check that the identifier is not one of the macro arguments.
7203 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007204 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007205
Richard Smith20e883e2015-04-29 23:20:19 +00007206 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007207 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007208 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007209
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007210 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007211}
7212
Richard Smith66a81862015-05-04 02:25:31 +00007213MacroDefinitionRecord *
7214cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7215 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007216 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007217 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007218
7219 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007220 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007221 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007222 Preprocessor &PP = Unit->getPreprocessor();
7223 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007224 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007225 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7226 Token Tok;
7227 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007228 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007229
7230 return checkForMacroInMacroDefinition(MI, Tok, TU);
7231}
7232
Guy Benyei11169dd2012-12-18 14:30:41 +00007233extern "C" {
7234
7235CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007236 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007237}
7238
7239} // end: extern "C"
7240
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007241Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7242 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007243 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007244 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007245 if (Unit->isMainFileAST())
7246 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007247 return *this;
7248 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007249 } else {
7250 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007251 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007252 return *this;
7253}
7254
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007255Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7256 *this << FE->getName();
7257 return *this;
7258}
7259
7260Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7261 CXString cursorName = clang_getCursorDisplayName(cursor);
7262 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7263 clang_disposeString(cursorName);
7264 return *this;
7265}
7266
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007267Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7268 CXFile File;
7269 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007270 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007271 CXString FileName = clang_getFileName(File);
7272 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7273 clang_disposeString(FileName);
7274 return *this;
7275}
7276
7277Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7278 CXSourceLocation BLoc = clang_getRangeStart(range);
7279 CXSourceLocation ELoc = clang_getRangeEnd(range);
7280
7281 CXFile BFile;
7282 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007283 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007284
7285 CXFile EFile;
7286 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007287 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007288
7289 CXString BFileName = clang_getFileName(BFile);
7290 if (BFile == EFile) {
7291 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7292 BLine, BColumn, ELine, EColumn);
7293 } else {
7294 CXString EFileName = clang_getFileName(EFile);
7295 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7296 BLine, BColumn)
7297 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7298 ELine, EColumn);
7299 clang_disposeString(EFileName);
7300 }
7301 clang_disposeString(BFileName);
7302 return *this;
7303}
7304
7305Logger &cxindex::Logger::operator<<(CXString Str) {
7306 *this << clang_getCString(Str);
7307 return *this;
7308}
7309
7310Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7311 LogOS << Fmt;
7312 return *this;
7313}
7314
Chandler Carruth37ad2582014-06-27 15:14:39 +00007315static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7316
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007317cxindex::Logger::~Logger() {
7318 LogOS.flush();
7319
Chandler Carruth37ad2582014-06-27 15:14:39 +00007320 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007321
7322 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7323
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007324 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007325 OS << "[libclang:" << Name << ':';
7326
Alp Toker1a86ad22014-07-06 06:24:00 +00007327#ifdef USE_DARWIN_THREADS
7328 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007329 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7330 OS << tid << ':';
7331#endif
7332
7333 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7334 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007335 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007336
7337 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007338 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007339 OS << "--------------------------------------------------\n";
7340 }
7341}