blob: a2467ebad4a6a961a882091ff79f6927bda02775 [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
Douglas Gregore9d95f12015-07-07 03:57:35 +00001024 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1025 return true;
1026
Guy Benyei11169dd2012-12-18 14:30:41 +00001027 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1028 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1029 E = ND->protocol_end(); I != E; ++I, ++PL)
1030 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1031 return true;
1032
1033 return VisitObjCContainerDecl(ND);
1034}
1035
1036bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1037 if (!PID->isThisDeclarationADefinition())
1038 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1039
1040 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1041 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1042 E = PID->protocol_end(); I != E; ++I, ++PL)
1043 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1044 return true;
1045
1046 return VisitObjCContainerDecl(PID);
1047}
1048
1049bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1050 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1051 return true;
1052
1053 // FIXME: This implements a workaround with @property declarations also being
1054 // installed in the DeclContext for the @interface. Eventually this code
1055 // should be removed.
1056 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1057 if (!CDecl || !CDecl->IsClassExtension())
1058 return false;
1059
1060 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1061 if (!ID)
1062 return false;
1063
1064 IdentifierInfo *PropertyId = PD->getIdentifier();
1065 ObjCPropertyDecl *prevDecl =
1066 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1067
1068 if (!prevDecl)
1069 return false;
1070
1071 // Visit synthesized methods since they will be skipped when visiting
1072 // the @interface.
1073 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1074 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1075 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1076 return true;
1077
1078 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1079 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1080 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1081 return true;
1082
1083 return false;
1084}
1085
Douglas Gregore9d95f12015-07-07 03:57:35 +00001086bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1087 if (!typeParamList)
1088 return false;
1089
1090 for (auto *typeParam : *typeParamList) {
1091 // Visit the type parameter.
1092 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1093 return true;
1094
1095 // Visit the bound, if it's explicit.
1096 if (typeParam->hasExplicitBound()) {
1097 if (auto TInfo = typeParam->getTypeSourceInfo()) {
1098 if (Visit(TInfo->getTypeLoc()))
1099 return true;
1100 }
1101 }
1102 }
1103
1104 return false;
1105}
1106
Guy Benyei11169dd2012-12-18 14:30:41 +00001107bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1108 if (!D->isThisDeclarationADefinition()) {
1109 // Forward declaration is treated like a reference.
1110 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1111 }
1112
Douglas Gregore9d95f12015-07-07 03:57:35 +00001113 // Objective-C type parameters.
1114 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1115 return true;
1116
Guy Benyei11169dd2012-12-18 14:30:41 +00001117 // Issue callbacks for super class.
1118 if (D->getSuperClass() &&
1119 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1120 D->getSuperClassLoc(),
1121 TU)))
1122 return true;
1123
Douglas Gregore9d95f12015-07-07 03:57:35 +00001124 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1125 if (Visit(SuperClassTInfo->getTypeLoc()))
1126 return true;
1127
Guy Benyei11169dd2012-12-18 14:30:41 +00001128 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1129 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1130 E = D->protocol_end(); I != E; ++I, ++PL)
1131 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1132 return true;
1133
1134 return VisitObjCContainerDecl(D);
1135}
1136
1137bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1138 return VisitObjCContainerDecl(D);
1139}
1140
1141bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1142 // 'ID' could be null when dealing with invalid code.
1143 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1144 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1145 return true;
1146
1147 return VisitObjCImplDecl(D);
1148}
1149
1150bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1151#if 0
1152 // Issue callbacks for super class.
1153 // FIXME: No source location information!
1154 if (D->getSuperClass() &&
1155 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1156 D->getSuperClassLoc(),
1157 TU)))
1158 return true;
1159#endif
1160
1161 return VisitObjCImplDecl(D);
1162}
1163
1164bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1165 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1166 if (PD->isIvarNameSpecified())
1167 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1168
1169 return false;
1170}
1171
1172bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1173 return VisitDeclContext(D);
1174}
1175
1176bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1177 // Visit nested-name-specifier.
1178 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1179 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1180 return true;
1181
1182 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1183 D->getTargetNameLoc(), TU));
1184}
1185
1186bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1187 // Visit nested-name-specifier.
1188 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1189 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1190 return true;
1191 }
1192
1193 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1194 return true;
1195
1196 return VisitDeclarationNameInfo(D->getNameInfo());
1197}
1198
1199bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1200 // Visit nested-name-specifier.
1201 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1202 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1203 return true;
1204
1205 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1206 D->getIdentLocation(), TU));
1207}
1208
1209bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1210 // Visit nested-name-specifier.
1211 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1212 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1213 return true;
1214 }
1215
1216 return VisitDeclarationNameInfo(D->getNameInfo());
1217}
1218
1219bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1220 UnresolvedUsingTypenameDecl *D) {
1221 // Visit nested-name-specifier.
1222 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1223 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1224 return true;
1225
1226 return false;
1227}
1228
1229bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1230 switch (Name.getName().getNameKind()) {
1231 case clang::DeclarationName::Identifier:
1232 case clang::DeclarationName::CXXLiteralOperatorName:
1233 case clang::DeclarationName::CXXOperatorName:
1234 case clang::DeclarationName::CXXUsingDirective:
1235 return false;
1236
1237 case clang::DeclarationName::CXXConstructorName:
1238 case clang::DeclarationName::CXXDestructorName:
1239 case clang::DeclarationName::CXXConversionFunctionName:
1240 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1241 return Visit(TSInfo->getTypeLoc());
1242 return false;
1243
1244 case clang::DeclarationName::ObjCZeroArgSelector:
1245 case clang::DeclarationName::ObjCOneArgSelector:
1246 case clang::DeclarationName::ObjCMultiArgSelector:
1247 // FIXME: Per-identifier location info?
1248 return false;
1249 }
1250
1251 llvm_unreachable("Invalid DeclarationName::Kind!");
1252}
1253
1254bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1255 SourceRange Range) {
1256 // FIXME: This whole routine is a hack to work around the lack of proper
1257 // source information in nested-name-specifiers (PR5791). Since we do have
1258 // a beginning source location, we can visit the first component of the
1259 // nested-name-specifier, if it's a single-token component.
1260 if (!NNS)
1261 return false;
1262
1263 // Get the first component in the nested-name-specifier.
1264 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1265 NNS = Prefix;
1266
1267 switch (NNS->getKind()) {
1268 case NestedNameSpecifier::Namespace:
1269 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1270 TU));
1271
1272 case NestedNameSpecifier::NamespaceAlias:
1273 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1274 Range.getBegin(), TU));
1275
1276 case NestedNameSpecifier::TypeSpec: {
1277 // If the type has a form where we know that the beginning of the source
1278 // range matches up with a reference cursor. Visit the appropriate reference
1279 // cursor.
1280 const Type *T = NNS->getAsType();
1281 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1282 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1283 if (const TagType *Tag = dyn_cast<TagType>(T))
1284 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1285 if (const TemplateSpecializationType *TST
1286 = dyn_cast<TemplateSpecializationType>(T))
1287 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1288 break;
1289 }
1290
1291 case NestedNameSpecifier::TypeSpecWithTemplate:
1292 case NestedNameSpecifier::Global:
1293 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001294 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001295 break;
1296 }
1297
1298 return false;
1299}
1300
1301bool
1302CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1303 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1304 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1305 Qualifiers.push_back(Qualifier);
1306
1307 while (!Qualifiers.empty()) {
1308 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1309 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1310 switch (NNS->getKind()) {
1311 case NestedNameSpecifier::Namespace:
1312 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1313 Q.getLocalBeginLoc(),
1314 TU)))
1315 return true;
1316
1317 break;
1318
1319 case NestedNameSpecifier::NamespaceAlias:
1320 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1321 Q.getLocalBeginLoc(),
1322 TU)))
1323 return true;
1324
1325 break;
1326
1327 case NestedNameSpecifier::TypeSpec:
1328 case NestedNameSpecifier::TypeSpecWithTemplate:
1329 if (Visit(Q.getTypeLoc()))
1330 return true;
1331
1332 break;
1333
1334 case NestedNameSpecifier::Global:
1335 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001336 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001337 break;
1338 }
1339 }
1340
1341 return false;
1342}
1343
1344bool CursorVisitor::VisitTemplateParameters(
1345 const TemplateParameterList *Params) {
1346 if (!Params)
1347 return false;
1348
1349 for (TemplateParameterList::const_iterator P = Params->begin(),
1350 PEnd = Params->end();
1351 P != PEnd; ++P) {
1352 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1353 return true;
1354 }
1355
1356 return false;
1357}
1358
1359bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1360 switch (Name.getKind()) {
1361 case TemplateName::Template:
1362 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1363
1364 case TemplateName::OverloadedTemplate:
1365 // Visit the overloaded template set.
1366 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1367 return true;
1368
1369 return false;
1370
1371 case TemplateName::DependentTemplate:
1372 // FIXME: Visit nested-name-specifier.
1373 return false;
1374
1375 case TemplateName::QualifiedTemplate:
1376 // FIXME: Visit nested-name-specifier.
1377 return Visit(MakeCursorTemplateRef(
1378 Name.getAsQualifiedTemplateName()->getDecl(),
1379 Loc, TU));
1380
1381 case TemplateName::SubstTemplateTemplateParm:
1382 return Visit(MakeCursorTemplateRef(
1383 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1384 Loc, TU));
1385
1386 case TemplateName::SubstTemplateTemplateParmPack:
1387 return Visit(MakeCursorTemplateRef(
1388 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1389 Loc, TU));
1390 }
1391
1392 llvm_unreachable("Invalid TemplateName::Kind!");
1393}
1394
1395bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1396 switch (TAL.getArgument().getKind()) {
1397 case TemplateArgument::Null:
1398 case TemplateArgument::Integral:
1399 case TemplateArgument::Pack:
1400 return false;
1401
1402 case TemplateArgument::Type:
1403 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1404 return Visit(TSInfo->getTypeLoc());
1405 return false;
1406
1407 case TemplateArgument::Declaration:
1408 if (Expr *E = TAL.getSourceDeclExpression())
1409 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1410 return false;
1411
1412 case TemplateArgument::NullPtr:
1413 if (Expr *E = TAL.getSourceNullPtrExpression())
1414 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1415 return false;
1416
1417 case TemplateArgument::Expression:
1418 if (Expr *E = TAL.getSourceExpression())
1419 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1420 return false;
1421
1422 case TemplateArgument::Template:
1423 case TemplateArgument::TemplateExpansion:
1424 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1425 return true;
1426
1427 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1428 TAL.getTemplateNameLoc());
1429 }
1430
1431 llvm_unreachable("Invalid TemplateArgument::Kind!");
1432}
1433
1434bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1435 return VisitDeclContext(D);
1436}
1437
1438bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1439 return Visit(TL.getUnqualifiedLoc());
1440}
1441
1442bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1443 ASTContext &Context = AU->getASTContext();
1444
1445 // Some builtin types (such as Objective-C's "id", "sel", and
1446 // "Class") have associated declarations. Create cursors for those.
1447 QualType VisitType;
1448 switch (TL.getTypePtr()->getKind()) {
1449
1450 case BuiltinType::Void:
1451 case BuiltinType::NullPtr:
1452 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001453 case BuiltinType::OCLImage1d:
1454 case BuiltinType::OCLImage1dArray:
1455 case BuiltinType::OCLImage1dBuffer:
1456 case BuiltinType::OCLImage2d:
1457 case BuiltinType::OCLImage2dArray:
1458 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001459 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001460 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001461#define BUILTIN_TYPE(Id, SingletonId)
1462#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1463#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1464#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1465#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1466#include "clang/AST/BuiltinTypes.def"
1467 break;
1468
1469 case BuiltinType::ObjCId:
1470 VisitType = Context.getObjCIdType();
1471 break;
1472
1473 case BuiltinType::ObjCClass:
1474 VisitType = Context.getObjCClassType();
1475 break;
1476
1477 case BuiltinType::ObjCSel:
1478 VisitType = Context.getObjCSelType();
1479 break;
1480 }
1481
1482 if (!VisitType.isNull()) {
1483 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1484 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1485 TU));
1486 }
1487
1488 return false;
1489}
1490
1491bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1492 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1493}
1494
1495bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1496 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1497}
1498
1499bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1500 if (TL.isDefinition())
1501 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1502
1503 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1504}
1505
1506bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1507 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1508}
1509
1510bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1511 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1512 return true;
1513
1514 return false;
1515}
1516
1517bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1518 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1519 return true;
1520
Douglas Gregore9d95f12015-07-07 03:57:35 +00001521 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1522 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1523 return true;
1524 }
1525
Guy Benyei11169dd2012-12-18 14:30:41 +00001526 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1527 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1528 TU)))
1529 return true;
1530 }
1531
1532 return false;
1533}
1534
1535bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1536 return Visit(TL.getPointeeLoc());
1537}
1538
1539bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1540 return Visit(TL.getInnerLoc());
1541}
1542
1543bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1544 return Visit(TL.getPointeeLoc());
1545}
1546
1547bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1548 return Visit(TL.getPointeeLoc());
1549}
1550
1551bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1552 return Visit(TL.getPointeeLoc());
1553}
1554
1555bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1556 return Visit(TL.getPointeeLoc());
1557}
1558
1559bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1560 return Visit(TL.getPointeeLoc());
1561}
1562
1563bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1564 return Visit(TL.getModifiedLoc());
1565}
1566
1567bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1568 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001569 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001570 return true;
1571
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001572 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1573 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001574 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1575 return true;
1576
1577 return false;
1578}
1579
1580bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1581 if (Visit(TL.getElementLoc()))
1582 return true;
1583
1584 if (Expr *Size = TL.getSizeExpr())
1585 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1586
1587 return false;
1588}
1589
Reid Kleckner8a365022013-06-24 17:51:48 +00001590bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1591 return Visit(TL.getOriginalLoc());
1592}
1593
Reid Kleckner0503a872013-12-05 01:23:43 +00001594bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1595 return Visit(TL.getOriginalLoc());
1596}
1597
Guy Benyei11169dd2012-12-18 14:30:41 +00001598bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1599 TemplateSpecializationTypeLoc TL) {
1600 // Visit the template name.
1601 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1602 TL.getTemplateNameLoc()))
1603 return true;
1604
1605 // Visit the template arguments.
1606 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1607 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1608 return true;
1609
1610 return false;
1611}
1612
1613bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1614 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1615}
1616
1617bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1618 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1619 return Visit(TSInfo->getTypeLoc());
1620
1621 return false;
1622}
1623
1624bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1625 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1626 return Visit(TSInfo->getTypeLoc());
1627
1628 return false;
1629}
1630
1631bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1632 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1633 return true;
1634
1635 return false;
1636}
1637
1638bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1639 DependentTemplateSpecializationTypeLoc TL) {
1640 // Visit the nested-name-specifier, if there is one.
1641 if (TL.getQualifierLoc() &&
1642 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1643 return true;
1644
1645 // Visit the template arguments.
1646 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1647 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1648 return true;
1649
1650 return false;
1651}
1652
1653bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1654 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1655 return true;
1656
1657 return Visit(TL.getNamedTypeLoc());
1658}
1659
1660bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1661 return Visit(TL.getPatternLoc());
1662}
1663
1664bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1665 if (Expr *E = TL.getUnderlyingExpr())
1666 return Visit(MakeCXCursor(E, StmtParent, TU));
1667
1668 return false;
1669}
1670
1671bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1672 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1673}
1674
1675bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1676 return Visit(TL.getValueLoc());
1677}
1678
1679#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1680bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1681 return Visit##PARENT##Loc(TL); \
1682}
1683
1684DEFAULT_TYPELOC_IMPL(Complex, Type)
1685DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1686DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1687DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1688DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1689DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1690DEFAULT_TYPELOC_IMPL(Vector, Type)
1691DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1692DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1693DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1694DEFAULT_TYPELOC_IMPL(Record, TagType)
1695DEFAULT_TYPELOC_IMPL(Enum, TagType)
1696DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1697DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1698DEFAULT_TYPELOC_IMPL(Auto, Type)
1699
1700bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1701 // Visit the nested-name-specifier, if present.
1702 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1703 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1704 return true;
1705
1706 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001707 for (const auto &I : D->bases()) {
1708 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001709 return true;
1710 }
1711 }
1712
1713 return VisitTagDecl(D);
1714}
1715
1716bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001717 for (const auto *I : D->attrs())
1718 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001719 return true;
1720
1721 return false;
1722}
1723
1724//===----------------------------------------------------------------------===//
1725// Data-recursive visitor methods.
1726//===----------------------------------------------------------------------===//
1727
1728namespace {
1729#define DEF_JOB(NAME, DATA, KIND)\
1730class NAME : public VisitorJob {\
1731public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001732 NAME(const DATA *d, CXCursor parent) : \
1733 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001734 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001735 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001736};
1737
1738DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1739DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1740DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1741DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1742DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1743 ExplicitTemplateArgsVisitKind)
1744DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1745DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1746DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1747#undef DEF_JOB
1748
1749class DeclVisit : public VisitorJob {
1750public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001751 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001752 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001753 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001754 static bool classof(const VisitorJob *VJ) {
1755 return VJ->getKind() == DeclVisitKind;
1756 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001757 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001758 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001759};
1760class TypeLocVisit : public VisitorJob {
1761public:
1762 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1763 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1764 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1765
1766 static bool classof(const VisitorJob *VJ) {
1767 return VJ->getKind() == TypeLocVisitKind;
1768 }
1769
1770 TypeLoc get() const {
1771 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001772 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 }
1774};
1775
1776class LabelRefVisit : public VisitorJob {
1777public:
1778 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1779 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1780 labelLoc.getPtrEncoding()) {}
1781
1782 static bool classof(const VisitorJob *VJ) {
1783 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1784 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001785 const LabelDecl *get() const {
1786 return static_cast<const LabelDecl *>(data[0]);
1787 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001788 SourceLocation getLoc() const {
1789 return SourceLocation::getFromPtrEncoding(data[1]); }
1790};
1791
1792class NestedNameSpecifierLocVisit : public VisitorJob {
1793public:
1794 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1795 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1796 Qualifier.getNestedNameSpecifier(),
1797 Qualifier.getOpaqueData()) { }
1798
1799 static bool classof(const VisitorJob *VJ) {
1800 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1801 }
1802
1803 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804 return NestedNameSpecifierLoc(
1805 const_cast<NestedNameSpecifier *>(
1806 static_cast<const NestedNameSpecifier *>(data[0])),
1807 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001808 }
1809};
1810
1811class DeclarationNameInfoVisit : public VisitorJob {
1812public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001814 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001815 static bool classof(const VisitorJob *VJ) {
1816 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1817 }
1818 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001819 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001820 switch (S->getStmtClass()) {
1821 default:
1822 llvm_unreachable("Unhandled Stmt");
1823 case clang::Stmt::MSDependentExistsStmtClass:
1824 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1825 case Stmt::CXXDependentScopeMemberExprClass:
1826 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1827 case Stmt::DependentScopeDeclRefExprClass:
1828 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001829 case Stmt::OMPCriticalDirectiveClass:
1830 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001831 }
1832 }
1833};
1834class MemberRefVisit : public VisitorJob {
1835public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001836 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001837 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1838 L.getPtrEncoding()) {}
1839 static bool classof(const VisitorJob *VJ) {
1840 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1841 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001842 const FieldDecl *get() const {
1843 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001844 }
1845 SourceLocation getLoc() const {
1846 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1847 }
1848};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001849class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001850 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001851 VisitorWorkList &WL;
1852 CXCursor Parent;
1853public:
1854 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1855 : WL(wl), Parent(parent) {}
1856
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001857 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1858 void VisitBlockExpr(const BlockExpr *B);
1859 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1860 void VisitCompoundStmt(const CompoundStmt *S);
1861 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1862 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1863 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1864 void VisitCXXNewExpr(const CXXNewExpr *E);
1865 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1866 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1867 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1868 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1869 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1870 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1871 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1872 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001873 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001874 void VisitDeclRefExpr(const DeclRefExpr *D);
1875 void VisitDeclStmt(const DeclStmt *S);
1876 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1877 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1878 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1879 void VisitForStmt(const ForStmt *FS);
1880 void VisitGotoStmt(const GotoStmt *GS);
1881 void VisitIfStmt(const IfStmt *If);
1882 void VisitInitListExpr(const InitListExpr *IE);
1883 void VisitMemberExpr(const MemberExpr *M);
1884 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1885 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1886 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1887 void VisitOverloadExpr(const OverloadExpr *E);
1888 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1889 void VisitStmt(const Stmt *S);
1890 void VisitSwitchStmt(const SwitchStmt *S);
1891 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1893 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1894 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1895 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1896 void VisitVAArgExpr(const VAArgExpr *E);
1897 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1898 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1899 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1900 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001901 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001902 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001903 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001904 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001905 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001906 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001907 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001908 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001909 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001910 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001911 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001912 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001913 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001914 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001915 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001916 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001917 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001918 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001919 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001920 void
1921 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001922 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001923 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001924 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001925 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001926 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001927 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001928
Guy Benyei11169dd2012-12-18 14:30:41 +00001929private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001930 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001931 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1932 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001933 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1934 void AddStmt(const Stmt *S);
1935 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001936 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001937 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001938 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001939};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001940} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001941
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001942void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001943 // 'S' should always be non-null, since it comes from the
1944 // statement we are visiting.
1945 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1946}
1947
1948void
1949EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1950 if (Qualifier)
1951 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1952}
1953
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001954void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001955 if (S)
1956 WL.push_back(StmtVisit(S, Parent));
1957}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001958void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001959 if (D)
1960 WL.push_back(DeclVisit(D, Parent, isFirst));
1961}
1962void EnqueueVisitor::
1963 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1964 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001965 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001966}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001967void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001968 if (D)
1969 WL.push_back(MemberRefVisit(D, L, Parent));
1970}
1971void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1972 if (TI)
1973 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1974 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001977 for (const Stmt *SubStmt : S->children()) {
1978 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 }
1980 if (size == WL.size())
1981 return;
1982 // Now reverse the entries we just added. This will match the DFS
1983 // ordering performed by the worklist.
1984 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1985 std::reverse(I, E);
1986}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001987namespace {
1988class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1989 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001990 /// \brief Process clauses with list of variables.
1991 template <typename T>
1992 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001993public:
1994 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1995#define OPENMP_CLAUSE(Name, Class) \
1996 void Visit##Class(const Class *C);
1997#include "clang/Basic/OpenMPKinds.def"
1998};
1999
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002000void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2001 Visitor->AddStmt(C->getCondition());
2002}
2003
Alexey Bataev3778b602014-07-17 07:32:53 +00002004void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2005 Visitor->AddStmt(C->getCondition());
2006}
2007
Alexey Bataev568a8332014-03-06 06:15:19 +00002008void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2009 Visitor->AddStmt(C->getNumThreads());
2010}
2011
Alexey Bataev62c87d22014-03-21 04:51:18 +00002012void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2013 Visitor->AddStmt(C->getSafelen());
2014}
2015
Alexander Musman8bd31e62014-05-27 15:12:19 +00002016void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2017 Visitor->AddStmt(C->getNumForLoops());
2018}
2019
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002020void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002021
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002022void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2023
Alexey Bataev56dafe82014-06-20 07:16:17 +00002024void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2025 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002026 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002027}
2028
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002029void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
2030
Alexey Bataev236070f2014-06-20 11:19:47 +00002031void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2032
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002033void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2034
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002035void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2036
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002037void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2038
Alexey Bataevdea47612014-07-23 07:46:59 +00002039void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2040
Alexey Bataev67a4f222014-07-23 10:25:33 +00002041void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2042
Alexey Bataev459dec02014-07-24 06:46:57 +00002043void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2044
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002045void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2046
Alexey Bataev756c1962013-09-24 03:17:45 +00002047template<typename T>
2048void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002049 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002050 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002051 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002052}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002053
2054void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002055 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002056 for (const auto *E : C->private_copies()) {
2057 Visitor->AddStmt(E);
2058 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002059}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002060void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2061 const OMPFirstprivateClause *C) {
2062 VisitOMPClauseList(C);
2063}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002064void OMPClauseEnqueue::VisitOMPLastprivateClause(
2065 const OMPLastprivateClause *C) {
2066 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002067 for (auto *E : C->private_copies()) {
2068 Visitor->AddStmt(E);
2069 }
2070 for (auto *E : C->source_exprs()) {
2071 Visitor->AddStmt(E);
2072 }
2073 for (auto *E : C->destination_exprs()) {
2074 Visitor->AddStmt(E);
2075 }
2076 for (auto *E : C->assignment_ops()) {
2077 Visitor->AddStmt(E);
2078 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002079}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002080void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002081 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002082}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002083void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2084 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002085 for (auto *E : C->lhs_exprs()) {
2086 Visitor->AddStmt(E);
2087 }
2088 for (auto *E : C->rhs_exprs()) {
2089 Visitor->AddStmt(E);
2090 }
2091 for (auto *E : C->reduction_ops()) {
2092 Visitor->AddStmt(E);
2093 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002094}
Alexander Musman8dba6642014-04-22 13:09:42 +00002095void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2096 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002097 for (const auto *E : C->inits()) {
2098 Visitor->AddStmt(E);
2099 }
2100 for (const auto *E : C->updates()) {
2101 Visitor->AddStmt(E);
2102 }
2103 for (const auto *E : C->finals()) {
2104 Visitor->AddStmt(E);
2105 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002106 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002107 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002108}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002109void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2110 VisitOMPClauseList(C);
2111 Visitor->AddStmt(C->getAlignment());
2112}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002113void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2114 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002115 for (auto *E : C->source_exprs()) {
2116 Visitor->AddStmt(E);
2117 }
2118 for (auto *E : C->destination_exprs()) {
2119 Visitor->AddStmt(E);
2120 }
2121 for (auto *E : C->assignment_ops()) {
2122 Visitor->AddStmt(E);
2123 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002124}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002125void
2126OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2127 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002128 for (auto *E : C->source_exprs()) {
2129 Visitor->AddStmt(E);
2130 }
2131 for (auto *E : C->destination_exprs()) {
2132 Visitor->AddStmt(E);
2133 }
2134 for (auto *E : C->assignment_ops()) {
2135 Visitor->AddStmt(E);
2136 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002137}
Alexey Bataev6125da92014-07-21 11:26:11 +00002138void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2139 VisitOMPClauseList(C);
2140}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002141void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2142 VisitOMPClauseList(C);
2143}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002144}
Alexey Bataev756c1962013-09-24 03:17:45 +00002145
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002146void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2147 unsigned size = WL.size();
2148 OMPClauseEnqueue Visitor(this);
2149 Visitor.Visit(S);
2150 if (size == WL.size())
2151 return;
2152 // Now reverse the entries we just added. This will match the DFS
2153 // ordering performed by the worklist.
2154 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2155 std::reverse(I, E);
2156}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002157void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002158 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2159}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002160void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002161 AddDecl(B->getBlockDecl());
2162}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 EnqueueChildren(E);
2165 AddTypeLoc(E->getTypeSourceInfo());
2166}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002167void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2168 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 E = S->body_rend(); I != E; ++I) {
2170 AddStmt(*I);
2171 }
2172}
2173void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 AddStmt(S->getSubStmt());
2176 AddDeclarationNameInfo(S);
2177 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2178 AddNestedNameSpecifierLoc(QualifierLoc);
2179}
2180
2181void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2184 AddDeclarationNameInfo(E);
2185 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2186 AddNestedNameSpecifierLoc(QualifierLoc);
2187 if (!E->isImplicitAccess())
2188 AddStmt(E->getBase());
2189}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 // Enqueue the initializer , if any.
2192 AddStmt(E->getInitializer());
2193 // Enqueue the array size, if any.
2194 AddStmt(E->getArraySize());
2195 // Enqueue the allocated type.
2196 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2197 // Enqueue the placement arguments.
2198 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2199 AddStmt(E->getPlacementArg(I-1));
2200}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002201void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002202 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2203 AddStmt(CE->getArg(I-1));
2204 AddStmt(CE->getCallee());
2205 AddStmt(CE->getArg(0));
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2208 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 // Visit the name of the type being destroyed.
2210 AddTypeLoc(E->getDestroyedTypeInfo());
2211 // Visit the scope type that looks disturbingly like the nested-name-specifier
2212 // but isn't.
2213 AddTypeLoc(E->getScopeTypeInfo());
2214 // Visit the nested-name-specifier.
2215 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2216 AddNestedNameSpecifierLoc(QualifierLoc);
2217 // Visit base expression.
2218 AddStmt(E->getBase());
2219}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2221 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 AddTypeLoc(E->getTypeSourceInfo());
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2225 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 EnqueueChildren(E);
2227 AddTypeLoc(E->getTypeSourceInfo());
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 EnqueueChildren(E);
2231 if (E->isTypeOperand())
2232 AddTypeLoc(E->getTypeOperandSourceInfo());
2233}
2234
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2236 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 EnqueueChildren(E);
2238 AddTypeLoc(E->getTypeSourceInfo());
2239}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002240void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 EnqueueChildren(E);
2242 if (E->isTypeOperand())
2243 AddTypeLoc(E->getTypeOperandSourceInfo());
2244}
2245
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002246void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002247 EnqueueChildren(S);
2248 AddDecl(S->getExceptionDecl());
2249}
2250
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002251void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002252 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002253 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002254 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002255}
2256
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 if (DR->hasExplicitTemplateArgs()) {
2259 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2260 }
2261 WL.push_back(DeclRefExprParts(DR, Parent));
2262}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2264 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2266 AddDeclarationNameInfo(E);
2267 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 unsigned size = WL.size();
2271 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002272 for (const auto *D : S->decls()) {
2273 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 isFirst = false;
2275 }
2276 if (size == WL.size())
2277 return;
2278 // Now reverse the entries we just added. This will match the DFS
2279 // ordering performed by the worklist.
2280 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2281 std::reverse(I, E);
2282}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002283void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 D = E->designators_rbegin(), DEnd = E->designators_rend();
2287 D != DEnd; ++D) {
2288 if (D->isFieldDesignator()) {
2289 if (FieldDecl *Field = D->getField())
2290 AddMemberRef(Field, D->getFieldLoc());
2291 continue;
2292 }
2293 if (D->isArrayDesignator()) {
2294 AddStmt(E->getArrayIndex(*D));
2295 continue;
2296 }
2297 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2298 AddStmt(E->getArrayRangeEnd(*D));
2299 AddStmt(E->getArrayRangeStart(*D));
2300 }
2301}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002302void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 EnqueueChildren(E);
2304 AddTypeLoc(E->getTypeInfoAsWritten());
2305}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002306void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002307 AddStmt(FS->getBody());
2308 AddStmt(FS->getInc());
2309 AddStmt(FS->getCond());
2310 AddDecl(FS->getConditionVariable());
2311 AddStmt(FS->getInit());
2312}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2315}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002316void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002317 AddStmt(If->getElse());
2318 AddStmt(If->getThen());
2319 AddStmt(If->getCond());
2320 AddDecl(If->getConditionVariable());
2321}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002322void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 // We care about the syntactic form of the initializer list, only.
2324 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2325 IE = Syntactic;
2326 EnqueueChildren(IE);
2327}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002328void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002329 WL.push_back(MemberExprParts(M, Parent));
2330
2331 // If the base of the member access expression is an implicit 'this', don't
2332 // visit it.
2333 // FIXME: If we ever want to show these implicit accesses, this will be
2334 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002335 if (M->isImplicitAccess())
2336 return;
2337
2338 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2339 // real field that that we are interested in.
2340 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2341 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2342 if (FD->isAnonymousStructOrUnion()) {
2343 AddStmt(SubME->getBase());
2344 return;
2345 }
2346 }
2347 }
2348
2349 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002350}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002351void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002352 AddTypeLoc(E->getEncodedTypeSourceInfo());
2353}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002354void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002355 EnqueueChildren(M);
2356 AddTypeLoc(M->getClassReceiverTypeInfo());
2357}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002358void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002359 // Visit the components of the offsetof expression.
2360 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2361 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2362 const OffsetOfNode &Node = E->getComponent(I-1);
2363 switch (Node.getKind()) {
2364 case OffsetOfNode::Array:
2365 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2366 break;
2367 case OffsetOfNode::Field:
2368 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2369 break;
2370 case OffsetOfNode::Identifier:
2371 case OffsetOfNode::Base:
2372 continue;
2373 }
2374 }
2375 // Visit the type into which we're computing the offset.
2376 AddTypeLoc(E->getTypeSourceInfo());
2377}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002378void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002379 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2380 WL.push_back(OverloadExprParts(E, Parent));
2381}
2382void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 EnqueueChildren(E);
2385 if (E->isArgumentType())
2386 AddTypeLoc(E->getArgumentTypeInfo());
2387}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002388void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002389 EnqueueChildren(S);
2390}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002391void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002392 AddStmt(S->getBody());
2393 AddStmt(S->getCond());
2394 AddDecl(S->getConditionVariable());
2395}
2396
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 AddStmt(W->getBody());
2399 AddStmt(W->getCond());
2400 AddDecl(W->getConditionVariable());
2401}
2402
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002403void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002404 for (unsigned I = E->getNumArgs(); I > 0; --I)
2405 AddTypeLoc(E->getArg(I-1));
2406}
2407
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002408void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002409 AddTypeLoc(E->getQueriedTypeSourceInfo());
2410}
2411
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002412void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002413 EnqueueChildren(E);
2414}
2415
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 VisitOverloadExpr(U);
2418 if (!U->isImplicitAccess())
2419 AddStmt(U->getBase());
2420}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002421void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002422 AddStmt(E->getSubExpr());
2423 AddTypeLoc(E->getWrittenTypeInfo());
2424}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002425void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002426 WL.push_back(SizeOfPackExprParts(E, Parent));
2427}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002428void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002429 // If the opaque value has a source expression, just transparently
2430 // visit that. This is useful for (e.g.) pseudo-object expressions.
2431 if (Expr *SourceExpr = E->getSourceExpr())
2432 return Visit(SourceExpr);
2433}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002434void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002435 AddStmt(E->getBody());
2436 WL.push_back(LambdaExprParts(E, Parent));
2437}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 // Treat the expression like its syntactic form.
2440 Visit(E->getSyntacticForm());
2441}
2442
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002443void EnqueueVisitor::VisitOMPExecutableDirective(
2444 const OMPExecutableDirective *D) {
2445 EnqueueChildren(D);
2446 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2447 E = D->clauses().end();
2448 I != E; ++I)
2449 EnqueueChildren(*I);
2450}
2451
Alexander Musman3aaab662014-08-19 11:27:13 +00002452void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2453 VisitOMPExecutableDirective(D);
2454}
2455
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002456void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2457 VisitOMPExecutableDirective(D);
2458}
2459
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002460void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002461 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002462}
2463
Alexey Bataevf29276e2014-06-18 04:14:57 +00002464void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002465 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002466}
2467
Alexander Musmanf82886e2014-09-18 05:12:34 +00002468void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2469 VisitOMPLoopDirective(D);
2470}
2471
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002472void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2473 VisitOMPExecutableDirective(D);
2474}
2475
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002476void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2477 VisitOMPExecutableDirective(D);
2478}
2479
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002480void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2481 VisitOMPExecutableDirective(D);
2482}
2483
Alexander Musman80c22892014-07-17 08:54:58 +00002484void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2485 VisitOMPExecutableDirective(D);
2486}
2487
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002488void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2489 VisitOMPExecutableDirective(D);
2490 AddDeclarationNameInfo(D);
2491}
2492
Alexey Bataev4acb8592014-07-07 13:01:15 +00002493void
2494EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002495 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002496}
2497
Alexander Musmane4e893b2014-09-23 09:33:00 +00002498void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2499 const OMPParallelForSimdDirective *D) {
2500 VisitOMPLoopDirective(D);
2501}
2502
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002503void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2504 const OMPParallelSectionsDirective *D) {
2505 VisitOMPExecutableDirective(D);
2506}
2507
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002508void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2509 VisitOMPExecutableDirective(D);
2510}
2511
Alexey Bataev68446b72014-07-18 07:47:19 +00002512void
2513EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2514 VisitOMPExecutableDirective(D);
2515}
2516
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002517void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2518 VisitOMPExecutableDirective(D);
2519}
2520
Alexey Bataev2df347a2014-07-18 10:17:07 +00002521void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2522 VisitOMPExecutableDirective(D);
2523}
2524
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002525void EnqueueVisitor::VisitOMPTaskgroupDirective(
2526 const OMPTaskgroupDirective *D) {
2527 VisitOMPExecutableDirective(D);
2528}
2529
Alexey Bataev6125da92014-07-21 11:26:11 +00002530void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2531 VisitOMPExecutableDirective(D);
2532}
2533
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002534void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2535 VisitOMPExecutableDirective(D);
2536}
2537
Alexey Bataev0162e452014-07-22 10:10:35 +00002538void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2539 VisitOMPExecutableDirective(D);
2540}
2541
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002542void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2543 VisitOMPExecutableDirective(D);
2544}
2545
Alexey Bataev13314bf2014-10-09 04:18:56 +00002546void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2547 VisitOMPExecutableDirective(D);
2548}
2549
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002550void EnqueueVisitor::VisitOMPCancellationPointDirective(
2551 const OMPCancellationPointDirective *D) {
2552 VisitOMPExecutableDirective(D);
2553}
2554
Alexey Bataev80909872015-07-02 11:25:17 +00002555void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2556 VisitOMPExecutableDirective(D);
2557}
2558
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002559void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002560 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2561}
2562
2563bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2564 if (RegionOfInterest.isValid()) {
2565 SourceRange Range = getRawCursorExtent(C);
2566 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2567 return false;
2568 }
2569 return true;
2570}
2571
2572bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2573 while (!WL.empty()) {
2574 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002575 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002576
2577 // Set the Parent field, then back to its old value once we're done.
2578 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2579
2580 switch (LI.getKind()) {
2581 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002582 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002583 if (!D)
2584 continue;
2585
2586 // For now, perform default visitation for Decls.
2587 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2588 cast<DeclVisit>(&LI)->isFirst())))
2589 return true;
2590
2591 continue;
2592 }
2593 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2594 const ASTTemplateArgumentListInfo *ArgList =
2595 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2596 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2597 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2598 Arg != ArgEnd; ++Arg) {
2599 if (VisitTemplateArgumentLoc(*Arg))
2600 return true;
2601 }
2602 continue;
2603 }
2604 case VisitorJob::TypeLocVisitKind: {
2605 // Perform default visitation for TypeLocs.
2606 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2607 return true;
2608 continue;
2609 }
2610 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002611 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002612 if (LabelStmt *stmt = LS->getStmt()) {
2613 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2614 TU))) {
2615 return true;
2616 }
2617 }
2618 continue;
2619 }
2620
2621 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2622 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2623 if (VisitNestedNameSpecifierLoc(V->get()))
2624 return true;
2625 continue;
2626 }
2627
2628 case VisitorJob::DeclarationNameInfoVisitKind: {
2629 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2630 ->get()))
2631 return true;
2632 continue;
2633 }
2634 case VisitorJob::MemberRefVisitKind: {
2635 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2636 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2637 return true;
2638 continue;
2639 }
2640 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002641 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002642 if (!S)
2643 continue;
2644
2645 // Update the current cursor.
2646 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2647 if (!IsInRegionOfInterest(Cursor))
2648 continue;
2649 switch (Visitor(Cursor, Parent, ClientData)) {
2650 case CXChildVisit_Break: return true;
2651 case CXChildVisit_Continue: break;
2652 case CXChildVisit_Recurse:
2653 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002654 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002655 EnqueueWorkList(WL, S);
2656 break;
2657 }
2658 continue;
2659 }
2660 case VisitorJob::MemberExprPartsKind: {
2661 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002662 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002663
2664 // Visit the nested-name-specifier
2665 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2666 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2667 return true;
2668
2669 // Visit the declaration name.
2670 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2671 return true;
2672
2673 // Visit the explicitly-specified template arguments, if any.
2674 if (M->hasExplicitTemplateArgs()) {
2675 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2676 *ArgEnd = Arg + M->getNumTemplateArgs();
2677 Arg != ArgEnd; ++Arg) {
2678 if (VisitTemplateArgumentLoc(*Arg))
2679 return true;
2680 }
2681 }
2682 continue;
2683 }
2684 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002685 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002686 // Visit nested-name-specifier, if present.
2687 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2688 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2689 return true;
2690 // Visit declaration name.
2691 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2692 return true;
2693 continue;
2694 }
2695 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002696 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002697 // Visit the nested-name-specifier.
2698 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2699 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2700 return true;
2701 // Visit the declaration name.
2702 if (VisitDeclarationNameInfo(O->getNameInfo()))
2703 return true;
2704 // Visit the overloaded declaration reference.
2705 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2706 return true;
2707 continue;
2708 }
2709 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002710 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002711 NamedDecl *Pack = E->getPack();
2712 if (isa<TemplateTypeParmDecl>(Pack)) {
2713 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2714 E->getPackLoc(), TU)))
2715 return true;
2716
2717 continue;
2718 }
2719
2720 if (isa<TemplateTemplateParmDecl>(Pack)) {
2721 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2722 E->getPackLoc(), TU)))
2723 return true;
2724
2725 continue;
2726 }
2727
2728 // Non-type template parameter packs and function parameter packs are
2729 // treated like DeclRefExpr cursors.
2730 continue;
2731 }
2732
2733 case VisitorJob::LambdaExprPartsKind: {
2734 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002735 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002736 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2737 CEnd = E->explicit_capture_end();
2738 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002739 // FIXME: Lambda init-captures.
2740 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002741 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002742
Guy Benyei11169dd2012-12-18 14:30:41 +00002743 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2744 C->getLocation(),
2745 TU)))
2746 return true;
2747 }
2748
2749 // Visit parameters and return type, if present.
2750 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2751 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2752 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2753 // Visit the whole type.
2754 if (Visit(TL))
2755 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002756 } else if (FunctionProtoTypeLoc Proto =
2757 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002758 if (E->hasExplicitParameters()) {
2759 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002760 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2761 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002762 return true;
2763 } else {
2764 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002765 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002766 return true;
2767 }
2768 }
2769 }
2770 break;
2771 }
2772
2773 case VisitorJob::PostChildrenVisitKind:
2774 if (PostChildrenVisitor(Parent, ClientData))
2775 return true;
2776 break;
2777 }
2778 }
2779 return false;
2780}
2781
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002782bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002783 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002784 if (!WorkListFreeList.empty()) {
2785 WL = WorkListFreeList.back();
2786 WL->clear();
2787 WorkListFreeList.pop_back();
2788 }
2789 else {
2790 WL = new VisitorWorkList();
2791 WorkListCache.push_back(WL);
2792 }
2793 EnqueueWorkList(*WL, S);
2794 bool result = RunVisitorWorkList(*WL);
2795 WorkListFreeList.push_back(WL);
2796 return result;
2797}
2798
2799namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002800typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002801RefNamePieces
2802buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2803 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2804 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002805 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2806 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2807 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2808
2809 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2810
2811 RefNamePieces Pieces;
2812
2813 if (WantQualifier && QLoc.isValid())
2814 Pieces.push_back(QLoc);
2815
2816 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2817 Pieces.push_back(NI.getLoc());
2818
2819 if (WantTemplateArgs && TemplateArgs)
2820 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2821 TemplateArgs->RAngleLoc));
2822
2823 if (Kind == DeclarationName::CXXOperatorName) {
2824 Pieces.push_back(SourceLocation::getFromRawEncoding(
2825 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2826 Pieces.push_back(SourceLocation::getFromRawEncoding(
2827 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2828 }
2829
2830 if (WantSinglePiece) {
2831 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2832 Pieces.clear();
2833 Pieces.push_back(R);
2834 }
2835
2836 return Pieces;
2837}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002838}
Guy Benyei11169dd2012-12-18 14:30:41 +00002839
2840//===----------------------------------------------------------------------===//
2841// Misc. API hooks.
2842//===----------------------------------------------------------------------===//
2843
Chad Rosier05c71aa2013-03-27 18:28:23 +00002844static void fatal_error_handler(void *user_data, const std::string& reason,
2845 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002846 // Write the result out to stderr avoiding errs() because raw_ostreams can
2847 // call report_fatal_error.
2848 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2849 ::abort();
2850}
2851
Chandler Carruth66660742014-06-27 16:37:27 +00002852namespace {
2853struct RegisterFatalErrorHandler {
2854 RegisterFatalErrorHandler() {
2855 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2856 }
2857};
2858}
2859
2860static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2861
Guy Benyei11169dd2012-12-18 14:30:41 +00002862extern "C" {
2863CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2864 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002865 // We use crash recovery to make some of our APIs more reliable, implicitly
2866 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002867 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2868 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002869
Chandler Carruth66660742014-06-27 16:37:27 +00002870 // Look through the managed static to trigger construction of the managed
2871 // static which registers our fatal error handler. This ensures it is only
2872 // registered once.
2873 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002874
2875 CIndexer *CIdxr = new CIndexer();
2876 if (excludeDeclarationsFromPCH)
2877 CIdxr->setOnlyLocalDecls();
2878 if (displayDiagnostics)
2879 CIdxr->setDisplayDiagnostics();
2880
2881 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2882 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2883 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2884 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2885 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2886 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2887
2888 return CIdxr;
2889}
2890
2891void clang_disposeIndex(CXIndex CIdx) {
2892 if (CIdx)
2893 delete static_cast<CIndexer *>(CIdx);
2894}
2895
2896void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2897 if (CIdx)
2898 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2899}
2900
2901unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2902 if (CIdx)
2903 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2904 return 0;
2905}
2906
2907void clang_toggleCrashRecovery(unsigned isEnabled) {
2908 if (isEnabled)
2909 llvm::CrashRecoveryContext::Enable();
2910 else
2911 llvm::CrashRecoveryContext::Disable();
2912}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002913
Guy Benyei11169dd2012-12-18 14:30:41 +00002914CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2915 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002916 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002917 enum CXErrorCode Result =
2918 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002919 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002920 assert((TU && Result == CXError_Success) ||
2921 (!TU && Result != CXError_Success));
2922 return TU;
2923}
2924
2925enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2926 const char *ast_filename,
2927 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002928 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002929 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002930
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002931 if (!CIdx || !ast_filename || !out_TU)
2932 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002933
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002934 LOG_FUNC_SECTION {
2935 *Log << ast_filename;
2936 }
2937
Guy Benyei11169dd2012-12-18 14:30:41 +00002938 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2939 FileSystemOptions FileSystemOpts;
2940
Justin Bognerd512c1e2014-10-15 00:33:06 +00002941 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2942 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002943 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00002944 ast_filename, CXXIdx->getPCHContainerOperations(), Diags, FileSystemOpts,
2945 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002946 /*CaptureDiagnostics=*/true,
2947 /*AllowPCHWithCompilerErrors=*/true,
2948 /*UserFilesAreVolatile=*/true);
2949 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002950 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002951}
2952
2953unsigned clang_defaultEditingTranslationUnitOptions() {
2954 return CXTranslationUnit_PrecompiledPreamble |
2955 CXTranslationUnit_CacheCompletionResults;
2956}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002957
Guy Benyei11169dd2012-12-18 14:30:41 +00002958CXTranslationUnit
2959clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2960 const char *source_filename,
2961 int num_command_line_args,
2962 const char * const *command_line_args,
2963 unsigned num_unsaved_files,
2964 struct CXUnsavedFile *unsaved_files) {
2965 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2966 return clang_parseTranslationUnit(CIdx, source_filename,
2967 command_line_args, num_command_line_args,
2968 unsaved_files, num_unsaved_files,
2969 Options);
2970}
2971
2972struct ParseTranslationUnitInfo {
2973 CXIndex CIdx;
2974 const char *source_filename;
2975 const char *const *command_line_args;
2976 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002977 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002978 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002979 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002980 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002981};
2982static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002983 const ParseTranslationUnitInfo *PTUI =
2984 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002985 CXIndex CIdx = PTUI->CIdx;
2986 const char *source_filename = PTUI->source_filename;
2987 const char * const *command_line_args = PTUI->command_line_args;
2988 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002989 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002990 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002991
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002992 // Set up the initial return values.
2993 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002994 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002995
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002996 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002997 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002999 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003000 }
3001
Guy Benyei11169dd2012-12-18 14:30:41 +00003002 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3003
3004 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3005 setThreadBackgroundPriority();
3006
3007 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3008 // FIXME: Add a flag for modules.
3009 TranslationUnitKind TUKind
3010 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003011 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003012 = options & CXTranslationUnit_CacheCompletionResults;
3013 bool IncludeBriefCommentsInCodeCompletion
3014 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3015 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3016 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3017
3018 // Configure the diagnostics.
3019 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003020 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003021
3022 // Recover resources if we crash before exiting this function.
3023 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3024 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003025 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003026
Ahmed Charlesb8984322014-03-07 20:03:18 +00003027 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3028 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003029
3030 // Recover resources if we crash before exiting this function.
3031 llvm::CrashRecoveryContextCleanupRegistrar<
3032 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3033
Alp Toker9d85b182014-07-07 01:23:14 +00003034 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003035 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003036 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003037 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003038 }
3039
Ahmed Charlesb8984322014-03-07 20:03:18 +00003040 std::unique_ptr<std::vector<const char *>> Args(
3041 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003042
3043 // Recover resources if we crash before exiting this method.
3044 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3045 ArgsCleanup(Args.get());
3046
3047 // Since the Clang C library is primarily used by batch tools dealing with
3048 // (often very broken) source code, where spell-checking can have a
3049 // significant negative impact on performance (particularly when
3050 // precompiled headers are involved), we disable it by default.
3051 // Only do this if we haven't found a spell-checking-related argument.
3052 bool FoundSpellCheckingArgument = false;
3053 for (int I = 0; I != num_command_line_args; ++I) {
3054 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3055 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3056 FoundSpellCheckingArgument = true;
3057 break;
3058 }
3059 }
3060 if (!FoundSpellCheckingArgument)
3061 Args->push_back("-fno-spell-checking");
3062
3063 Args->insert(Args->end(), command_line_args,
3064 command_line_args + num_command_line_args);
3065
3066 // The 'source_filename' argument is optional. If the caller does not
3067 // specify it then it is assumed that the source file is specified
3068 // in the actual argument list.
3069 // Put the source file after command_line_args otherwise if '-x' flag is
3070 // present it will be unused.
3071 if (source_filename)
3072 Args->push_back(source_filename);
3073
3074 // Do we need the detailed preprocessing record?
3075 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3076 Args->push_back("-Xclang");
3077 Args->push_back("-detailed-preprocessing-record");
3078 }
3079
3080 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003081 std::unique_ptr<ASTUnit> ErrUnit;
3082 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003083 Args->data(), Args->data() + Args->size(),
3084 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003085 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3086 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3087 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3088 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3089 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3090 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003091
3092 if (NumErrors != Diags->getClient()->getNumErrors()) {
3093 // Make sure to check that 'Unit' is non-NULL.
3094 if (CXXIdx->getDisplayDiagnostics())
3095 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3096 }
3097
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003098 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3099 PTUI->result = CXError_ASTReadError;
3100 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003101 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003102 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3103 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003104}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003105
3106CXTranslationUnit
3107clang_parseTranslationUnit(CXIndex CIdx,
3108 const char *source_filename,
3109 const char *const *command_line_args,
3110 int num_command_line_args,
3111 struct CXUnsavedFile *unsaved_files,
3112 unsigned num_unsaved_files,
3113 unsigned options) {
3114 CXTranslationUnit TU;
3115 enum CXErrorCode Result = clang_parseTranslationUnit2(
3116 CIdx, source_filename, command_line_args, num_command_line_args,
3117 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003118 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003119 assert((TU && Result == CXError_Success) ||
3120 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003121 return TU;
3122}
3123
3124enum CXErrorCode clang_parseTranslationUnit2(
3125 CXIndex CIdx,
3126 const char *source_filename,
3127 const char *const *command_line_args,
3128 int num_command_line_args,
3129 struct CXUnsavedFile *unsaved_files,
3130 unsigned num_unsaved_files,
3131 unsigned options,
3132 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003133 LOG_FUNC_SECTION {
3134 *Log << source_filename << ": ";
3135 for (int i = 0; i != num_command_line_args; ++i)
3136 *Log << command_line_args[i] << " ";
3137 }
3138
Alp Toker9d85b182014-07-07 01:23:14 +00003139 if (num_unsaved_files && !unsaved_files)
3140 return CXError_InvalidArguments;
3141
Alp Toker5c532982014-07-07 22:42:03 +00003142 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003143 ParseTranslationUnitInfo PTUI = {
3144 CIdx,
3145 source_filename,
3146 command_line_args,
3147 num_command_line_args,
3148 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3149 options,
3150 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003151 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003152 llvm::CrashRecoveryContext CRC;
3153
3154 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3155 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3156 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3157 fprintf(stderr, " 'command_line_args' : [");
3158 for (int i = 0; i != num_command_line_args; ++i) {
3159 if (i)
3160 fprintf(stderr, ", ");
3161 fprintf(stderr, "'%s'", command_line_args[i]);
3162 }
3163 fprintf(stderr, "],\n");
3164 fprintf(stderr, " 'unsaved_files' : [");
3165 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3166 if (i)
3167 fprintf(stderr, ", ");
3168 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3169 unsaved_files[i].Length);
3170 }
3171 fprintf(stderr, "],\n");
3172 fprintf(stderr, " 'options' : %d,\n", options);
3173 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003174
3175 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003177 if (CXTranslationUnit *TU = PTUI.out_TU)
3178 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 }
Alp Toker5c532982014-07-07 22:42:03 +00003180
3181 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003182}
3183
3184unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3185 return CXSaveTranslationUnit_None;
3186}
3187
3188namespace {
3189
3190struct SaveTranslationUnitInfo {
3191 CXTranslationUnit TU;
3192 const char *FileName;
3193 unsigned options;
3194 CXSaveError result;
3195};
3196
3197}
3198
3199static void clang_saveTranslationUnit_Impl(void *UserData) {
3200 SaveTranslationUnitInfo *STUI =
3201 static_cast<SaveTranslationUnitInfo*>(UserData);
3202
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003203 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3205 setThreadBackgroundPriority();
3206
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003207 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3209}
3210
3211int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3212 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003213 LOG_FUNC_SECTION {
3214 *Log << TU << ' ' << FileName;
3215 }
3216
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003217 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003218 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003220 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003221
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003222 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3224 if (!CXXUnit->hasSema())
3225 return CXSaveError_InvalidTU;
3226
3227 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3228
3229 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3230 getenv("LIBCLANG_NOTHREADS")) {
3231 clang_saveTranslationUnit_Impl(&STUI);
3232
3233 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3234 PrintLibclangResourceUsage(TU);
3235
3236 return STUI.result;
3237 }
3238
3239 // We have an AST that has invalid nodes due to compiler errors.
3240 // Use a crash recovery thread for protection.
3241
3242 llvm::CrashRecoveryContext CRC;
3243
3244 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3245 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3246 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3247 fprintf(stderr, " 'options' : %d,\n", options);
3248 fprintf(stderr, "}\n");
3249
3250 return CXSaveError_Unknown;
3251
3252 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3253 PrintLibclangResourceUsage(TU);
3254 }
3255
3256 return STUI.result;
3257}
3258
3259void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3260 if (CTUnit) {
3261 // If the translation unit has been marked as unsafe to free, just discard
3262 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003263 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3264 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 return;
3266
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003267 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003268 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3270 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003271 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 delete CTUnit;
3273 }
3274}
3275
3276unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3277 return CXReparse_None;
3278}
3279
3280struct ReparseTranslationUnitInfo {
3281 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003282 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003284 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003285};
3286
3287static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003288 const ReparseTranslationUnitInfo *RTUI =
3289 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003291 unsigned options = RTUI->options;
3292 (void) options;
3293
3294 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003295 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003296 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003297 RTUI->result = CXError_InvalidArguments;
3298 return;
3299 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003300
3301 // Reset the associated diagnostics.
3302 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003303 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003304
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003305 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3307 setThreadBackgroundPriority();
3308
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003309 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003311
3312 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3313 new std::vector<ASTUnit::RemappedFile>());
3314
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 // Recover resources if we crash before exiting this function.
3316 llvm::CrashRecoveryContextCleanupRegistrar<
3317 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003318
3319 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003320 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003321 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003322 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003324
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003325 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3326 *RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003327 RTUI->result = CXError_Success;
3328 else if (isASTReadError(CXXUnit))
3329 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003330}
3331
3332int clang_reparseTranslationUnit(CXTranslationUnit TU,
3333 unsigned num_unsaved_files,
3334 struct CXUnsavedFile *unsaved_files,
3335 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003336 LOG_FUNC_SECTION {
3337 *Log << TU;
3338 }
3339
Alp Toker9d85b182014-07-07 01:23:14 +00003340 if (num_unsaved_files && !unsaved_files)
3341 return CXError_InvalidArguments;
3342
Alp Toker5c532982014-07-07 22:42:03 +00003343 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003344 ReparseTranslationUnitInfo RTUI = {
3345 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003346 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003347
3348 if (getenv("LIBCLANG_NOTHREADS")) {
3349 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003350 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 }
3352
3353 llvm::CrashRecoveryContext CRC;
3354
3355 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3356 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003357 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003358 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3360 PrintLibclangResourceUsage(TU);
3361
Alp Toker5c532982014-07-07 22:42:03 +00003362 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003363}
3364
3365
3366CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003367 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003368 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003369 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003370 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003371
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003372 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003373 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003374}
3375
3376CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003377 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003378 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003379 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003380 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003381
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003382 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3384}
3385
3386} // end: extern "C"
3387
3388//===----------------------------------------------------------------------===//
3389// CXFile Operations.
3390//===----------------------------------------------------------------------===//
3391
3392extern "C" {
3393CXString clang_getFileName(CXFile SFile) {
3394 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003395 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003396
3397 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003398 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003399}
3400
3401time_t clang_getFileTime(CXFile SFile) {
3402 if (!SFile)
3403 return 0;
3404
3405 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3406 return FEnt->getModificationTime();
3407}
3408
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003409CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003410 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003411 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003412 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003413 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003414
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003415 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003416
3417 FileManager &FMgr = CXXUnit->getFileManager();
3418 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3419}
3420
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003421unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3422 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003423 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003424 LOG_BAD_TU(TU);
3425 return 0;
3426 }
3427
3428 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 return 0;
3430
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003431 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 FileEntry *FEnt = static_cast<FileEntry *>(file);
3433 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3434 .isFileMultipleIncludeGuarded(FEnt);
3435}
3436
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003437int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3438 if (!file || !outID)
3439 return 1;
3440
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003441 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003442 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3443 outID->data[0] = ID.getDevice();
3444 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003445 outID->data[2] = FEnt->getModificationTime();
3446 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003447}
3448
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003449int clang_File_isEqual(CXFile file1, CXFile file2) {
3450 if (file1 == file2)
3451 return true;
3452
3453 if (!file1 || !file2)
3454 return false;
3455
3456 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3457 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3458 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3459}
3460
Guy Benyei11169dd2012-12-18 14:30:41 +00003461} // end: extern "C"
3462
3463//===----------------------------------------------------------------------===//
3464// CXCursor Operations.
3465//===----------------------------------------------------------------------===//
3466
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003467static const Decl *getDeclFromExpr(const Stmt *E) {
3468 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 return getDeclFromExpr(CE->getSubExpr());
3470
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003471 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003473 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003475 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003477 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 if (PRE->isExplicitProperty())
3479 return PRE->getExplicitProperty();
3480 // It could be messaging both getter and setter as in:
3481 // ++myobj.myprop;
3482 // in which case prefer to associate the setter since it is less obvious
3483 // from inspecting the source that the setter is going to get called.
3484 if (PRE->isMessagingSetter())
3485 return PRE->getImplicitPropertySetter();
3486 return PRE->getImplicitPropertyGetter();
3487 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003488 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003490 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 if (Expr *Src = OVE->getSourceExpr())
3492 return getDeclFromExpr(Src);
3493
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 if (!CE->isElidable())
3498 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003499 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 return OME->getMethodDecl();
3501
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003502 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003504 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3506 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3509 isa<ParmVarDecl>(SizeOfPack->getPack()))
3510 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003511
3512 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003513}
3514
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003515static SourceLocation getLocationFromExpr(const Expr *E) {
3516 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 return getLocationFromExpr(CE->getSubExpr());
3518
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003519 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003521 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003523 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003525 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003527 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003529 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 return PropRef->getLocation();
3531
3532 return E->getLocStart();
3533}
3534
3535extern "C" {
3536
3537unsigned clang_visitChildren(CXCursor parent,
3538 CXCursorVisitor visitor,
3539 CXClientData client_data) {
3540 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3541 /*VisitPreprocessorLast=*/false);
3542 return CursorVis.VisitChildren(parent);
3543}
3544
3545#ifndef __has_feature
3546#define __has_feature(x) 0
3547#endif
3548#if __has_feature(blocks)
3549typedef enum CXChildVisitResult
3550 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3551
3552static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3553 CXClientData client_data) {
3554 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3555 return block(cursor, parent);
3556}
3557#else
3558// If we are compiled with a compiler that doesn't have native blocks support,
3559// define and call the block manually, so the
3560typedef struct _CXChildVisitResult
3561{
3562 void *isa;
3563 int flags;
3564 int reserved;
3565 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3566 CXCursor);
3567} *CXCursorVisitorBlock;
3568
3569static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3570 CXClientData client_data) {
3571 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3572 return block->invoke(block, cursor, parent);
3573}
3574#endif
3575
3576
3577unsigned clang_visitChildrenWithBlock(CXCursor parent,
3578 CXCursorVisitorBlock block) {
3579 return clang_visitChildren(parent, visitWithBlock, block);
3580}
3581
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003582static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003584 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003585
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003586 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003587 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003588 if (const ObjCPropertyImplDecl *PropImpl =
3589 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003591 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003592
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003593 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003595 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003596
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003597 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 }
3599
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003600 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003601 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003602
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003603 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3605 // and returns different names. NamedDecl returns the class name and
3606 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003607 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003608
3609 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003610 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003611
3612 SmallString<1024> S;
3613 llvm::raw_svector_ostream os(S);
3614 ND->printName(os);
3615
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003616 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003617}
3618
3619CXString clang_getCursorSpelling(CXCursor C) {
3620 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003621 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003622
3623 if (clang_isReference(C.kind)) {
3624 switch (C.kind) {
3625 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003626 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 }
3629 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003630 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 }
3633 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003634 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 }
3638 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003639 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003640 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 }
3642 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003643 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 assert(Type && "Missing type decl");
3645
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003646 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 getAsString());
3648 }
3649 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003650 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 assert(Template && "Missing template decl");
3652
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003653 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 }
3655
3656 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003657 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 assert(NS && "Missing namespace decl");
3659
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003660 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 }
3662
3663 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003664 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 assert(Field && "Missing member decl");
3666
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003667 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 }
3669
3670 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003671 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 assert(Label && "Missing label");
3673
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 }
3676
3677 case CXCursor_OverloadedDeclRef: {
3678 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003679 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3680 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003681 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003682 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003684 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003685 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 OverloadedTemplateStorage *Ovl
3687 = Storage.get<OverloadedTemplateStorage*>();
3688 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003689 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003690 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 }
3692
3693 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003694 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 assert(Var && "Missing variable decl");
3696
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003697 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 }
3699
3700 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 }
3703 }
3704
3705 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003706 const Expr *E = getCursorExpr(C);
3707
3708 if (C.kind == CXCursor_ObjCStringLiteral ||
3709 C.kind == CXCursor_StringLiteral) {
3710 const StringLiteral *SLit;
3711 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3712 SLit = OSL->getString();
3713 } else {
3714 SLit = cast<StringLiteral>(E);
3715 }
3716 SmallString<256> Buf;
3717 llvm::raw_svector_ostream OS(Buf);
3718 SLit->outputString(OS);
3719 return cxstring::createDup(OS.str());
3720 }
3721
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003722 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 if (D)
3724 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003725 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 }
3727
3728 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003729 const Stmt *S = getCursorStmt(C);
3730 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003732
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003733 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 }
3735
3736 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 ->getNameStart());
3739
3740 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 ->getNameStart());
3743
3744 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003745 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003746
3747 if (clang_isDeclaration(C.kind))
3748 return getDeclSpelling(getCursorDecl(C));
3749
3750 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003751 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003752 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 }
3754
3755 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003756 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003757 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 }
3759
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003760 if (C.kind == CXCursor_PackedAttr) {
3761 return cxstring::createRef("packed");
3762 }
3763
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003764 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003765}
3766
3767CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3768 unsigned pieceIndex,
3769 unsigned options) {
3770 if (clang_Cursor_isNull(C))
3771 return clang_getNullRange();
3772
3773 ASTContext &Ctx = getCursorContext(C);
3774
3775 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003776 const Stmt *S = getCursorStmt(C);
3777 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 if (pieceIndex > 0)
3779 return clang_getNullRange();
3780 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3781 }
3782
3783 return clang_getNullRange();
3784 }
3785
3786 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003787 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3789 if (pieceIndex >= ME->getNumSelectorLocs())
3790 return clang_getNullRange();
3791 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3792 }
3793 }
3794
3795 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3796 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003797 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3799 if (pieceIndex >= MD->getNumSelectorLocs())
3800 return clang_getNullRange();
3801 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3802 }
3803 }
3804
3805 if (C.kind == CXCursor_ObjCCategoryDecl ||
3806 C.kind == CXCursor_ObjCCategoryImplDecl) {
3807 if (pieceIndex > 0)
3808 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003809 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3811 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003812 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3814 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3815 }
3816
3817 if (C.kind == CXCursor_ModuleImportDecl) {
3818 if (pieceIndex > 0)
3819 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003820 if (const ImportDecl *ImportD =
3821 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3823 if (!Locs.empty())
3824 return cxloc::translateSourceRange(Ctx,
3825 SourceRange(Locs.front(), Locs.back()));
3826 }
3827 return clang_getNullRange();
3828 }
3829
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003830 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3831 C.kind == CXCursor_ConversionFunction) {
3832 if (pieceIndex > 0)
3833 return clang_getNullRange();
3834 if (const FunctionDecl *FD =
3835 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3836 DeclarationNameInfo FunctionName = FD->getNameInfo();
3837 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3838 }
3839 return clang_getNullRange();
3840 }
3841
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 // FIXME: A CXCursor_InclusionDirective should give the location of the
3843 // filename, but we don't keep track of this.
3844
3845 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3846 // but we don't keep track of this.
3847
3848 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3849 // but we don't keep track of this.
3850
3851 // Default handling, give the location of the cursor.
3852
3853 if (pieceIndex > 0)
3854 return clang_getNullRange();
3855
3856 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3857 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3858 return cxloc::translateSourceRange(Ctx, Loc);
3859}
3860
Eli Bendersky44a206f2014-07-31 18:04:56 +00003861CXString clang_Cursor_getMangling(CXCursor C) {
3862 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3863 return cxstring::createEmpty();
3864
Eli Bendersky44a206f2014-07-31 18:04:56 +00003865 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003866 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003867 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3868 return cxstring::createEmpty();
3869
Eli Bendersky79759592014-08-01 15:01:10 +00003870 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003871 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003872 ASTContext &Ctx = ND->getASTContext();
3873 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003874
Eli Bendersky79759592014-08-01 15:01:10 +00003875 std::string FrontendBuf;
3876 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3877 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003878
Eli Bendersky79759592014-08-01 15:01:10 +00003879 // Now apply backend mangling.
3880 std::unique_ptr<llvm::DataLayout> DL(
3881 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
Eli Bendersky79759592014-08-01 15:01:10 +00003882
3883 std::string FinalBuf;
3884 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003885 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3886 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003887
3888 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003889}
3890
Guy Benyei11169dd2012-12-18 14:30:41 +00003891CXString clang_getCursorDisplayName(CXCursor C) {
3892 if (!clang_isDeclaration(C.kind))
3893 return clang_getCursorSpelling(C);
3894
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003895 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003897 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003898
3899 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003900 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 D = FunTmpl->getTemplatedDecl();
3902
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003903 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 SmallString<64> Str;
3905 llvm::raw_svector_ostream OS(Str);
3906 OS << *Function;
3907 if (Function->getPrimaryTemplate())
3908 OS << "<>";
3909 OS << "(";
3910 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3911 if (I)
3912 OS << ", ";
3913 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3914 }
3915
3916 if (Function->isVariadic()) {
3917 if (Function->getNumParams())
3918 OS << ", ";
3919 OS << "...";
3920 }
3921 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003922 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 }
3924
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003925 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 SmallString<64> Str;
3927 llvm::raw_svector_ostream OS(Str);
3928 OS << *ClassTemplate;
3929 OS << "<";
3930 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3931 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3932 if (I)
3933 OS << ", ";
3934
3935 NamedDecl *Param = Params->getParam(I);
3936 if (Param->getIdentifier()) {
3937 OS << Param->getIdentifier()->getName();
3938 continue;
3939 }
3940
3941 // There is no parameter name, which makes this tricky. Try to come up
3942 // with something useful that isn't too long.
3943 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3944 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3945 else if (NonTypeTemplateParmDecl *NTTP
3946 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3947 OS << NTTP->getType().getAsString(Policy);
3948 else
3949 OS << "template<...> class";
3950 }
3951
3952 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003953 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 }
3955
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003956 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3958 // If the type was explicitly written, use that.
3959 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003960 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003961
Benjamin Kramer9170e912013-02-22 15:46:01 +00003962 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 llvm::raw_svector_ostream OS(Str);
3964 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003965 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 ClassSpec->getTemplateArgs().data(),
3967 ClassSpec->getTemplateArgs().size(),
3968 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003969 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 }
3971
3972 return clang_getCursorSpelling(C);
3973}
3974
3975CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3976 switch (Kind) {
3977 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004105 case CXCursor_ObjCSelfExpr:
4106 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004195 case CXCursor_SEHLeaveStmt:
4196 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004218 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004220 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004222 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004224 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004225 case CXCursor_PackedAttr:
4226 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004227 case CXCursor_PureAttr:
4228 return cxstring::createRef("attribute(pure)");
4229 case CXCursor_ConstAttr:
4230 return cxstring::createRef("attribute(const)");
4231 case CXCursor_NoDuplicateAttr:
4232 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004233 case CXCursor_CUDAConstantAttr:
4234 return cxstring::createRef("attribute(constant)");
4235 case CXCursor_CUDADeviceAttr:
4236 return cxstring::createRef("attribute(device)");
4237 case CXCursor_CUDAGlobalAttr:
4238 return cxstring::createRef("attribute(global)");
4239 case CXCursor_CUDAHostAttr:
4240 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004241 case CXCursor_CUDASharedAttr:
4242 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004244 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004246 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004248 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004250 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004252 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004254 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004256 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004258 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004260 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004262 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004264 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004266 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004268 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004276 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004282 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004284 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004286 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004288 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004290 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004291 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004292 return cxstring::createRef("OMPParallelDirective");
4293 case CXCursor_OMPSimdDirective:
4294 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004295 case CXCursor_OMPForDirective:
4296 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004297 case CXCursor_OMPForSimdDirective:
4298 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004299 case CXCursor_OMPSectionsDirective:
4300 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004301 case CXCursor_OMPSectionDirective:
4302 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004303 case CXCursor_OMPSingleDirective:
4304 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004305 case CXCursor_OMPMasterDirective:
4306 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004307 case CXCursor_OMPCriticalDirective:
4308 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004309 case CXCursor_OMPParallelForDirective:
4310 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004311 case CXCursor_OMPParallelForSimdDirective:
4312 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004313 case CXCursor_OMPParallelSectionsDirective:
4314 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004315 case CXCursor_OMPTaskDirective:
4316 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004317 case CXCursor_OMPTaskyieldDirective:
4318 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004319 case CXCursor_OMPBarrierDirective:
4320 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004321 case CXCursor_OMPTaskwaitDirective:
4322 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004323 case CXCursor_OMPTaskgroupDirective:
4324 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004325 case CXCursor_OMPFlushDirective:
4326 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004327 case CXCursor_OMPOrderedDirective:
4328 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004329 case CXCursor_OMPAtomicDirective:
4330 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004331 case CXCursor_OMPTargetDirective:
4332 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004333 case CXCursor_OMPTeamsDirective:
4334 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004335 case CXCursor_OMPCancellationPointDirective:
4336 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004337 case CXCursor_OMPCancelDirective:
4338 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004339 case CXCursor_OverloadCandidate:
4340 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004341 }
4342
4343 llvm_unreachable("Unhandled CXCursorKind");
4344}
4345
4346struct GetCursorData {
4347 SourceLocation TokenBeginLoc;
4348 bool PointsAtMacroArgExpansion;
4349 bool VisitedObjCPropertyImplDecl;
4350 SourceLocation VisitedDeclaratorDeclStartLoc;
4351 CXCursor &BestCursor;
4352
4353 GetCursorData(SourceManager &SM,
4354 SourceLocation tokenBegin, CXCursor &outputCursor)
4355 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4356 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4357 VisitedObjCPropertyImplDecl = false;
4358 }
4359};
4360
4361static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4362 CXCursor parent,
4363 CXClientData client_data) {
4364 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4365 CXCursor *BestCursor = &Data->BestCursor;
4366
4367 // If we point inside a macro argument we should provide info of what the
4368 // token is so use the actual cursor, don't replace it with a macro expansion
4369 // cursor.
4370 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4371 return CXChildVisit_Recurse;
4372
4373 if (clang_isDeclaration(cursor.kind)) {
4374 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004375 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4377 if (MD->isImplicit())
4378 return CXChildVisit_Break;
4379
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004380 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004381 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4382 // Check that when we have multiple @class references in the same line,
4383 // that later ones do not override the previous ones.
4384 // If we have:
4385 // @class Foo, Bar;
4386 // source ranges for both start at '@', so 'Bar' will end up overriding
4387 // 'Foo' even though the cursor location was at 'Foo'.
4388 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4389 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004390 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004391 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4392 if (PrevID != ID &&
4393 !PrevID->isThisDeclarationADefinition() &&
4394 !ID->isThisDeclarationADefinition())
4395 return CXChildVisit_Break;
4396 }
4397
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004398 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4400 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4401 // Check that when we have multiple declarators in the same line,
4402 // that later ones do not override the previous ones.
4403 // If we have:
4404 // int Foo, Bar;
4405 // source ranges for both start at 'int', so 'Bar' will end up overriding
4406 // 'Foo' even though the cursor location was at 'Foo'.
4407 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4408 return CXChildVisit_Break;
4409 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4410
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004411 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004412 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4413 (void)PropImp;
4414 // Check that when we have multiple @synthesize in the same line,
4415 // that later ones do not override the previous ones.
4416 // If we have:
4417 // @synthesize Foo, Bar;
4418 // source ranges for both start at '@', so 'Bar' will end up overriding
4419 // 'Foo' even though the cursor location was at 'Foo'.
4420 if (Data->VisitedObjCPropertyImplDecl)
4421 return CXChildVisit_Break;
4422 Data->VisitedObjCPropertyImplDecl = true;
4423 }
4424 }
4425
4426 if (clang_isExpression(cursor.kind) &&
4427 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004428 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004429 // Avoid having the cursor of an expression replace the declaration cursor
4430 // when the expression source range overlaps the declaration range.
4431 // This can happen for C++ constructor expressions whose range generally
4432 // include the variable declaration, e.g.:
4433 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4434 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4435 D->getLocation() == Data->TokenBeginLoc)
4436 return CXChildVisit_Break;
4437 }
4438 }
4439
4440 // If our current best cursor is the construction of a temporary object,
4441 // don't replace that cursor with a type reference, because we want
4442 // clang_getCursor() to point at the constructor.
4443 if (clang_isExpression(BestCursor->kind) &&
4444 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4445 cursor.kind == CXCursor_TypeRef) {
4446 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4447 // as having the actual point on the type reference.
4448 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4449 return CXChildVisit_Recurse;
4450 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004451
4452 // If we already have an Objective-C superclass reference, don't
4453 // update it further.
4454 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4455 return CXChildVisit_Break;
4456
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 *BestCursor = cursor;
4458 return CXChildVisit_Recurse;
4459}
4460
4461CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004462 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004463 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004465 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004466
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004467 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4469
4470 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4471 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4472
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004473 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 CXFile SearchFile;
4475 unsigned SearchLine, SearchColumn;
4476 CXFile ResultFile;
4477 unsigned ResultLine, ResultColumn;
4478 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4479 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4480 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004481
4482 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4483 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004484 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004485 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 SearchFileName = clang_getFileName(SearchFile);
4487 ResultFileName = clang_getFileName(ResultFile);
4488 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4489 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004490 *Log << llvm::format("(%s:%d:%d) = %s",
4491 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4492 clang_getCString(KindSpelling))
4493 << llvm::format("(%s:%d:%d):%s%s",
4494 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4495 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 clang_disposeString(SearchFileName);
4497 clang_disposeString(ResultFileName);
4498 clang_disposeString(KindSpelling);
4499 clang_disposeString(USR);
4500
4501 CXCursor Definition = clang_getCursorDefinition(Result);
4502 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4503 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4504 CXString DefinitionKindSpelling
4505 = clang_getCursorKindSpelling(Definition.kind);
4506 CXFile DefinitionFile;
4507 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004508 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004509 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004511 *Log << llvm::format(" -> %s(%s:%d:%d)",
4512 clang_getCString(DefinitionKindSpelling),
4513 clang_getCString(DefinitionFileName),
4514 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 clang_disposeString(DefinitionFileName);
4516 clang_disposeString(DefinitionKindSpelling);
4517 }
4518 }
4519
4520 return Result;
4521}
4522
4523CXCursor clang_getNullCursor(void) {
4524 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4525}
4526
4527unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004528 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4529 // can't set consistently. For example, when visiting a DeclStmt we will set
4530 // it but we don't set it on the result of clang_getCursorDefinition for
4531 // a reference of the same declaration.
4532 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4533 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4534 // to provide that kind of info.
4535 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004536 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004537 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004538 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004539
Guy Benyei11169dd2012-12-18 14:30:41 +00004540 return X == Y;
4541}
4542
4543unsigned clang_hashCursor(CXCursor C) {
4544 unsigned Index = 0;
4545 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4546 Index = 1;
4547
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004548 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 std::make_pair(C.kind, C.data[Index]));
4550}
4551
4552unsigned clang_isInvalid(enum CXCursorKind K) {
4553 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4554}
4555
4556unsigned clang_isDeclaration(enum CXCursorKind K) {
4557 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4558 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4559}
4560
4561unsigned clang_isReference(enum CXCursorKind K) {
4562 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4563}
4564
4565unsigned clang_isExpression(enum CXCursorKind K) {
4566 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4567}
4568
4569unsigned clang_isStatement(enum CXCursorKind K) {
4570 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4571}
4572
4573unsigned clang_isAttribute(enum CXCursorKind K) {
4574 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4575}
4576
4577unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4578 return K == CXCursor_TranslationUnit;
4579}
4580
4581unsigned clang_isPreprocessing(enum CXCursorKind K) {
4582 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4583}
4584
4585unsigned clang_isUnexposed(enum CXCursorKind K) {
4586 switch (K) {
4587 case CXCursor_UnexposedDecl:
4588 case CXCursor_UnexposedExpr:
4589 case CXCursor_UnexposedStmt:
4590 case CXCursor_UnexposedAttr:
4591 return true;
4592 default:
4593 return false;
4594 }
4595}
4596
4597CXCursorKind clang_getCursorKind(CXCursor C) {
4598 return C.kind;
4599}
4600
4601CXSourceLocation clang_getCursorLocation(CXCursor C) {
4602 if (clang_isReference(C.kind)) {
4603 switch (C.kind) {
4604 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004605 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004606 = getCursorObjCSuperClassRef(C);
4607 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4608 }
4609
4610 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004611 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 = getCursorObjCProtocolRef(C);
4613 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4614 }
4615
4616 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004617 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 = getCursorObjCClassRef(C);
4619 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4620 }
4621
4622 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004623 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4625 }
4626
4627 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004628 std::pair<const TemplateDecl *, SourceLocation> P =
4629 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4631 }
4632
4633 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004634 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4636 }
4637
4638 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004639 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4641 }
4642
4643 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004644 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4646 }
4647
4648 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004649 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 if (!BaseSpec)
4651 return clang_getNullLocation();
4652
4653 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4654 return cxloc::translateSourceLocation(getCursorContext(C),
4655 TSInfo->getTypeLoc().getBeginLoc());
4656
4657 return cxloc::translateSourceLocation(getCursorContext(C),
4658 BaseSpec->getLocStart());
4659 }
4660
4661 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004662 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4664 }
4665
4666 case CXCursor_OverloadedDeclRef:
4667 return cxloc::translateSourceLocation(getCursorContext(C),
4668 getCursorOverloadedDeclRef(C).second);
4669
4670 default:
4671 // FIXME: Need a way to enumerate all non-reference cases.
4672 llvm_unreachable("Missed a reference kind");
4673 }
4674 }
4675
4676 if (clang_isExpression(C.kind))
4677 return cxloc::translateSourceLocation(getCursorContext(C),
4678 getLocationFromExpr(getCursorExpr(C)));
4679
4680 if (clang_isStatement(C.kind))
4681 return cxloc::translateSourceLocation(getCursorContext(C),
4682 getCursorStmt(C)->getLocStart());
4683
4684 if (C.kind == CXCursor_PreprocessingDirective) {
4685 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4686 return cxloc::translateSourceLocation(getCursorContext(C), L);
4687 }
4688
4689 if (C.kind == CXCursor_MacroExpansion) {
4690 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004691 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004692 return cxloc::translateSourceLocation(getCursorContext(C), L);
4693 }
4694
4695 if (C.kind == CXCursor_MacroDefinition) {
4696 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4697 return cxloc::translateSourceLocation(getCursorContext(C), L);
4698 }
4699
4700 if (C.kind == CXCursor_InclusionDirective) {
4701 SourceLocation L
4702 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4703 return cxloc::translateSourceLocation(getCursorContext(C), L);
4704 }
4705
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004706 if (clang_isAttribute(C.kind)) {
4707 SourceLocation L
4708 = cxcursor::getCursorAttr(C)->getLocation();
4709 return cxloc::translateSourceLocation(getCursorContext(C), L);
4710 }
4711
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 if (!clang_isDeclaration(C.kind))
4713 return clang_getNullLocation();
4714
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004715 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004716 if (!D)
4717 return clang_getNullLocation();
4718
4719 SourceLocation Loc = D->getLocation();
4720 // FIXME: Multiple variables declared in a single declaration
4721 // currently lack the information needed to correctly determine their
4722 // ranges when accounting for the type-specifier. We use context
4723 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4724 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004725 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004726 if (!cxcursor::isFirstInDeclGroup(C))
4727 Loc = VD->getLocation();
4728 }
4729
4730 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004731 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 Loc = MD->getSelectorStartLoc();
4733
4734 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4735}
4736
4737} // end extern "C"
4738
4739CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4740 assert(TU);
4741
4742 // Guard against an invalid SourceLocation, or we may assert in one
4743 // of the following calls.
4744 if (SLoc.isInvalid())
4745 return clang_getNullCursor();
4746
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004747 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004748
4749 // Translate the given source location to make it point at the beginning of
4750 // the token under the cursor.
4751 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4752 CXXUnit->getASTContext().getLangOpts());
4753
4754 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4755 if (SLoc.isValid()) {
4756 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4757 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4758 /*VisitPreprocessorLast=*/true,
4759 /*VisitIncludedEntities=*/false,
4760 SourceLocation(SLoc));
4761 CursorVis.visitFileRegion();
4762 }
4763
4764 return Result;
4765}
4766
4767static SourceRange getRawCursorExtent(CXCursor C) {
4768 if (clang_isReference(C.kind)) {
4769 switch (C.kind) {
4770 case CXCursor_ObjCSuperClassRef:
4771 return getCursorObjCSuperClassRef(C).second;
4772
4773 case CXCursor_ObjCProtocolRef:
4774 return getCursorObjCProtocolRef(C).second;
4775
4776 case CXCursor_ObjCClassRef:
4777 return getCursorObjCClassRef(C).second;
4778
4779 case CXCursor_TypeRef:
4780 return getCursorTypeRef(C).second;
4781
4782 case CXCursor_TemplateRef:
4783 return getCursorTemplateRef(C).second;
4784
4785 case CXCursor_NamespaceRef:
4786 return getCursorNamespaceRef(C).second;
4787
4788 case CXCursor_MemberRef:
4789 return getCursorMemberRef(C).second;
4790
4791 case CXCursor_CXXBaseSpecifier:
4792 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4793
4794 case CXCursor_LabelRef:
4795 return getCursorLabelRef(C).second;
4796
4797 case CXCursor_OverloadedDeclRef:
4798 return getCursorOverloadedDeclRef(C).second;
4799
4800 case CXCursor_VariableRef:
4801 return getCursorVariableRef(C).second;
4802
4803 default:
4804 // FIXME: Need a way to enumerate all non-reference cases.
4805 llvm_unreachable("Missed a reference kind");
4806 }
4807 }
4808
4809 if (clang_isExpression(C.kind))
4810 return getCursorExpr(C)->getSourceRange();
4811
4812 if (clang_isStatement(C.kind))
4813 return getCursorStmt(C)->getSourceRange();
4814
4815 if (clang_isAttribute(C.kind))
4816 return getCursorAttr(C)->getRange();
4817
4818 if (C.kind == CXCursor_PreprocessingDirective)
4819 return cxcursor::getCursorPreprocessingDirective(C);
4820
4821 if (C.kind == CXCursor_MacroExpansion) {
4822 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004823 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 return TU->mapRangeFromPreamble(Range);
4825 }
4826
4827 if (C.kind == CXCursor_MacroDefinition) {
4828 ASTUnit *TU = getCursorASTUnit(C);
4829 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4830 return TU->mapRangeFromPreamble(Range);
4831 }
4832
4833 if (C.kind == CXCursor_InclusionDirective) {
4834 ASTUnit *TU = getCursorASTUnit(C);
4835 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4836 return TU->mapRangeFromPreamble(Range);
4837 }
4838
4839 if (C.kind == CXCursor_TranslationUnit) {
4840 ASTUnit *TU = getCursorASTUnit(C);
4841 FileID MainID = TU->getSourceManager().getMainFileID();
4842 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4843 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4844 return SourceRange(Start, End);
4845 }
4846
4847 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004848 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004849 if (!D)
4850 return SourceRange();
4851
4852 SourceRange R = D->getSourceRange();
4853 // FIXME: Multiple variables declared in a single declaration
4854 // currently lack the information needed to correctly determine their
4855 // ranges when accounting for the type-specifier. We use context
4856 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4857 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004858 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 if (!cxcursor::isFirstInDeclGroup(C))
4860 R.setBegin(VD->getLocation());
4861 }
4862 return R;
4863 }
4864 return SourceRange();
4865}
4866
4867/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4868/// the decl-specifier-seq for declarations.
4869static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4870 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004871 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004872 if (!D)
4873 return SourceRange();
4874
4875 SourceRange R = D->getSourceRange();
4876
4877 // Adjust the start of the location for declarations preceded by
4878 // declaration specifiers.
4879 SourceLocation StartLoc;
4880 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4881 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4882 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004883 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4885 StartLoc = TI->getTypeLoc().getLocStart();
4886 }
4887
4888 if (StartLoc.isValid() && R.getBegin().isValid() &&
4889 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4890 R.setBegin(StartLoc);
4891
4892 // FIXME: Multiple variables declared in a single declaration
4893 // currently lack the information needed to correctly determine their
4894 // ranges when accounting for the type-specifier. We use context
4895 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4896 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004897 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004898 if (!cxcursor::isFirstInDeclGroup(C))
4899 R.setBegin(VD->getLocation());
4900 }
4901
4902 return R;
4903 }
4904
4905 return getRawCursorExtent(C);
4906}
4907
4908extern "C" {
4909
4910CXSourceRange clang_getCursorExtent(CXCursor C) {
4911 SourceRange R = getRawCursorExtent(C);
4912 if (R.isInvalid())
4913 return clang_getNullRange();
4914
4915 return cxloc::translateSourceRange(getCursorContext(C), R);
4916}
4917
4918CXCursor clang_getCursorReferenced(CXCursor C) {
4919 if (clang_isInvalid(C.kind))
4920 return clang_getNullCursor();
4921
4922 CXTranslationUnit tu = getCursorTU(C);
4923 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004924 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 if (!D)
4926 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004927 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004928 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004929 if (const ObjCPropertyImplDecl *PropImpl =
4930 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004931 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4932 return MakeCXCursor(Property, tu);
4933
4934 return C;
4935 }
4936
4937 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004938 const Expr *E = getCursorExpr(C);
4939 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004940 if (D) {
4941 CXCursor declCursor = MakeCXCursor(D, tu);
4942 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4943 declCursor);
4944 return declCursor;
4945 }
4946
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004947 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 return MakeCursorOverloadedDeclRef(Ovl, tu);
4949
4950 return clang_getNullCursor();
4951 }
4952
4953 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004954 const Stmt *S = getCursorStmt(C);
4955 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004956 if (LabelDecl *label = Goto->getLabel())
4957 if (LabelStmt *labelS = label->getStmt())
4958 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4959
4960 return clang_getNullCursor();
4961 }
Richard Smith66a81862015-05-04 02:25:31 +00004962
Guy Benyei11169dd2012-12-18 14:30:41 +00004963 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004964 if (const MacroDefinitionRecord *Def =
4965 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004966 return MakeMacroDefinitionCursor(Def, tu);
4967 }
4968
4969 if (!clang_isReference(C.kind))
4970 return clang_getNullCursor();
4971
4972 switch (C.kind) {
4973 case CXCursor_ObjCSuperClassRef:
4974 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4975
4976 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004977 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4978 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004979 return MakeCXCursor(Def, tu);
4980
4981 return MakeCXCursor(Prot, tu);
4982 }
4983
4984 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004985 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4986 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004987 return MakeCXCursor(Def, tu);
4988
4989 return MakeCXCursor(Class, tu);
4990 }
4991
4992 case CXCursor_TypeRef:
4993 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4994
4995 case CXCursor_TemplateRef:
4996 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4997
4998 case CXCursor_NamespaceRef:
4999 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5000
5001 case CXCursor_MemberRef:
5002 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5003
5004 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005005 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5007 tu ));
5008 }
5009
5010 case CXCursor_LabelRef:
5011 // FIXME: We end up faking the "parent" declaration here because we
5012 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005013 return MakeCXCursor(getCursorLabelRef(C).first,
5014 cxtu::getASTUnit(tu)->getASTContext()
5015 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005016 tu);
5017
5018 case CXCursor_OverloadedDeclRef:
5019 return C;
5020
5021 case CXCursor_VariableRef:
5022 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5023
5024 default:
5025 // We would prefer to enumerate all non-reference cursor kinds here.
5026 llvm_unreachable("Unhandled reference cursor kind");
5027 }
5028}
5029
5030CXCursor clang_getCursorDefinition(CXCursor C) {
5031 if (clang_isInvalid(C.kind))
5032 return clang_getNullCursor();
5033
5034 CXTranslationUnit TU = getCursorTU(C);
5035
5036 bool WasReference = false;
5037 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5038 C = clang_getCursorReferenced(C);
5039 WasReference = true;
5040 }
5041
5042 if (C.kind == CXCursor_MacroExpansion)
5043 return clang_getCursorReferenced(C);
5044
5045 if (!clang_isDeclaration(C.kind))
5046 return clang_getNullCursor();
5047
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005048 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 if (!D)
5050 return clang_getNullCursor();
5051
5052 switch (D->getKind()) {
5053 // Declaration kinds that don't really separate the notions of
5054 // declaration and definition.
5055 case Decl::Namespace:
5056 case Decl::Typedef:
5057 case Decl::TypeAlias:
5058 case Decl::TypeAliasTemplate:
5059 case Decl::TemplateTypeParm:
5060 case Decl::EnumConstant:
5061 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005062 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005063 case Decl::IndirectField:
5064 case Decl::ObjCIvar:
5065 case Decl::ObjCAtDefsField:
5066 case Decl::ImplicitParam:
5067 case Decl::ParmVar:
5068 case Decl::NonTypeTemplateParm:
5069 case Decl::TemplateTemplateParm:
5070 case Decl::ObjCCategoryImpl:
5071 case Decl::ObjCImplementation:
5072 case Decl::AccessSpec:
5073 case Decl::LinkageSpec:
5074 case Decl::ObjCPropertyImpl:
5075 case Decl::FileScopeAsm:
5076 case Decl::StaticAssert:
5077 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005078 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005079 case Decl::Label: // FIXME: Is this right??
5080 case Decl::ClassScopeFunctionSpecialization:
5081 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005082 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005083 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 return C;
5085
5086 // Declaration kinds that don't make any sense here, but are
5087 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005088 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005089 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005090 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005091 break;
5092
5093 // Declaration kinds for which the definition is not resolvable.
5094 case Decl::UnresolvedUsingTypename:
5095 case Decl::UnresolvedUsingValue:
5096 break;
5097
5098 case Decl::UsingDirective:
5099 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5100 TU);
5101
5102 case Decl::NamespaceAlias:
5103 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5104
5105 case Decl::Enum:
5106 case Decl::Record:
5107 case Decl::CXXRecord:
5108 case Decl::ClassTemplateSpecialization:
5109 case Decl::ClassTemplatePartialSpecialization:
5110 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5111 return MakeCXCursor(Def, TU);
5112 return clang_getNullCursor();
5113
5114 case Decl::Function:
5115 case Decl::CXXMethod:
5116 case Decl::CXXConstructor:
5117 case Decl::CXXDestructor:
5118 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005119 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005121 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 return clang_getNullCursor();
5123 }
5124
Larisse Voufo39a1e502013-08-06 01:03:05 +00005125 case Decl::Var:
5126 case Decl::VarTemplateSpecialization:
5127 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005129 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 return MakeCXCursor(Def, TU);
5131 return clang_getNullCursor();
5132 }
5133
5134 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005135 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5137 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5138 return clang_getNullCursor();
5139 }
5140
5141 case Decl::ClassTemplate: {
5142 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5143 ->getDefinition())
5144 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5145 TU);
5146 return clang_getNullCursor();
5147 }
5148
Larisse Voufo39a1e502013-08-06 01:03:05 +00005149 case Decl::VarTemplate: {
5150 if (VarDecl *Def =
5151 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5152 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5153 return clang_getNullCursor();
5154 }
5155
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 case Decl::Using:
5157 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5158 D->getLocation(), TU);
5159
5160 case Decl::UsingShadow:
5161 return clang_getCursorDefinition(
5162 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5163 TU));
5164
5165 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005166 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005167 if (Method->isThisDeclarationADefinition())
5168 return C;
5169
5170 // Dig out the method definition in the associated
5171 // @implementation, if we have it.
5172 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005173 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5175 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5176 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5177 Method->isInstanceMethod()))
5178 if (Def->isThisDeclarationADefinition())
5179 return MakeCXCursor(Def, TU);
5180
5181 return clang_getNullCursor();
5182 }
5183
5184 case Decl::ObjCCategory:
5185 if (ObjCCategoryImplDecl *Impl
5186 = cast<ObjCCategoryDecl>(D)->getImplementation())
5187 return MakeCXCursor(Impl, TU);
5188 return clang_getNullCursor();
5189
5190 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005191 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 return MakeCXCursor(Def, TU);
5193 return clang_getNullCursor();
5194
5195 case Decl::ObjCInterface: {
5196 // There are two notions of a "definition" for an Objective-C
5197 // class: the interface and its implementation. When we resolved a
5198 // reference to an Objective-C class, produce the @interface as
5199 // the definition; when we were provided with the interface,
5200 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005201 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005203 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 return MakeCXCursor(Def, TU);
5205 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5206 return MakeCXCursor(Impl, TU);
5207 return clang_getNullCursor();
5208 }
5209
5210 case Decl::ObjCProperty:
5211 // FIXME: We don't really know where to find the
5212 // ObjCPropertyImplDecls that implement this property.
5213 return clang_getNullCursor();
5214
5215 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005216 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005218 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 return MakeCXCursor(Def, TU);
5220
5221 return clang_getNullCursor();
5222
5223 case Decl::Friend:
5224 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5225 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5226 return clang_getNullCursor();
5227
5228 case Decl::FriendTemplate:
5229 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5230 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5231 return clang_getNullCursor();
5232 }
5233
5234 return clang_getNullCursor();
5235}
5236
5237unsigned clang_isCursorDefinition(CXCursor C) {
5238 if (!clang_isDeclaration(C.kind))
5239 return 0;
5240
5241 return clang_getCursorDefinition(C) == C;
5242}
5243
5244CXCursor clang_getCanonicalCursor(CXCursor C) {
5245 if (!clang_isDeclaration(C.kind))
5246 return C;
5247
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005248 if (const Decl *D = getCursorDecl(C)) {
5249 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5251 return MakeCXCursor(CatD, getCursorTU(C));
5252
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005253 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5254 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 return MakeCXCursor(IFD, getCursorTU(C));
5256
5257 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5258 }
5259
5260 return C;
5261}
5262
5263int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5264 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5265}
5266
5267unsigned clang_getNumOverloadedDecls(CXCursor C) {
5268 if (C.kind != CXCursor_OverloadedDeclRef)
5269 return 0;
5270
5271 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005272 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005273 return E->getNumDecls();
5274
5275 if (OverloadedTemplateStorage *S
5276 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5277 return S->size();
5278
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005279 const Decl *D = Storage.get<const Decl *>();
5280 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005281 return Using->shadow_size();
5282
5283 return 0;
5284}
5285
5286CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5287 if (cursor.kind != CXCursor_OverloadedDeclRef)
5288 return clang_getNullCursor();
5289
5290 if (index >= clang_getNumOverloadedDecls(cursor))
5291 return clang_getNullCursor();
5292
5293 CXTranslationUnit TU = getCursorTU(cursor);
5294 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005295 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 return MakeCXCursor(E->decls_begin()[index], TU);
5297
5298 if (OverloadedTemplateStorage *S
5299 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5300 return MakeCXCursor(S->begin()[index], TU);
5301
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005302 const Decl *D = Storage.get<const Decl *>();
5303 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 // FIXME: This is, unfortunately, linear time.
5305 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5306 std::advance(Pos, index);
5307 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5308 }
5309
5310 return clang_getNullCursor();
5311}
5312
5313void clang_getDefinitionSpellingAndExtent(CXCursor C,
5314 const char **startBuf,
5315 const char **endBuf,
5316 unsigned *startLine,
5317 unsigned *startColumn,
5318 unsigned *endLine,
5319 unsigned *endColumn) {
5320 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005321 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5323
5324 SourceManager &SM = FD->getASTContext().getSourceManager();
5325 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5326 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5327 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5328 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5329 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5330 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5331}
5332
5333
5334CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5335 unsigned PieceIndex) {
5336 RefNamePieces Pieces;
5337
5338 switch (C.kind) {
5339 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005340 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5342 E->getQualifierLoc().getSourceRange());
5343 break;
5344
5345 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005346 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5348 E->getQualifierLoc().getSourceRange(),
5349 E->getOptionalExplicitTemplateArgs());
5350 break;
5351
5352 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005353 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005355 const Expr *Callee = OCE->getCallee();
5356 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 Callee = ICE->getSubExpr();
5358
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005359 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5361 DRE->getQualifierLoc().getSourceRange());
5362 }
5363 break;
5364
5365 default:
5366 break;
5367 }
5368
5369 if (Pieces.empty()) {
5370 if (PieceIndex == 0)
5371 return clang_getCursorExtent(C);
5372 } else if (PieceIndex < Pieces.size()) {
5373 SourceRange R = Pieces[PieceIndex];
5374 if (R.isValid())
5375 return cxloc::translateSourceRange(getCursorContext(C), R);
5376 }
5377
5378 return clang_getNullRange();
5379}
5380
5381void clang_enableStackTraces(void) {
5382 llvm::sys::PrintStackTraceOnErrorSignal();
5383}
5384
5385void clang_executeOnThread(void (*fn)(void*), void *user_data,
5386 unsigned stack_size) {
5387 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5388}
5389
5390} // end: extern "C"
5391
5392//===----------------------------------------------------------------------===//
5393// Token-based Operations.
5394//===----------------------------------------------------------------------===//
5395
5396/* CXToken layout:
5397 * int_data[0]: a CXTokenKind
5398 * int_data[1]: starting token location
5399 * int_data[2]: token length
5400 * int_data[3]: reserved
5401 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5402 * otherwise unused.
5403 */
5404extern "C" {
5405
5406CXTokenKind clang_getTokenKind(CXToken CXTok) {
5407 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5408}
5409
5410CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5411 switch (clang_getTokenKind(CXTok)) {
5412 case CXToken_Identifier:
5413 case CXToken_Keyword:
5414 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005415 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005416 ->getNameStart());
5417
5418 case CXToken_Literal: {
5419 // We have stashed the starting pointer in the ptr_data field. Use it.
5420 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005421 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 }
5423
5424 case CXToken_Punctuation:
5425 case CXToken_Comment:
5426 break;
5427 }
5428
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005429 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005430 LOG_BAD_TU(TU);
5431 return cxstring::createEmpty();
5432 }
5433
Guy Benyei11169dd2012-12-18 14:30:41 +00005434 // We have to find the starting buffer pointer the hard way, by
5435 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005436 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005438 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005439
5440 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5441 std::pair<FileID, unsigned> LocInfo
5442 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5443 bool Invalid = false;
5444 StringRef Buffer
5445 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5446 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005447 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005448
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005449 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005450}
5451
5452CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005453 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005454 LOG_BAD_TU(TU);
5455 return clang_getNullLocation();
5456 }
5457
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005458 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 if (!CXXUnit)
5460 return clang_getNullLocation();
5461
5462 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5463 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5464}
5465
5466CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005467 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005468 LOG_BAD_TU(TU);
5469 return clang_getNullRange();
5470 }
5471
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005472 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 if (!CXXUnit)
5474 return clang_getNullRange();
5475
5476 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5477 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5478}
5479
5480static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5481 SmallVectorImpl<CXToken> &CXTokens) {
5482 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5483 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005484 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005486 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005487
5488 // Cannot tokenize across files.
5489 if (BeginLocInfo.first != EndLocInfo.first)
5490 return;
5491
5492 // Create a lexer
5493 bool Invalid = false;
5494 StringRef Buffer
5495 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5496 if (Invalid)
5497 return;
5498
5499 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5500 CXXUnit->getASTContext().getLangOpts(),
5501 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5502 Lex.SetCommentRetentionState(true);
5503
5504 // Lex tokens until we hit the end of the range.
5505 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5506 Token Tok;
5507 bool previousWasAt = false;
5508 do {
5509 // Lex the next token
5510 Lex.LexFromRawLexer(Tok);
5511 if (Tok.is(tok::eof))
5512 break;
5513
5514 // Initialize the CXToken.
5515 CXToken CXTok;
5516
5517 // - Common fields
5518 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5519 CXTok.int_data[2] = Tok.getLength();
5520 CXTok.int_data[3] = 0;
5521
5522 // - Kind-specific fields
5523 if (Tok.isLiteral()) {
5524 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005525 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005526 } else if (Tok.is(tok::raw_identifier)) {
5527 // Lookup the identifier to determine whether we have a keyword.
5528 IdentifierInfo *II
5529 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5530
5531 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5532 CXTok.int_data[0] = CXToken_Keyword;
5533 }
5534 else {
5535 CXTok.int_data[0] = Tok.is(tok::identifier)
5536 ? CXToken_Identifier
5537 : CXToken_Keyword;
5538 }
5539 CXTok.ptr_data = II;
5540 } else if (Tok.is(tok::comment)) {
5541 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005542 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005543 } else {
5544 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005545 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 }
5547 CXTokens.push_back(CXTok);
5548 previousWasAt = Tok.is(tok::at);
5549 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5550}
5551
5552void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5553 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005554 LOG_FUNC_SECTION {
5555 *Log << TU << ' ' << Range;
5556 }
5557
Guy Benyei11169dd2012-12-18 14:30:41 +00005558 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005559 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005560 if (NumTokens)
5561 *NumTokens = 0;
5562
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005563 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005564 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005565 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005566 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005567
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005568 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005569 if (!CXXUnit || !Tokens || !NumTokens)
5570 return;
5571
5572 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5573
5574 SourceRange R = cxloc::translateCXSourceRange(Range);
5575 if (R.isInvalid())
5576 return;
5577
5578 SmallVector<CXToken, 32> CXTokens;
5579 getTokens(CXXUnit, R, CXTokens);
5580
5581 if (CXTokens.empty())
5582 return;
5583
5584 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5585 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5586 *NumTokens = CXTokens.size();
5587}
5588
5589void clang_disposeTokens(CXTranslationUnit TU,
5590 CXToken *Tokens, unsigned NumTokens) {
5591 free(Tokens);
5592}
5593
5594} // end: extern "C"
5595
5596//===----------------------------------------------------------------------===//
5597// Token annotation APIs.
5598//===----------------------------------------------------------------------===//
5599
Guy Benyei11169dd2012-12-18 14:30:41 +00005600static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5601 CXCursor parent,
5602 CXClientData client_data);
5603static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5604 CXClientData client_data);
5605
5606namespace {
5607class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005608 CXToken *Tokens;
5609 CXCursor *Cursors;
5610 unsigned NumTokens;
5611 unsigned TokIdx;
5612 unsigned PreprocessingTokIdx;
5613 CursorVisitor AnnotateVis;
5614 SourceManager &SrcMgr;
5615 bool HasContextSensitiveKeywords;
5616
5617 struct PostChildrenInfo {
5618 CXCursor Cursor;
5619 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005620 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005621 unsigned BeforeChildrenTokenIdx;
5622 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005623 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005624
5625 CXToken &getTok(unsigned Idx) {
5626 assert(Idx < NumTokens);
5627 return Tokens[Idx];
5628 }
5629 const CXToken &getTok(unsigned Idx) const {
5630 assert(Idx < NumTokens);
5631 return Tokens[Idx];
5632 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 bool MoreTokens() const { return TokIdx < NumTokens; }
5634 unsigned NextToken() const { return TokIdx; }
5635 void AdvanceToken() { ++TokIdx; }
5636 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005637 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005638 }
5639 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005640 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005641 }
5642 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005643 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005644 }
5645
5646 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005647 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 SourceRange);
5649
5650public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005651 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005652 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005653 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005654 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005655 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005656 AnnotateTokensVisitor, this,
5657 /*VisitPreprocessorLast=*/true,
5658 /*VisitIncludedEntities=*/false,
5659 RegionOfInterest,
5660 /*VisitDeclsOnly=*/false,
5661 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005662 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 HasContextSensitiveKeywords(false) { }
5664
5665 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5666 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5667 bool postVisitChildren(CXCursor cursor);
5668 void AnnotateTokens();
5669
5670 /// \brief Determine whether the annotator saw any cursors that have
5671 /// context-sensitive keywords.
5672 bool hasContextSensitiveKeywords() const {
5673 return HasContextSensitiveKeywords;
5674 }
5675
5676 ~AnnotateTokensWorker() {
5677 assert(PostChildrenInfos.empty());
5678 }
5679};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005680}
Guy Benyei11169dd2012-12-18 14:30:41 +00005681
5682void AnnotateTokensWorker::AnnotateTokens() {
5683 // Walk the AST within the region of interest, annotating tokens
5684 // along the way.
5685 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005686}
Guy Benyei11169dd2012-12-18 14:30:41 +00005687
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005688static inline void updateCursorAnnotation(CXCursor &Cursor,
5689 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005690 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005692 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005693}
5694
5695/// \brief It annotates and advances tokens with a cursor until the comparison
5696//// between the cursor location and the source range is the same as
5697/// \arg compResult.
5698///
5699/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5700/// Pass RangeOverlap to annotate tokens inside a range.
5701void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5702 RangeComparisonResult compResult,
5703 SourceRange range) {
5704 while (MoreTokens()) {
5705 const unsigned I = NextToken();
5706 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005707 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5708 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005709
5710 SourceLocation TokLoc = GetTokenLoc(I);
5711 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005712 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005713 AdvanceToken();
5714 continue;
5715 }
5716 break;
5717 }
5718}
5719
5720/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005721/// \returns true if it advanced beyond all macro tokens, false otherwise.
5722bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005723 CXCursor updateC,
5724 RangeComparisonResult compResult,
5725 SourceRange range) {
5726 assert(MoreTokens());
5727 assert(isFunctionMacroToken(NextToken()) &&
5728 "Should be called only for macro arg tokens");
5729
5730 // This works differently than annotateAndAdvanceTokens; because expanded
5731 // macro arguments can have arbitrary translation-unit source order, we do not
5732 // advance the token index one by one until a token fails the range test.
5733 // We only advance once past all of the macro arg tokens if all of them
5734 // pass the range test. If one of them fails we keep the token index pointing
5735 // at the start of the macro arg tokens so that the failing token will be
5736 // annotated by a subsequent annotation try.
5737
5738 bool atLeastOneCompFail = false;
5739
5740 unsigned I = NextToken();
5741 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5742 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5743 if (TokLoc.isFileID())
5744 continue; // not macro arg token, it's parens or comma.
5745 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5746 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5747 Cursors[I] = updateC;
5748 } else
5749 atLeastOneCompFail = true;
5750 }
5751
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005752 if (atLeastOneCompFail)
5753 return false;
5754
5755 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5756 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005757}
5758
5759enum CXChildVisitResult
5760AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 SourceRange cursorRange = getRawCursorExtent(cursor);
5762 if (cursorRange.isInvalid())
5763 return CXChildVisit_Recurse;
5764
5765 if (!HasContextSensitiveKeywords) {
5766 // Objective-C properties can have context-sensitive keywords.
5767 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005768 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005769 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5770 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5771 }
5772 // Objective-C methods can have context-sensitive keywords.
5773 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5774 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005775 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005776 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5777 if (Method->getObjCDeclQualifier())
5778 HasContextSensitiveKeywords = true;
5779 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005780 for (const auto *P : Method->params()) {
5781 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005782 HasContextSensitiveKeywords = true;
5783 break;
5784 }
5785 }
5786 }
5787 }
5788 }
5789 // C++ methods can have context-sensitive keywords.
5790 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005791 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005792 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5793 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5794 HasContextSensitiveKeywords = true;
5795 }
5796 }
5797 // C++ classes can have context-sensitive keywords.
5798 else if (cursor.kind == CXCursor_StructDecl ||
5799 cursor.kind == CXCursor_ClassDecl ||
5800 cursor.kind == CXCursor_ClassTemplate ||
5801 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005802 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005803 if (D->hasAttr<FinalAttr>())
5804 HasContextSensitiveKeywords = true;
5805 }
5806 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005807
5808 // Don't override a property annotation with its getter/setter method.
5809 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5810 parent.kind == CXCursor_ObjCPropertyDecl)
5811 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005812
5813 if (clang_isPreprocessing(cursor.kind)) {
5814 // Items in the preprocessing record are kept separate from items in
5815 // declarations, so we keep a separate token index.
5816 unsigned SavedTokIdx = TokIdx;
5817 TokIdx = PreprocessingTokIdx;
5818
5819 // Skip tokens up until we catch up to the beginning of the preprocessing
5820 // entry.
5821 while (MoreTokens()) {
5822 const unsigned I = NextToken();
5823 SourceLocation TokLoc = GetTokenLoc(I);
5824 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5825 case RangeBefore:
5826 AdvanceToken();
5827 continue;
5828 case RangeAfter:
5829 case RangeOverlap:
5830 break;
5831 }
5832 break;
5833 }
5834
5835 // Look at all of the tokens within this range.
5836 while (MoreTokens()) {
5837 const unsigned I = NextToken();
5838 SourceLocation TokLoc = GetTokenLoc(I);
5839 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5840 case RangeBefore:
5841 llvm_unreachable("Infeasible");
5842 case RangeAfter:
5843 break;
5844 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005845 // For macro expansions, just note where the beginning of the macro
5846 // expansion occurs.
5847 if (cursor.kind == CXCursor_MacroExpansion) {
5848 if (TokLoc == cursorRange.getBegin())
5849 Cursors[I] = cursor;
5850 AdvanceToken();
5851 break;
5852 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005853 // We may have already annotated macro names inside macro definitions.
5854 if (Cursors[I].kind != CXCursor_MacroExpansion)
5855 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005856 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005857 continue;
5858 }
5859 break;
5860 }
5861
5862 // Save the preprocessing token index; restore the non-preprocessing
5863 // token index.
5864 PreprocessingTokIdx = TokIdx;
5865 TokIdx = SavedTokIdx;
5866 return CXChildVisit_Recurse;
5867 }
5868
5869 if (cursorRange.isInvalid())
5870 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005871
5872 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005873 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005874 const enum CXCursorKind K = clang_getCursorKind(parent);
5875 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005876 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5877 // Attributes are annotated out-of-order, skip tokens until we reach it.
5878 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005879 ? clang_getNullCursor() : parent;
5880
5881 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5882
5883 // Avoid having the cursor of an expression "overwrite" the annotation of the
5884 // variable declaration that it belongs to.
5885 // This can happen for C++ constructor expressions whose range generally
5886 // include the variable declaration, e.g.:
5887 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005888 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005889 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005890 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 const unsigned I = NextToken();
5892 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5893 E->getLocStart() == D->getLocation() &&
5894 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005895 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005896 AdvanceToken();
5897 }
5898 }
5899 }
5900
5901 // Before recursing into the children keep some state that we are going
5902 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5903 // extra work after the child nodes are visited.
5904 // Note that we don't call VisitChildren here to avoid traversing statements
5905 // code-recursively which can blow the stack.
5906
5907 PostChildrenInfo Info;
5908 Info.Cursor = cursor;
5909 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005910 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005911 Info.BeforeChildrenTokenIdx = NextToken();
5912 PostChildrenInfos.push_back(Info);
5913
5914 return CXChildVisit_Recurse;
5915}
5916
5917bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5918 if (PostChildrenInfos.empty())
5919 return false;
5920 const PostChildrenInfo &Info = PostChildrenInfos.back();
5921 if (!clang_equalCursors(Info.Cursor, cursor))
5922 return false;
5923
5924 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5925 const unsigned AfterChildren = NextToken();
5926 SourceRange cursorRange = Info.CursorRange;
5927
5928 // Scan the tokens that are at the end of the cursor, but are not captured
5929 // but the child cursors.
5930 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5931
5932 // Scan the tokens that are at the beginning of the cursor, but are not
5933 // capture by the child cursors.
5934 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5935 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5936 break;
5937
5938 Cursors[I] = cursor;
5939 }
5940
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005941 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5942 // encountered the attribute cursor.
5943 if (clang_isAttribute(cursor.kind))
5944 TokIdx = Info.BeforeReachingCursorIdx;
5945
Guy Benyei11169dd2012-12-18 14:30:41 +00005946 PostChildrenInfos.pop_back();
5947 return false;
5948}
5949
5950static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5951 CXCursor parent,
5952 CXClientData client_data) {
5953 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5954}
5955
5956static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5957 CXClientData client_data) {
5958 return static_cast<AnnotateTokensWorker*>(client_data)->
5959 postVisitChildren(cursor);
5960}
5961
5962namespace {
5963
5964/// \brief Uses the macro expansions in the preprocessing record to find
5965/// and mark tokens that are macro arguments. This info is used by the
5966/// AnnotateTokensWorker.
5967class MarkMacroArgTokensVisitor {
5968 SourceManager &SM;
5969 CXToken *Tokens;
5970 unsigned NumTokens;
5971 unsigned CurIdx;
5972
5973public:
5974 MarkMacroArgTokensVisitor(SourceManager &SM,
5975 CXToken *tokens, unsigned numTokens)
5976 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5977
5978 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5979 if (cursor.kind != CXCursor_MacroExpansion)
5980 return CXChildVisit_Continue;
5981
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005982 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005983 if (macroRange.getBegin() == macroRange.getEnd())
5984 return CXChildVisit_Continue; // it's not a function macro.
5985
5986 for (; CurIdx < NumTokens; ++CurIdx) {
5987 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5988 macroRange.getBegin()))
5989 break;
5990 }
5991
5992 if (CurIdx == NumTokens)
5993 return CXChildVisit_Break;
5994
5995 for (; CurIdx < NumTokens; ++CurIdx) {
5996 SourceLocation tokLoc = getTokenLoc(CurIdx);
5997 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5998 break;
5999
6000 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6001 }
6002
6003 if (CurIdx == NumTokens)
6004 return CXChildVisit_Break;
6005
6006 return CXChildVisit_Continue;
6007 }
6008
6009private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006010 CXToken &getTok(unsigned Idx) {
6011 assert(Idx < NumTokens);
6012 return Tokens[Idx];
6013 }
6014 const CXToken &getTok(unsigned Idx) const {
6015 assert(Idx < NumTokens);
6016 return Tokens[Idx];
6017 }
6018
Guy Benyei11169dd2012-12-18 14:30:41 +00006019 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006020 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006021 }
6022
6023 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6024 // The third field is reserved and currently not used. Use it here
6025 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006026 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006027 }
6028};
6029
6030} // end anonymous namespace
6031
6032static CXChildVisitResult
6033MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6034 CXClientData client_data) {
6035 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6036 parent);
6037}
6038
6039namespace {
6040 struct clang_annotateTokens_Data {
6041 CXTranslationUnit TU;
6042 ASTUnit *CXXUnit;
6043 CXToken *Tokens;
6044 unsigned NumTokens;
6045 CXCursor *Cursors;
6046 };
6047}
6048
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006049/// \brief Used by \c annotatePreprocessorTokens.
6050/// \returns true if lexing was finished, false otherwise.
6051static bool lexNext(Lexer &Lex, Token &Tok,
6052 unsigned &NextIdx, unsigned NumTokens) {
6053 if (NextIdx >= NumTokens)
6054 return true;
6055
6056 ++NextIdx;
6057 Lex.LexFromRawLexer(Tok);
6058 if (Tok.is(tok::eof))
6059 return true;
6060
6061 return false;
6062}
6063
Guy Benyei11169dd2012-12-18 14:30:41 +00006064static void annotatePreprocessorTokens(CXTranslationUnit TU,
6065 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006066 CXCursor *Cursors,
6067 CXToken *Tokens,
6068 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006069 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006070
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006071 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006072 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6073 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006074 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006075 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006076 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006077
6078 if (BeginLocInfo.first != EndLocInfo.first)
6079 return;
6080
6081 StringRef Buffer;
6082 bool Invalid = false;
6083 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6084 if (Buffer.empty() || Invalid)
6085 return;
6086
6087 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6088 CXXUnit->getASTContext().getLangOpts(),
6089 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6090 Buffer.end());
6091 Lex.SetCommentRetentionState(true);
6092
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006093 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006094 // Lex tokens in raw mode until we hit the end of the range, to avoid
6095 // entering #includes or expanding macros.
6096 while (true) {
6097 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006098 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6099 break;
6100 unsigned TokIdx = NextIdx-1;
6101 assert(Tok.getLocation() ==
6102 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006103
6104 reprocess:
6105 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006106 // We have found a preprocessing directive. Annotate the tokens
6107 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006108 //
6109 // FIXME: Some simple tests here could identify macro definitions and
6110 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006111
6112 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006113 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6114 break;
6115
Craig Topper69186e72014-06-08 08:38:04 +00006116 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006117 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006118 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6119 break;
6120
6121 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006122 IdentifierInfo &II =
6123 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006124 SourceLocation MappedTokLoc =
6125 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6126 MI = getMacroInfo(II, MappedTokLoc, TU);
6127 }
6128 }
6129
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006130 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006131 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006132 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6133 finished = true;
6134 break;
6135 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006136 // If we are in a macro definition, check if the token was ever a
6137 // macro name and annotate it if that's the case.
6138 if (MI) {
6139 SourceLocation SaveLoc = Tok.getLocation();
6140 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006141 MacroDefinitionRecord *MacroDef =
6142 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006143 Tok.setLocation(SaveLoc);
6144 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006145 Cursors[NextIdx - 1] =
6146 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006147 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006148 } while (!Tok.isAtStartOfLine());
6149
6150 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6151 assert(TokIdx <= LastIdx);
6152 SourceLocation EndLoc =
6153 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6154 CXCursor Cursor =
6155 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6156
6157 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006158 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006159
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006160 if (finished)
6161 break;
6162 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006163 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006164 }
6165}
6166
6167// This gets run a separate thread to avoid stack blowout.
6168static void clang_annotateTokensImpl(void *UserData) {
6169 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6170 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6171 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6172 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6173 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6174
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006175 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6177 setThreadBackgroundPriority();
6178
6179 // Determine the region of interest, which contains all of the tokens.
6180 SourceRange RegionOfInterest;
6181 RegionOfInterest.setBegin(
6182 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6183 RegionOfInterest.setEnd(
6184 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6185 Tokens[NumTokens-1])));
6186
Guy Benyei11169dd2012-12-18 14:30:41 +00006187 // Relex the tokens within the source range to look for preprocessing
6188 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006189 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006190
6191 // If begin location points inside a macro argument, set it to the expansion
6192 // location so we can have the full context when annotating semantically.
6193 {
6194 SourceManager &SM = CXXUnit->getSourceManager();
6195 SourceLocation Loc =
6196 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6197 if (Loc.isMacroID())
6198 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6199 }
6200
Guy Benyei11169dd2012-12-18 14:30:41 +00006201 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6202 // Search and mark tokens that are macro argument expansions.
6203 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6204 Tokens, NumTokens);
6205 CursorVisitor MacroArgMarker(TU,
6206 MarkMacroArgTokensVisitorDelegate, &Visitor,
6207 /*VisitPreprocessorLast=*/true,
6208 /*VisitIncludedEntities=*/false,
6209 RegionOfInterest);
6210 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6211 }
6212
6213 // Annotate all of the source locations in the region of interest that map to
6214 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006215 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006216
6217 // FIXME: We use a ridiculous stack size here because the data-recursion
6218 // algorithm uses a large stack frame than the non-data recursive version,
6219 // and AnnotationTokensWorker currently transforms the data-recursion
6220 // algorithm back into a traditional recursion by explicitly calling
6221 // VisitChildren(). We will need to remove this explicit recursive call.
6222 W.AnnotateTokens();
6223
6224 // If we ran into any entities that involve context-sensitive keywords,
6225 // take another pass through the tokens to mark them as such.
6226 if (W.hasContextSensitiveKeywords()) {
6227 for (unsigned I = 0; I != NumTokens; ++I) {
6228 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6229 continue;
6230
6231 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6232 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006233 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006234 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6235 if (Property->getPropertyAttributesAsWritten() != 0 &&
6236 llvm::StringSwitch<bool>(II->getName())
6237 .Case("readonly", true)
6238 .Case("assign", true)
6239 .Case("unsafe_unretained", true)
6240 .Case("readwrite", true)
6241 .Case("retain", true)
6242 .Case("copy", true)
6243 .Case("nonatomic", true)
6244 .Case("atomic", true)
6245 .Case("getter", true)
6246 .Case("setter", true)
6247 .Case("strong", true)
6248 .Case("weak", true)
6249 .Default(false))
6250 Tokens[I].int_data[0] = CXToken_Keyword;
6251 }
6252 continue;
6253 }
6254
6255 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6256 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6257 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6258 if (llvm::StringSwitch<bool>(II->getName())
6259 .Case("in", true)
6260 .Case("out", true)
6261 .Case("inout", true)
6262 .Case("oneway", true)
6263 .Case("bycopy", true)
6264 .Case("byref", true)
6265 .Default(false))
6266 Tokens[I].int_data[0] = CXToken_Keyword;
6267 continue;
6268 }
6269
6270 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6271 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6272 Tokens[I].int_data[0] = CXToken_Keyword;
6273 continue;
6274 }
6275 }
6276 }
6277}
6278
6279extern "C" {
6280
6281void clang_annotateTokens(CXTranslationUnit TU,
6282 CXToken *Tokens, unsigned NumTokens,
6283 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006284 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006285 LOG_BAD_TU(TU);
6286 return;
6287 }
6288 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006289 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006290 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006291 }
6292
6293 LOG_FUNC_SECTION {
6294 *Log << TU << ' ';
6295 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6296 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6297 *Log << clang_getRange(bloc, eloc);
6298 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006299
6300 // Any token we don't specifically annotate will have a NULL cursor.
6301 CXCursor C = clang_getNullCursor();
6302 for (unsigned I = 0; I != NumTokens; ++I)
6303 Cursors[I] = C;
6304
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006305 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006306 if (!CXXUnit)
6307 return;
6308
6309 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6310
6311 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6312 llvm::CrashRecoveryContext CRC;
6313 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6314 GetSafetyThreadStackSize() * 2)) {
6315 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6316 }
6317}
6318
6319} // end: extern "C"
6320
6321//===----------------------------------------------------------------------===//
6322// Operations for querying linkage of a cursor.
6323//===----------------------------------------------------------------------===//
6324
6325extern "C" {
6326CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6327 if (!clang_isDeclaration(cursor.kind))
6328 return CXLinkage_Invalid;
6329
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006330 const Decl *D = cxcursor::getCursorDecl(cursor);
6331 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006332 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006333 case NoLinkage:
6334 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006335 case InternalLinkage: return CXLinkage_Internal;
6336 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6337 case ExternalLinkage: return CXLinkage_External;
6338 };
6339
6340 return CXLinkage_Invalid;
6341}
6342} // end: extern "C"
6343
6344//===----------------------------------------------------------------------===//
6345// Operations for querying language of a cursor.
6346//===----------------------------------------------------------------------===//
6347
6348static CXLanguageKind getDeclLanguage(const Decl *D) {
6349 if (!D)
6350 return CXLanguage_C;
6351
6352 switch (D->getKind()) {
6353 default:
6354 break;
6355 case Decl::ImplicitParam:
6356 case Decl::ObjCAtDefsField:
6357 case Decl::ObjCCategory:
6358 case Decl::ObjCCategoryImpl:
6359 case Decl::ObjCCompatibleAlias:
6360 case Decl::ObjCImplementation:
6361 case Decl::ObjCInterface:
6362 case Decl::ObjCIvar:
6363 case Decl::ObjCMethod:
6364 case Decl::ObjCProperty:
6365 case Decl::ObjCPropertyImpl:
6366 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006367 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006368 return CXLanguage_ObjC;
6369 case Decl::CXXConstructor:
6370 case Decl::CXXConversion:
6371 case Decl::CXXDestructor:
6372 case Decl::CXXMethod:
6373 case Decl::CXXRecord:
6374 case Decl::ClassTemplate:
6375 case Decl::ClassTemplatePartialSpecialization:
6376 case Decl::ClassTemplateSpecialization:
6377 case Decl::Friend:
6378 case Decl::FriendTemplate:
6379 case Decl::FunctionTemplate:
6380 case Decl::LinkageSpec:
6381 case Decl::Namespace:
6382 case Decl::NamespaceAlias:
6383 case Decl::NonTypeTemplateParm:
6384 case Decl::StaticAssert:
6385 case Decl::TemplateTemplateParm:
6386 case Decl::TemplateTypeParm:
6387 case Decl::UnresolvedUsingTypename:
6388 case Decl::UnresolvedUsingValue:
6389 case Decl::Using:
6390 case Decl::UsingDirective:
6391 case Decl::UsingShadow:
6392 return CXLanguage_CPlusPlus;
6393 }
6394
6395 return CXLanguage_C;
6396}
6397
6398extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006399
6400static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6401 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6402 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006403
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006404 switch (D->getAvailability()) {
6405 case AR_Available:
6406 case AR_NotYetIntroduced:
6407 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006408 return getCursorAvailabilityForDecl(
6409 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006410 return CXAvailability_Available;
6411
6412 case AR_Deprecated:
6413 return CXAvailability_Deprecated;
6414
6415 case AR_Unavailable:
6416 return CXAvailability_NotAvailable;
6417 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006418
6419 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006420}
6421
Guy Benyei11169dd2012-12-18 14:30:41 +00006422enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6423 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006424 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6425 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006426
6427 return CXAvailability_Available;
6428}
6429
6430static CXVersion convertVersion(VersionTuple In) {
6431 CXVersion Out = { -1, -1, -1 };
6432 if (In.empty())
6433 return Out;
6434
6435 Out.Major = In.getMajor();
6436
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006437 Optional<unsigned> Minor = In.getMinor();
6438 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006439 Out.Minor = *Minor;
6440 else
6441 return Out;
6442
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006443 Optional<unsigned> Subminor = In.getSubminor();
6444 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006445 Out.Subminor = *Subminor;
6446
6447 return Out;
6448}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006449
6450static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6451 int *always_deprecated,
6452 CXString *deprecated_message,
6453 int *always_unavailable,
6454 CXString *unavailable_message,
6455 CXPlatformAvailability *availability,
6456 int availability_size) {
6457 bool HadAvailAttr = false;
6458 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006459 for (auto A : D->attrs()) {
6460 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006461 HadAvailAttr = true;
6462 if (always_deprecated)
6463 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006464 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006465 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006466 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006467 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006468 continue;
6469 }
6470
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006471 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006472 HadAvailAttr = true;
6473 if (always_unavailable)
6474 *always_unavailable = 1;
6475 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006476 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006477 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6478 }
6479 continue;
6480 }
6481
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006482 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006483 HadAvailAttr = true;
6484 if (N < availability_size) {
6485 availability[N].Platform
6486 = cxstring::createDup(Avail->getPlatform()->getName());
6487 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6488 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6489 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6490 availability[N].Unavailable = Avail->getUnavailable();
6491 availability[N].Message = cxstring::createDup(Avail->getMessage());
6492 }
6493 ++N;
6494 }
6495 }
6496
6497 if (!HadAvailAttr)
6498 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6499 return getCursorPlatformAvailabilityForDecl(
6500 cast<Decl>(EnumConst->getDeclContext()),
6501 always_deprecated,
6502 deprecated_message,
6503 always_unavailable,
6504 unavailable_message,
6505 availability,
6506 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006507
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006508 return N;
6509}
6510
Guy Benyei11169dd2012-12-18 14:30:41 +00006511int clang_getCursorPlatformAvailability(CXCursor cursor,
6512 int *always_deprecated,
6513 CXString *deprecated_message,
6514 int *always_unavailable,
6515 CXString *unavailable_message,
6516 CXPlatformAvailability *availability,
6517 int availability_size) {
6518 if (always_deprecated)
6519 *always_deprecated = 0;
6520 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006521 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006522 if (always_unavailable)
6523 *always_unavailable = 0;
6524 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006525 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006526
Guy Benyei11169dd2012-12-18 14:30:41 +00006527 if (!clang_isDeclaration(cursor.kind))
6528 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006529
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006530 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006531 if (!D)
6532 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006533
6534 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6535 deprecated_message,
6536 always_unavailable,
6537 unavailable_message,
6538 availability,
6539 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006540}
6541
6542void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6543 clang_disposeString(availability->Platform);
6544 clang_disposeString(availability->Message);
6545}
6546
6547CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6548 if (clang_isDeclaration(cursor.kind))
6549 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6550
6551 return CXLanguage_Invalid;
6552}
6553
6554 /// \brief If the given cursor is the "templated" declaration
6555 /// descibing a class or function template, return the class or
6556 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006557static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006558 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006559 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006560
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006561 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006562 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6563 return FunTmpl;
6564
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006565 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006566 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6567 return ClassTmpl;
6568
6569 return D;
6570}
6571
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006572
6573enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6574 StorageClass sc = SC_None;
6575 const Decl *D = getCursorDecl(C);
6576 if (D) {
6577 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6578 sc = FD->getStorageClass();
6579 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6580 sc = VD->getStorageClass();
6581 } else {
6582 return CX_SC_Invalid;
6583 }
6584 } else {
6585 return CX_SC_Invalid;
6586 }
6587 switch (sc) {
6588 case SC_None:
6589 return CX_SC_None;
6590 case SC_Extern:
6591 return CX_SC_Extern;
6592 case SC_Static:
6593 return CX_SC_Static;
6594 case SC_PrivateExtern:
6595 return CX_SC_PrivateExtern;
6596 case SC_OpenCLWorkGroupLocal:
6597 return CX_SC_OpenCLWorkGroupLocal;
6598 case SC_Auto:
6599 return CX_SC_Auto;
6600 case SC_Register:
6601 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006602 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006603 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006604}
6605
Guy Benyei11169dd2012-12-18 14:30:41 +00006606CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6607 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006608 if (const Decl *D = getCursorDecl(cursor)) {
6609 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006610 if (!DC)
6611 return clang_getNullCursor();
6612
6613 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6614 getCursorTU(cursor));
6615 }
6616 }
6617
6618 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006619 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006620 return MakeCXCursor(D, getCursorTU(cursor));
6621 }
6622
6623 return clang_getNullCursor();
6624}
6625
6626CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6627 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006628 if (const Decl *D = getCursorDecl(cursor)) {
6629 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006630 if (!DC)
6631 return clang_getNullCursor();
6632
6633 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6634 getCursorTU(cursor));
6635 }
6636 }
6637
6638 // FIXME: Note that we can't easily compute the lexical context of a
6639 // statement or expression, so we return nothing.
6640 return clang_getNullCursor();
6641}
6642
6643CXFile clang_getIncludedFile(CXCursor cursor) {
6644 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006645 return nullptr;
6646
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006647 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006648 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006649}
6650
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006651unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6652 if (C.kind != CXCursor_ObjCPropertyDecl)
6653 return CXObjCPropertyAttr_noattr;
6654
6655 unsigned Result = CXObjCPropertyAttr_noattr;
6656 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6657 ObjCPropertyDecl::PropertyAttributeKind Attr =
6658 PD->getPropertyAttributesAsWritten();
6659
6660#define SET_CXOBJCPROP_ATTR(A) \
6661 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6662 Result |= CXObjCPropertyAttr_##A
6663 SET_CXOBJCPROP_ATTR(readonly);
6664 SET_CXOBJCPROP_ATTR(getter);
6665 SET_CXOBJCPROP_ATTR(assign);
6666 SET_CXOBJCPROP_ATTR(readwrite);
6667 SET_CXOBJCPROP_ATTR(retain);
6668 SET_CXOBJCPROP_ATTR(copy);
6669 SET_CXOBJCPROP_ATTR(nonatomic);
6670 SET_CXOBJCPROP_ATTR(setter);
6671 SET_CXOBJCPROP_ATTR(atomic);
6672 SET_CXOBJCPROP_ATTR(weak);
6673 SET_CXOBJCPROP_ATTR(strong);
6674 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6675#undef SET_CXOBJCPROP_ATTR
6676
6677 return Result;
6678}
6679
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006680unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6681 if (!clang_isDeclaration(C.kind))
6682 return CXObjCDeclQualifier_None;
6683
6684 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6685 const Decl *D = getCursorDecl(C);
6686 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6687 QT = MD->getObjCDeclQualifier();
6688 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6689 QT = PD->getObjCDeclQualifier();
6690 if (QT == Decl::OBJC_TQ_None)
6691 return CXObjCDeclQualifier_None;
6692
6693 unsigned Result = CXObjCDeclQualifier_None;
6694 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6695 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6696 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6697 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6698 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6699 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6700
6701 return Result;
6702}
6703
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006704unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6705 if (!clang_isDeclaration(C.kind))
6706 return 0;
6707
6708 const Decl *D = getCursorDecl(C);
6709 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6710 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6711 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6712 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6713
6714 return 0;
6715}
6716
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006717unsigned clang_Cursor_isVariadic(CXCursor C) {
6718 if (!clang_isDeclaration(C.kind))
6719 return 0;
6720
6721 const Decl *D = getCursorDecl(C);
6722 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6723 return FD->isVariadic();
6724 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6725 return MD->isVariadic();
6726
6727 return 0;
6728}
6729
Guy Benyei11169dd2012-12-18 14:30:41 +00006730CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6731 if (!clang_isDeclaration(C.kind))
6732 return clang_getNullRange();
6733
6734 const Decl *D = getCursorDecl(C);
6735 ASTContext &Context = getCursorContext(C);
6736 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6737 if (!RC)
6738 return clang_getNullRange();
6739
6740 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6741}
6742
6743CXString clang_Cursor_getRawCommentText(CXCursor C) {
6744 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006745 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006746
6747 const Decl *D = getCursorDecl(C);
6748 ASTContext &Context = getCursorContext(C);
6749 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6750 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6751 StringRef();
6752
6753 // Don't duplicate the string because RawText points directly into source
6754 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006755 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006756}
6757
6758CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6759 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006760 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006761
6762 const Decl *D = getCursorDecl(C);
6763 const ASTContext &Context = getCursorContext(C);
6764 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6765
6766 if (RC) {
6767 StringRef BriefText = RC->getBriefText(Context);
6768
6769 // Don't duplicate the string because RawComment ensures that this memory
6770 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006771 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006772 }
6773
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006774 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006775}
6776
Guy Benyei11169dd2012-12-18 14:30:41 +00006777CXModule clang_Cursor_getModule(CXCursor C) {
6778 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006779 if (const ImportDecl *ImportD =
6780 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006781 return ImportD->getImportedModule();
6782 }
6783
Craig Topper69186e72014-06-08 08:38:04 +00006784 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006785}
6786
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006787CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6788 if (isNotUsableTU(TU)) {
6789 LOG_BAD_TU(TU);
6790 return nullptr;
6791 }
6792 if (!File)
6793 return nullptr;
6794 FileEntry *FE = static_cast<FileEntry *>(File);
6795
6796 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6797 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6798 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6799
Richard Smithfeb54b62014-10-23 02:01:19 +00006800 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006801}
6802
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006803CXFile clang_Module_getASTFile(CXModule CXMod) {
6804 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006805 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006806 Module *Mod = static_cast<Module*>(CXMod);
6807 return const_cast<FileEntry *>(Mod->getASTFile());
6808}
6809
Guy Benyei11169dd2012-12-18 14:30:41 +00006810CXModule clang_Module_getParent(CXModule CXMod) {
6811 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006812 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006813 Module *Mod = static_cast<Module*>(CXMod);
6814 return Mod->Parent;
6815}
6816
6817CXString clang_Module_getName(CXModule CXMod) {
6818 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006819 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006820 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006821 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006822}
6823
6824CXString clang_Module_getFullName(CXModule CXMod) {
6825 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006826 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006827 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006828 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006829}
6830
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006831int clang_Module_isSystem(CXModule CXMod) {
6832 if (!CXMod)
6833 return 0;
6834 Module *Mod = static_cast<Module*>(CXMod);
6835 return Mod->IsSystem;
6836}
6837
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006838unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6839 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006840 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006841 LOG_BAD_TU(TU);
6842 return 0;
6843 }
6844 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006845 return 0;
6846 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006847 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6848 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6849 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006850}
6851
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006852CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6853 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006854 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006855 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006856 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006857 }
6858 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006859 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006860 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006861 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006862
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006863 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6864 if (Index < TopHeaders.size())
6865 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006866
Craig Topper69186e72014-06-08 08:38:04 +00006867 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006868}
6869
6870} // end: extern "C"
6871
6872//===----------------------------------------------------------------------===//
6873// C++ AST instrospection.
6874//===----------------------------------------------------------------------===//
6875
6876extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006877unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6878 if (!clang_isDeclaration(C.kind))
6879 return 0;
6880
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006881 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006882 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006883 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006884 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6885}
6886
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006887unsigned clang_CXXMethod_isConst(CXCursor C) {
6888 if (!clang_isDeclaration(C.kind))
6889 return 0;
6890
6891 const Decl *D = cxcursor::getCursorDecl(C);
6892 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006893 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006894 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6895}
6896
Guy Benyei11169dd2012-12-18 14:30:41 +00006897unsigned clang_CXXMethod_isStatic(CXCursor C) {
6898 if (!clang_isDeclaration(C.kind))
6899 return 0;
6900
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006901 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006902 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006903 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006904 return (Method && Method->isStatic()) ? 1 : 0;
6905}
6906
6907unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6908 if (!clang_isDeclaration(C.kind))
6909 return 0;
6910
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006911 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006912 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006913 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006914 return (Method && Method->isVirtual()) ? 1 : 0;
6915}
6916} // end: extern "C"
6917
6918//===----------------------------------------------------------------------===//
6919// Attribute introspection.
6920//===----------------------------------------------------------------------===//
6921
6922extern "C" {
6923CXType clang_getIBOutletCollectionType(CXCursor C) {
6924 if (C.kind != CXCursor_IBOutletCollectionAttr)
6925 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6926
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006927 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006928 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6929
6930 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6931}
6932} // end: extern "C"
6933
6934//===----------------------------------------------------------------------===//
6935// Inspecting memory usage.
6936//===----------------------------------------------------------------------===//
6937
6938typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6939
6940static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6941 enum CXTUResourceUsageKind k,
6942 unsigned long amount) {
6943 CXTUResourceUsageEntry entry = { k, amount };
6944 entries.push_back(entry);
6945}
6946
6947extern "C" {
6948
6949const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6950 const char *str = "";
6951 switch (kind) {
6952 case CXTUResourceUsage_AST:
6953 str = "ASTContext: expressions, declarations, and types";
6954 break;
6955 case CXTUResourceUsage_Identifiers:
6956 str = "ASTContext: identifiers";
6957 break;
6958 case CXTUResourceUsage_Selectors:
6959 str = "ASTContext: selectors";
6960 break;
6961 case CXTUResourceUsage_GlobalCompletionResults:
6962 str = "Code completion: cached global results";
6963 break;
6964 case CXTUResourceUsage_SourceManagerContentCache:
6965 str = "SourceManager: content cache allocator";
6966 break;
6967 case CXTUResourceUsage_AST_SideTables:
6968 str = "ASTContext: side tables";
6969 break;
6970 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6971 str = "SourceManager: malloc'ed memory buffers";
6972 break;
6973 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6974 str = "SourceManager: mmap'ed memory buffers";
6975 break;
6976 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6977 str = "ExternalASTSource: malloc'ed memory buffers";
6978 break;
6979 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6980 str = "ExternalASTSource: mmap'ed memory buffers";
6981 break;
6982 case CXTUResourceUsage_Preprocessor:
6983 str = "Preprocessor: malloc'ed memory";
6984 break;
6985 case CXTUResourceUsage_PreprocessingRecord:
6986 str = "Preprocessor: PreprocessingRecord";
6987 break;
6988 case CXTUResourceUsage_SourceManager_DataStructures:
6989 str = "SourceManager: data structures and tables";
6990 break;
6991 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6992 str = "Preprocessor: header search tables";
6993 break;
6994 }
6995 return str;
6996}
6997
6998CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006999 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007000 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007001 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007002 return usage;
7003 }
7004
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007005 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007006 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007007 ASTContext &astContext = astUnit->getASTContext();
7008
7009 // How much memory is used by AST nodes and types?
7010 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7011 (unsigned long) astContext.getASTAllocatedMemory());
7012
7013 // How much memory is used by identifiers?
7014 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7015 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7016
7017 // How much memory is used for selectors?
7018 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7019 (unsigned long) astContext.Selectors.getTotalMemory());
7020
7021 // How much memory is used by ASTContext's side tables?
7022 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7023 (unsigned long) astContext.getSideTableAllocatedMemory());
7024
7025 // How much memory is used for caching global code completion results?
7026 unsigned long completionBytes = 0;
7027 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007028 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007029 completionBytes = completionAllocator->getTotalMemory();
7030 }
7031 createCXTUResourceUsageEntry(*entries,
7032 CXTUResourceUsage_GlobalCompletionResults,
7033 completionBytes);
7034
7035 // How much memory is being used by SourceManager's content cache?
7036 createCXTUResourceUsageEntry(*entries,
7037 CXTUResourceUsage_SourceManagerContentCache,
7038 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7039
7040 // How much memory is being used by the MemoryBuffer's in SourceManager?
7041 const SourceManager::MemoryBufferSizes &srcBufs =
7042 astUnit->getSourceManager().getMemoryBufferSizes();
7043
7044 createCXTUResourceUsageEntry(*entries,
7045 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7046 (unsigned long) srcBufs.malloc_bytes);
7047 createCXTUResourceUsageEntry(*entries,
7048 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7049 (unsigned long) srcBufs.mmap_bytes);
7050 createCXTUResourceUsageEntry(*entries,
7051 CXTUResourceUsage_SourceManager_DataStructures,
7052 (unsigned long) astContext.getSourceManager()
7053 .getDataStructureSizes());
7054
7055 // How much memory is being used by the ExternalASTSource?
7056 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7057 const ExternalASTSource::MemoryBufferSizes &sizes =
7058 esrc->getMemoryBufferSizes();
7059
7060 createCXTUResourceUsageEntry(*entries,
7061 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7062 (unsigned long) sizes.malloc_bytes);
7063 createCXTUResourceUsageEntry(*entries,
7064 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7065 (unsigned long) sizes.mmap_bytes);
7066 }
7067
7068 // How much memory is being used by the Preprocessor?
7069 Preprocessor &pp = astUnit->getPreprocessor();
7070 createCXTUResourceUsageEntry(*entries,
7071 CXTUResourceUsage_Preprocessor,
7072 pp.getTotalMemory());
7073
7074 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7075 createCXTUResourceUsageEntry(*entries,
7076 CXTUResourceUsage_PreprocessingRecord,
7077 pRec->getTotalMemory());
7078 }
7079
7080 createCXTUResourceUsageEntry(*entries,
7081 CXTUResourceUsage_Preprocessor_HeaderSearch,
7082 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007083
Guy Benyei11169dd2012-12-18 14:30:41 +00007084 CXTUResourceUsage usage = { (void*) entries.get(),
7085 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007086 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007087 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007088 return usage;
7089}
7090
7091void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7092 if (usage.data)
7093 delete (MemUsageEntries*) usage.data;
7094}
7095
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007096CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7097 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007098 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007099 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007100
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007101 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007102 LOG_BAD_TU(TU);
7103 return skipped;
7104 }
7105
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007106 if (!file)
7107 return skipped;
7108
7109 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7110 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7111 if (!ppRec)
7112 return skipped;
7113
7114 ASTContext &Ctx = astUnit->getASTContext();
7115 SourceManager &sm = Ctx.getSourceManager();
7116 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7117 FileID wantedFileID = sm.translateFile(fileEntry);
7118
7119 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7120 std::vector<SourceRange> wantedRanges;
7121 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7122 i != ei; ++i) {
7123 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7124 wantedRanges.push_back(*i);
7125 }
7126
7127 skipped->count = wantedRanges.size();
7128 skipped->ranges = new CXSourceRange[skipped->count];
7129 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7130 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7131
7132 return skipped;
7133}
7134
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007135void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7136 if (ranges) {
7137 delete[] ranges->ranges;
7138 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007139 }
7140}
7141
Guy Benyei11169dd2012-12-18 14:30:41 +00007142} // end extern "C"
7143
7144void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7145 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7146 for (unsigned I = 0; I != Usage.numEntries; ++I)
7147 fprintf(stderr, " %s: %lu\n",
7148 clang_getTUResourceUsageName(Usage.entries[I].kind),
7149 Usage.entries[I].amount);
7150
7151 clang_disposeCXTUResourceUsage(Usage);
7152}
7153
7154//===----------------------------------------------------------------------===//
7155// Misc. utility functions.
7156//===----------------------------------------------------------------------===//
7157
7158/// Default to using an 8 MB stack size on "safety" threads.
7159static unsigned SafetyStackThreadSize = 8 << 20;
7160
7161namespace clang {
7162
7163bool RunSafely(llvm::CrashRecoveryContext &CRC,
7164 void (*Fn)(void*), void *UserData,
7165 unsigned Size) {
7166 if (!Size)
7167 Size = GetSafetyThreadStackSize();
7168 if (Size)
7169 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7170 return CRC.RunSafely(Fn, UserData);
7171}
7172
7173unsigned GetSafetyThreadStackSize() {
7174 return SafetyStackThreadSize;
7175}
7176
7177void SetSafetyThreadStackSize(unsigned Value) {
7178 SafetyStackThreadSize = Value;
7179}
7180
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007181}
Guy Benyei11169dd2012-12-18 14:30:41 +00007182
7183void clang::setThreadBackgroundPriority() {
7184 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7185 return;
7186
Alp Toker1a86ad22014-07-06 06:24:00 +00007187#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007188 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7189#endif
7190}
7191
7192void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7193 if (!Unit)
7194 return;
7195
7196 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7197 DEnd = Unit->stored_diag_end();
7198 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007199 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007200 CXString Msg = clang_formatDiagnostic(&Diag,
7201 clang_defaultDiagnosticDisplayOptions());
7202 fprintf(stderr, "%s\n", clang_getCString(Msg));
7203 clang_disposeString(Msg);
7204 }
7205#ifdef LLVM_ON_WIN32
7206 // On Windows, force a flush, since there may be multiple copies of
7207 // stderr and stdout in the file system, all with different buffers
7208 // but writing to the same device.
7209 fflush(stderr);
7210#endif
7211}
7212
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007213MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7214 SourceLocation MacroDefLoc,
7215 CXTranslationUnit TU){
7216 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007217 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007218 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007219 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007220
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007221 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007222 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007223 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007224 if (MD) {
7225 for (MacroDirective::DefInfo
7226 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7227 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7228 return Def.getMacroInfo();
7229 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007230 }
7231
Craig Topper69186e72014-06-08 08:38:04 +00007232 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007233}
7234
Richard Smith66a81862015-05-04 02:25:31 +00007235const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007236 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007237 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007238 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007239 const IdentifierInfo *II = MacroDef->getName();
7240 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007241 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007242
7243 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7244}
7245
Richard Smith66a81862015-05-04 02:25:31 +00007246MacroDefinitionRecord *
7247cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7248 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007249 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007250 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007251 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007252 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007253
7254 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007255 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007256 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7257 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007258 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007259
7260 // Check that the token is inside the definition and not its argument list.
7261 SourceManager &SM = Unit->getSourceManager();
7262 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007263 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007264 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007265 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007266
7267 Preprocessor &PP = Unit->getPreprocessor();
7268 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7269 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007270 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007271
Alp Toker2d57cea2014-05-17 04:53:25 +00007272 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007273 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007274 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007275
7276 // Check that the identifier is not one of the macro arguments.
7277 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007278 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007279
Richard Smith20e883e2015-04-29 23:20:19 +00007280 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007281 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007282 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007283
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007284 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007285}
7286
Richard Smith66a81862015-05-04 02:25:31 +00007287MacroDefinitionRecord *
7288cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7289 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007290 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007291 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007292
7293 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007294 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007295 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007296 Preprocessor &PP = Unit->getPreprocessor();
7297 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007298 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007299 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7300 Token Tok;
7301 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007302 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007303
7304 return checkForMacroInMacroDefinition(MI, Tok, TU);
7305}
7306
Guy Benyei11169dd2012-12-18 14:30:41 +00007307extern "C" {
7308
7309CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007310 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007311}
7312
7313} // end: extern "C"
7314
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007315Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7316 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007317 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007318 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007319 if (Unit->isMainFileAST())
7320 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007321 return *this;
7322 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007323 } else {
7324 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007325 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007326 return *this;
7327}
7328
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007329Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7330 *this << FE->getName();
7331 return *this;
7332}
7333
7334Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7335 CXString cursorName = clang_getCursorDisplayName(cursor);
7336 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7337 clang_disposeString(cursorName);
7338 return *this;
7339}
7340
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007341Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7342 CXFile File;
7343 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007344 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007345 CXString FileName = clang_getFileName(File);
7346 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7347 clang_disposeString(FileName);
7348 return *this;
7349}
7350
7351Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7352 CXSourceLocation BLoc = clang_getRangeStart(range);
7353 CXSourceLocation ELoc = clang_getRangeEnd(range);
7354
7355 CXFile BFile;
7356 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007357 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007358
7359 CXFile EFile;
7360 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007361 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007362
7363 CXString BFileName = clang_getFileName(BFile);
7364 if (BFile == EFile) {
7365 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7366 BLine, BColumn, ELine, EColumn);
7367 } else {
7368 CXString EFileName = clang_getFileName(EFile);
7369 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7370 BLine, BColumn)
7371 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7372 ELine, EColumn);
7373 clang_disposeString(EFileName);
7374 }
7375 clang_disposeString(BFileName);
7376 return *this;
7377}
7378
7379Logger &cxindex::Logger::operator<<(CXString Str) {
7380 *this << clang_getCString(Str);
7381 return *this;
7382}
7383
7384Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7385 LogOS << Fmt;
7386 return *this;
7387}
7388
Chandler Carruth37ad2582014-06-27 15:14:39 +00007389static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7390
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007391cxindex::Logger::~Logger() {
7392 LogOS.flush();
7393
Chandler Carruth37ad2582014-06-27 15:14:39 +00007394 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007395
7396 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7397
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007398 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007399 OS << "[libclang:" << Name << ':';
7400
Alp Toker1a86ad22014-07-06 06:24:00 +00007401#ifdef USE_DARWIN_THREADS
7402 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007403 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7404 OS << tid << ':';
7405#endif
7406
7407 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7408 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007409 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007410
7411 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007412 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007413 OS << "--------------------------------------------------\n";
7414 }
7415}