blob: b47128785c8c60a94482ac4487f468ae60e8f31e [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000243 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
244 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000245 PPRec, FID);
246}
247
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000248bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000249 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000250 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000251
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000252 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000253 SourceManager &SM = Unit->getSourceManager();
254
255 std::pair<FileID, unsigned>
256 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
257 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
258
259 if (End.first != Begin.first) {
260 // If the end does not reside in the same file, try to recover by
261 // picking the end of the file of begin location.
262 End.first = Begin.first;
263 End.second = SM.getFileIDSize(Begin.first);
264 }
265
266 assert(Begin.first == End.first);
267 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000268 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
270 FileID File = Begin.first;
271 unsigned Offset = Begin.second;
272 unsigned Length = End.second - Begin.second;
273
274 if (!VisitDeclsOnly && !VisitPreprocessorLast)
275 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000278 if (visitDeclsFromFileRegion(File, Offset, Length))
279 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000280
281 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000282 return visitPreprocessedEntitiesInRegion();
283
284 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000285}
286
287static bool isInLexicalContext(Decl *D, DeclContext *DC) {
288 if (!DC)
289 return false;
290
291 for (DeclContext *DeclDC = D->getLexicalDeclContext();
292 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
293 if (DeclDC == DC)
294 return true;
295 }
296 return false;
297}
298
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000299bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000300 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000301 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000302 SourceManager &SM = Unit->getSourceManager();
303 SourceRange Range = RegionOfInterest;
304
305 SmallVector<Decl *, 16> Decls;
306 Unit->findFileRegionDecls(File, Offset, Length, Decls);
307
308 // If we didn't find any file level decls for the file, try looking at the
309 // file that it was included from.
310 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
311 bool Invalid = false;
312 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
313 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000314 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315
316 SourceLocation Outer;
317 if (SLEntry.isFile())
318 Outer = SLEntry.getFile().getIncludeLoc();
319 else
320 Outer = SLEntry.getExpansion().getExpansionLocStart();
321 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000322 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000323
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000324 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000325 Length = 0;
326 Unit->findFileRegionDecls(File, Offset, Length, Decls);
327 }
328
329 assert(!Decls.empty());
330
331 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000332 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000333 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
334 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000335 Decl *D = *DIt;
336 if (D->getSourceRange().isInvalid())
337 continue;
338
339 if (isInLexicalContext(D, CurDC))
340 continue;
341
342 CurDC = dyn_cast<DeclContext>(D);
343
344 if (TagDecl *TD = dyn_cast<TagDecl>(D))
345 if (!TD->isFreeStanding())
346 continue;
347
348 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
349 if (CompRes == RangeBefore)
350 continue;
351 if (CompRes == RangeAfter)
352 break;
353
354 assert(CompRes == RangeOverlap);
355 VisitedAtLeastOnce = true;
356
357 if (isa<ObjCContainerDecl>(D)) {
358 FileDI_current = &DIt;
359 FileDE_current = DE;
360 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000361 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000362 }
363
364 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000365 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000366 }
367
368 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000369 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000370
371 // No Decls overlapped with the range. Move up the lexical context until there
372 // is a context that contains the range or we reach the translation unit
373 // level.
374 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
375 : (*(DIt-1))->getLexicalDeclContext();
376
377 while (DC && !DC->isTranslationUnit()) {
378 Decl *D = cast<Decl>(DC);
379 SourceRange CurDeclRange = D->getSourceRange();
380 if (CurDeclRange.isInvalid())
381 break;
382
383 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000384 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
385 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000386 }
387
388 DC = D->getLexicalDeclContext();
389 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000390
391 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000392}
393
394bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
395 if (!AU->getPreprocessor().getPreprocessingRecord())
396 return false;
397
398 PreprocessingRecord &PPRec
399 = *AU->getPreprocessor().getPreprocessingRecord();
400 SourceManager &SM = AU->getSourceManager();
401
402 if (RegionOfInterest.isValid()) {
403 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
404 SourceLocation B = MappedRange.getBegin();
405 SourceLocation E = MappedRange.getEnd();
406
407 if (AU->isInPreambleFileID(B)) {
408 if (SM.isLoadedSourceLocation(E))
409 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
410 PPRec, *this);
411
412 // Beginning of range lies in the preamble but it also extends beyond
413 // it into the main file. Split the range into 2 parts, one covering
414 // the preamble and another covering the main file. This allows subsequent
415 // calls to visitPreprocessedEntitiesInRange to accept a source range that
416 // lies in the same FileID, allowing it to skip preprocessed entities that
417 // do not come from the same FileID.
418 bool breaked =
419 visitPreprocessedEntitiesInRange(
420 SourceRange(B, AU->getEndOfPreambleFileID()),
421 PPRec, *this);
422 if (breaked) return true;
423 return visitPreprocessedEntitiesInRange(
424 SourceRange(AU->getStartOfMainFileID(), E),
425 PPRec, *this);
426 }
427
428 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
429 }
430
431 bool OnlyLocalDecls
432 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
433
434 if (OnlyLocalDecls)
435 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
436 PPRec);
437
438 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
439}
440
441template<typename InputIterator>
442bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
443 InputIterator Last,
444 PreprocessingRecord &PPRec,
445 FileID FID) {
446 for (; First != Last; ++First) {
447 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
448 continue;
449
450 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000451 if (!PPE)
452 continue;
453
Guy Benyei11169dd2012-12-18 14:30:41 +0000454 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
455 if (Visit(MakeMacroExpansionCursor(ME, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
462 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
463 return true;
464
465 continue;
466 }
467
468 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
469 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
470 return true;
471
472 continue;
473 }
474 }
475
476 return false;
477}
478
479/// \brief Visit the children of the given cursor.
480///
481/// \returns true if the visitation should be aborted, false if it
482/// should continue.
483bool CursorVisitor::VisitChildren(CXCursor Cursor) {
484 if (clang_isReference(Cursor.kind) &&
485 Cursor.kind != CXCursor_CXXBaseSpecifier) {
486 // By definition, references have no children.
487 return false;
488 }
489
490 // Set the Parent field to Cursor, then back to its old value once we're
491 // done.
492 SetParentRAII SetParent(Parent, StmtParent, Cursor);
493
494 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000495 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000496 if (!D)
497 return false;
498
499 return VisitAttributes(D) || Visit(D);
500 }
501
502 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(S);
505
506 return false;
507 }
508
509 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000510 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000511 return Visit(E);
512
513 return false;
514 }
515
516 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000517 CXTranslationUnit TU = getCursorTU(Cursor);
518 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000519
520 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
521 for (unsigned I = 0; I != 2; ++I) {
522 if (VisitOrder[I]) {
523 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
524 RegionOfInterest.isInvalid()) {
525 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
526 TLEnd = CXXUnit->top_level_end();
527 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000528 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000529 return true;
530 }
531 } else if (VisitDeclContext(
532 CXXUnit->getASTContext().getTranslationUnitDecl()))
533 return true;
534 continue;
535 }
536
537 // Walk the preprocessing record.
538 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
539 visitPreprocessedEntitiesInRegion();
540 }
541
542 return false;
543 }
544
545 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000546 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
548 return Visit(BaseTSInfo->getTypeLoc());
549 }
550 }
551 }
552
553 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000554 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000555 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000556 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000557 return Visit(cxcursor::MakeCursorObjCClassRef(
558 ObjT->getInterface(),
559 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000560 }
561
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000562 // If pointing inside a macro definition, check if the token is an identifier
563 // that was ever defined as a macro. In such a case, create a "pseudo" macro
564 // expansion cursor for that token.
565 SourceLocation BeginLoc = RegionOfInterest.getBegin();
566 if (Cursor.kind == CXCursor_MacroDefinition &&
567 BeginLoc == RegionOfInterest.getEnd()) {
568 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000569 const MacroInfo *MI =
570 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000571 if (MacroDefinition *MacroDef =
572 checkForMacroInMacroDefinition(MI, Loc, TU))
573 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
574 }
575
Guy Benyei11169dd2012-12-18 14:30:41 +0000576 // Nothing to visit at the moment.
577 return false;
578}
579
580bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
581 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
582 if (Visit(TSInfo->getTypeLoc()))
583 return true;
584
585 if (Stmt *Body = B->getBody())
586 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
587
588 return false;
589}
590
Ted Kremenek03325582013-02-21 01:29:01 +0000591Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000592 if (RegionOfInterest.isValid()) {
593 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
594 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000595 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000596
597 switch (CompareRegionOfInterest(Range)) {
598 case RangeBefore:
599 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000600 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000601
602 case RangeAfter:
603 // This declaration comes after the region of interest; we're done.
604 return false;
605
606 case RangeOverlap:
607 // This declaration overlaps the region of interest; visit it.
608 break;
609 }
610 }
611 return true;
612}
613
614bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
615 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
616
617 // FIXME: Eventually remove. This part of a hack to support proper
618 // iteration over all Decls contained lexically within an ObjC container.
619 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
620 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
621
622 for ( ; I != E; ++I) {
623 Decl *D = *I;
624 if (D->getLexicalDeclContext() != DC)
625 continue;
626 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
627
628 // Ignore synthesized ivars here, otherwise if we have something like:
629 // @synthesize prop = _prop;
630 // and '_prop' is not declared, we will encounter a '_prop' ivar before
631 // encountering the 'prop' synthesize declaration and we will think that
632 // we passed the region-of-interest.
633 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
634 if (ivarD->getSynthesize())
635 continue;
636 }
637
638 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
639 // declarations is a mismatch with the compiler semantics.
640 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
641 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
642 if (!ID->isThisDeclarationADefinition())
643 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
644
645 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
646 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
647 if (!PD->isThisDeclarationADefinition())
648 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
649 }
650
Ted Kremenek03325582013-02-21 01:29:01 +0000651 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000652 if (!V.hasValue())
653 continue;
654 if (!V.getValue())
655 return false;
656 if (Visit(Cursor, true))
657 return true;
658 }
659 return false;
660}
661
662bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
663 llvm_unreachable("Translation units are visited directly by Visit()");
664}
665
666bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
674 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
675 return Visit(TSInfo->getTypeLoc());
676
677 return false;
678}
679
680bool CursorVisitor::VisitTagDecl(TagDecl *D) {
681 return VisitDeclContext(D);
682}
683
684bool CursorVisitor::VisitClassTemplateSpecializationDecl(
685 ClassTemplateSpecializationDecl *D) {
686 bool ShouldVisitBody = false;
687 switch (D->getSpecializationKind()) {
688 case TSK_Undeclared:
689 case TSK_ImplicitInstantiation:
690 // Nothing to visit
691 return false;
692
693 case TSK_ExplicitInstantiationDeclaration:
694 case TSK_ExplicitInstantiationDefinition:
695 break;
696
697 case TSK_ExplicitSpecialization:
698 ShouldVisitBody = true;
699 break;
700 }
701
702 // Visit the template arguments used in the specialization.
703 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
704 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000705 if (TemplateSpecializationTypeLoc TSTLoc =
706 TL.getAs<TemplateSpecializationTypeLoc>()) {
707 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
708 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000709 return true;
710 }
711 }
712
713 if (ShouldVisitBody && VisitCXXRecordDecl(D))
714 return true;
715
716 return false;
717}
718
719bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
720 ClassTemplatePartialSpecializationDecl *D) {
721 // FIXME: Visit the "outer" template parameter lists on the TagDecl
722 // before visiting these template parameters.
723 if (VisitTemplateParameters(D->getTemplateParameters()))
724 return true;
725
726 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000727 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
728 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
729 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000730 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
731 return true;
732
733 return VisitCXXRecordDecl(D);
734}
735
736bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
737 // Visit the default argument.
738 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
739 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
740 if (Visit(DefArg->getTypeLoc()))
741 return true;
742
743 return false;
744}
745
746bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
747 if (Expr *Init = D->getInitExpr())
748 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
749 return false;
750}
751
752bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000753 unsigned NumParamList = DD->getNumTemplateParameterLists();
754 for (unsigned i = 0; i < NumParamList; i++) {
755 TemplateParameterList* Params = DD->getTemplateParameterList(i);
756 if (VisitTemplateParameters(Params))
757 return true;
758 }
759
Guy Benyei11169dd2012-12-18 14:30:41 +0000760 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
761 if (Visit(TSInfo->getTypeLoc()))
762 return true;
763
764 // Visit the nested-name-specifier, if present.
765 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
766 if (VisitNestedNameSpecifierLoc(QualifierLoc))
767 return true;
768
769 return false;
770}
771
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000772/// \brief Compare two base or member initializers based on their source order.
773static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
774 CXXCtorInitializer *const *Y) {
775 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
776}
777
Guy Benyei11169dd2012-12-18 14:30:41 +0000778bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000779 unsigned NumParamList = ND->getNumTemplateParameterLists();
780 for (unsigned i = 0; i < NumParamList; i++) {
781 TemplateParameterList* Params = ND->getTemplateParameterList(i);
782 if (VisitTemplateParameters(Params))
783 return true;
784 }
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
787 // Visit the function declaration's syntactic components in the order
788 // written. This requires a bit of work.
789 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000790 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000791
792 // If we have a function declared directly (without the use of a typedef),
793 // visit just the return type. Otherwise, just visit the function's type
794 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000795 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000796 (!FTL && Visit(TL)))
797 return true;
798
799 // Visit the nested-name-specifier, if present.
800 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
801 if (VisitNestedNameSpecifierLoc(QualifierLoc))
802 return true;
803
804 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000805 if (!isa<CXXDestructorDecl>(ND))
806 if (VisitDeclarationNameInfo(ND->getNameInfo()))
807 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000808
809 // FIXME: Visit explicitly-specified template arguments!
810
811 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000812 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 return true;
814
Bill Wendling44426052012-12-20 19:22:21 +0000815 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000816 }
817
818 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
819 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
820 // Find the initializers that were written in the source.
821 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000822 for (auto *I : Constructor->inits()) {
823 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 continue;
825
Aaron Ballman0ad78302014-03-13 17:34:31 +0000826 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000827 }
828
829 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000830 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
831 &CompareCXXCtorInitializers);
832
Guy Benyei11169dd2012-12-18 14:30:41 +0000833 // Visit the initializers in source order
834 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
835 CXXCtorInitializer *Init = WrittenInits[I];
836 if (Init->isAnyMemberInitializer()) {
837 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
838 Init->getMemberLocation(), TU)))
839 return true;
840 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
841 if (Visit(TInfo->getTypeLoc()))
842 return true;
843 }
844
845 // Visit the initializer value.
846 if (Expr *Initializer = Init->getInit())
847 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
848 return true;
849 }
850 }
851
852 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
853 return true;
854 }
855
856 return false;
857}
858
859bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
860 if (VisitDeclaratorDecl(D))
861 return true;
862
863 if (Expr *BitWidth = D->getBitWidth())
864 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
865
866 return false;
867}
868
869bool CursorVisitor::VisitVarDecl(VarDecl *D) {
870 if (VisitDeclaratorDecl(D))
871 return true;
872
873 if (Expr *Init = D->getInit())
874 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
875
876 return false;
877}
878
879bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
880 if (VisitDeclaratorDecl(D))
881 return true;
882
883 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
884 if (Expr *DefArg = D->getDefaultArgument())
885 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
886
887 return false;
888}
889
890bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
891 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
892 // before visiting these template parameters.
893 if (VisitTemplateParameters(D->getTemplateParameters()))
894 return true;
895
896 return VisitFunctionDecl(D->getTemplatedDecl());
897}
898
899bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
900 // FIXME: Visit the "outer" template parameter lists on the TagDecl
901 // before visiting these template parameters.
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 return VisitCXXRecordDecl(D->getTemplatedDecl());
906}
907
908bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
909 if (VisitTemplateParameters(D->getTemplateParameters()))
910 return true;
911
912 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
913 VisitTemplateArgumentLoc(D->getDefaultArgument()))
914 return true;
915
916 return false;
917}
918
919bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000920 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000921 if (Visit(TSInfo->getTypeLoc()))
922 return true;
923
Aaron Ballman43b68be2014-03-07 17:50:17 +0000924 for (const auto *P : ND->params()) {
925 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000926 return true;
927 }
928
929 if (ND->isThisDeclarationADefinition() &&
930 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
931 return true;
932
933 return false;
934}
935
936template <typename DeclIt>
937static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
938 SourceManager &SM, SourceLocation EndLoc,
939 SmallVectorImpl<Decl *> &Decls) {
940 DeclIt next = *DI_current;
941 while (++next != DE_current) {
942 Decl *D_next = *next;
943 if (!D_next)
944 break;
945 SourceLocation L = D_next->getLocStart();
946 if (!L.isValid())
947 break;
948 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
949 *DI_current = next;
950 Decls.push_back(D_next);
951 continue;
952 }
953 break;
954 }
955}
956
Guy Benyei11169dd2012-12-18 14:30:41 +0000957bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
958 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
959 // an @implementation can lexically contain Decls that are not properly
960 // nested in the AST. When we identify such cases, we need to retrofit
961 // this nesting here.
962 if (!DI_current && !FileDI_current)
963 return VisitDeclContext(D);
964
965 // Scan the Decls that immediately come after the container
966 // in the current DeclContext. If any fall within the
967 // container's lexical region, stash them into a vector
968 // for later processing.
969 SmallVector<Decl *, 24> DeclsInContainer;
970 SourceLocation EndLoc = D->getSourceRange().getEnd();
971 SourceManager &SM = AU->getSourceManager();
972 if (EndLoc.isValid()) {
973 if (DI_current) {
974 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
975 DeclsInContainer);
976 } else {
977 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
978 DeclsInContainer);
979 }
980 }
981
982 // The common case.
983 if (DeclsInContainer.empty())
984 return VisitDeclContext(D);
985
986 // Get all the Decls in the DeclContext, and sort them with the
987 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000988 for (auto *SubDecl : D->decls()) {
989 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
990 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000991 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000992 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000993 }
994
995 // Now sort the Decls so that they appear in lexical order.
996 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000997 [&SM](Decl *A, Decl *B) {
998 SourceLocation L_A = A->getLocStart();
999 SourceLocation L_B = B->getLocStart();
1000 assert(L_A.isValid() && L_B.isValid());
1001 return SM.isBeforeInTranslationUnit(L_A, L_B);
1002 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001003
1004 // Now visit the decls.
1005 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1006 E = DeclsInContainer.end(); I != E; ++I) {
1007 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001008 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001009 if (!V.hasValue())
1010 continue;
1011 if (!V.getValue())
1012 return false;
1013 if (Visit(Cursor, true))
1014 return true;
1015 }
1016 return false;
1017}
1018
1019bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1020 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1021 TU)))
1022 return true;
1023
1024 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1025 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1026 E = ND->protocol_end(); I != E; ++I, ++PL)
1027 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1028 return true;
1029
1030 return VisitObjCContainerDecl(ND);
1031}
1032
1033bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1034 if (!PID->isThisDeclarationADefinition())
1035 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1036
1037 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1038 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1039 E = PID->protocol_end(); I != E; ++I, ++PL)
1040 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1041 return true;
1042
1043 return VisitObjCContainerDecl(PID);
1044}
1045
1046bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1047 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1048 return true;
1049
1050 // FIXME: This implements a workaround with @property declarations also being
1051 // installed in the DeclContext for the @interface. Eventually this code
1052 // should be removed.
1053 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1054 if (!CDecl || !CDecl->IsClassExtension())
1055 return false;
1056
1057 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1058 if (!ID)
1059 return false;
1060
1061 IdentifierInfo *PropertyId = PD->getIdentifier();
1062 ObjCPropertyDecl *prevDecl =
1063 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1064
1065 if (!prevDecl)
1066 return false;
1067
1068 // Visit synthesized methods since they will be skipped when visiting
1069 // the @interface.
1070 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1071 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1072 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1073 return true;
1074
1075 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1076 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1077 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1078 return true;
1079
1080 return false;
1081}
1082
1083bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1084 if (!D->isThisDeclarationADefinition()) {
1085 // Forward declaration is treated like a reference.
1086 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1087 }
1088
1089 // Issue callbacks for super class.
1090 if (D->getSuperClass() &&
1091 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1092 D->getSuperClassLoc(),
1093 TU)))
1094 return true;
1095
1096 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1097 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1098 E = D->protocol_end(); I != E; ++I, ++PL)
1099 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1100 return true;
1101
1102 return VisitObjCContainerDecl(D);
1103}
1104
1105bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1106 return VisitObjCContainerDecl(D);
1107}
1108
1109bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1110 // 'ID' could be null when dealing with invalid code.
1111 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1112 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1113 return true;
1114
1115 return VisitObjCImplDecl(D);
1116}
1117
1118bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1119#if 0
1120 // Issue callbacks for super class.
1121 // FIXME: No source location information!
1122 if (D->getSuperClass() &&
1123 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1124 D->getSuperClassLoc(),
1125 TU)))
1126 return true;
1127#endif
1128
1129 return VisitObjCImplDecl(D);
1130}
1131
1132bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1133 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1134 if (PD->isIvarNameSpecified())
1135 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1136
1137 return false;
1138}
1139
1140bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1141 return VisitDeclContext(D);
1142}
1143
1144bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1145 // Visit nested-name-specifier.
1146 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1147 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1148 return true;
1149
1150 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1151 D->getTargetNameLoc(), TU));
1152}
1153
1154bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1155 // Visit nested-name-specifier.
1156 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1157 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1158 return true;
1159 }
1160
1161 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1162 return true;
1163
1164 return VisitDeclarationNameInfo(D->getNameInfo());
1165}
1166
1167bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1168 // Visit nested-name-specifier.
1169 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1170 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1171 return true;
1172
1173 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1174 D->getIdentLocation(), TU));
1175}
1176
1177bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1178 // Visit nested-name-specifier.
1179 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1180 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1181 return true;
1182 }
1183
1184 return VisitDeclarationNameInfo(D->getNameInfo());
1185}
1186
1187bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1188 UnresolvedUsingTypenameDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return false;
1195}
1196
1197bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1198 switch (Name.getName().getNameKind()) {
1199 case clang::DeclarationName::Identifier:
1200 case clang::DeclarationName::CXXLiteralOperatorName:
1201 case clang::DeclarationName::CXXOperatorName:
1202 case clang::DeclarationName::CXXUsingDirective:
1203 return false;
1204
1205 case clang::DeclarationName::CXXConstructorName:
1206 case clang::DeclarationName::CXXDestructorName:
1207 case clang::DeclarationName::CXXConversionFunctionName:
1208 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1209 return Visit(TSInfo->getTypeLoc());
1210 return false;
1211
1212 case clang::DeclarationName::ObjCZeroArgSelector:
1213 case clang::DeclarationName::ObjCOneArgSelector:
1214 case clang::DeclarationName::ObjCMultiArgSelector:
1215 // FIXME: Per-identifier location info?
1216 return false;
1217 }
1218
1219 llvm_unreachable("Invalid DeclarationName::Kind!");
1220}
1221
1222bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1223 SourceRange Range) {
1224 // FIXME: This whole routine is a hack to work around the lack of proper
1225 // source information in nested-name-specifiers (PR5791). Since we do have
1226 // a beginning source location, we can visit the first component of the
1227 // nested-name-specifier, if it's a single-token component.
1228 if (!NNS)
1229 return false;
1230
1231 // Get the first component in the nested-name-specifier.
1232 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1233 NNS = Prefix;
1234
1235 switch (NNS->getKind()) {
1236 case NestedNameSpecifier::Namespace:
1237 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1238 TU));
1239
1240 case NestedNameSpecifier::NamespaceAlias:
1241 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1242 Range.getBegin(), TU));
1243
1244 case NestedNameSpecifier::TypeSpec: {
1245 // If the type has a form where we know that the beginning of the source
1246 // range matches up with a reference cursor. Visit the appropriate reference
1247 // cursor.
1248 const Type *T = NNS->getAsType();
1249 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1250 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1251 if (const TagType *Tag = dyn_cast<TagType>(T))
1252 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1253 if (const TemplateSpecializationType *TST
1254 = dyn_cast<TemplateSpecializationType>(T))
1255 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1256 break;
1257 }
1258
1259 case NestedNameSpecifier::TypeSpecWithTemplate:
1260 case NestedNameSpecifier::Global:
1261 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001262 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001263 break;
1264 }
1265
1266 return false;
1267}
1268
1269bool
1270CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1271 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1272 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1273 Qualifiers.push_back(Qualifier);
1274
1275 while (!Qualifiers.empty()) {
1276 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1277 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1278 switch (NNS->getKind()) {
1279 case NestedNameSpecifier::Namespace:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::NamespaceAlias:
1288 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1289 Q.getLocalBeginLoc(),
1290 TU)))
1291 return true;
1292
1293 break;
1294
1295 case NestedNameSpecifier::TypeSpec:
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 if (Visit(Q.getTypeLoc()))
1298 return true;
1299
1300 break;
1301
1302 case NestedNameSpecifier::Global:
1303 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001304 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001305 break;
1306 }
1307 }
1308
1309 return false;
1310}
1311
1312bool CursorVisitor::VisitTemplateParameters(
1313 const TemplateParameterList *Params) {
1314 if (!Params)
1315 return false;
1316
1317 for (TemplateParameterList::const_iterator P = Params->begin(),
1318 PEnd = Params->end();
1319 P != PEnd; ++P) {
1320 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1321 return true;
1322 }
1323
1324 return false;
1325}
1326
1327bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1328 switch (Name.getKind()) {
1329 case TemplateName::Template:
1330 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1331
1332 case TemplateName::OverloadedTemplate:
1333 // Visit the overloaded template set.
1334 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1335 return true;
1336
1337 return false;
1338
1339 case TemplateName::DependentTemplate:
1340 // FIXME: Visit nested-name-specifier.
1341 return false;
1342
1343 case TemplateName::QualifiedTemplate:
1344 // FIXME: Visit nested-name-specifier.
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsQualifiedTemplateName()->getDecl(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParm:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1352 Loc, TU));
1353
1354 case TemplateName::SubstTemplateTemplateParmPack:
1355 return Visit(MakeCursorTemplateRef(
1356 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1357 Loc, TU));
1358 }
1359
1360 llvm_unreachable("Invalid TemplateName::Kind!");
1361}
1362
1363bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1364 switch (TAL.getArgument().getKind()) {
1365 case TemplateArgument::Null:
1366 case TemplateArgument::Integral:
1367 case TemplateArgument::Pack:
1368 return false;
1369
1370 case TemplateArgument::Type:
1371 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1372 return Visit(TSInfo->getTypeLoc());
1373 return false;
1374
1375 case TemplateArgument::Declaration:
1376 if (Expr *E = TAL.getSourceDeclExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::NullPtr:
1381 if (Expr *E = TAL.getSourceNullPtrExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Expression:
1386 if (Expr *E = TAL.getSourceExpression())
1387 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1388 return false;
1389
1390 case TemplateArgument::Template:
1391 case TemplateArgument::TemplateExpansion:
1392 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1393 return true;
1394
1395 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1396 TAL.getTemplateNameLoc());
1397 }
1398
1399 llvm_unreachable("Invalid TemplateArgument::Kind!");
1400}
1401
1402bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1403 return VisitDeclContext(D);
1404}
1405
1406bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1407 return Visit(TL.getUnqualifiedLoc());
1408}
1409
1410bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1411 ASTContext &Context = AU->getASTContext();
1412
1413 // Some builtin types (such as Objective-C's "id", "sel", and
1414 // "Class") have associated declarations. Create cursors for those.
1415 QualType VisitType;
1416 switch (TL.getTypePtr()->getKind()) {
1417
1418 case BuiltinType::Void:
1419 case BuiltinType::NullPtr:
1420 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001421 case BuiltinType::OCLImage1d:
1422 case BuiltinType::OCLImage1dArray:
1423 case BuiltinType::OCLImage1dBuffer:
1424 case BuiltinType::OCLImage2d:
1425 case BuiltinType::OCLImage2dArray:
1426 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001427 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001428 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001429#define BUILTIN_TYPE(Id, SingletonId)
1430#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1434#include "clang/AST/BuiltinTypes.def"
1435 break;
1436
1437 case BuiltinType::ObjCId:
1438 VisitType = Context.getObjCIdType();
1439 break;
1440
1441 case BuiltinType::ObjCClass:
1442 VisitType = Context.getObjCClassType();
1443 break;
1444
1445 case BuiltinType::ObjCSel:
1446 VisitType = Context.getObjCSelType();
1447 break;
1448 }
1449
1450 if (!VisitType.isNull()) {
1451 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1452 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1453 TU));
1454 }
1455
1456 return false;
1457}
1458
1459bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1460 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1468 if (TL.isDefinition())
1469 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1470
1471 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1472}
1473
1474bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1475 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1476}
1477
1478bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1479 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1480 return true;
1481
1482 return false;
1483}
1484
1485bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1486 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1487 return true;
1488
1489 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1490 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1491 TU)))
1492 return true;
1493 }
1494
1495 return false;
1496}
1497
1498bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1499 return Visit(TL.getPointeeLoc());
1500}
1501
1502bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1503 return Visit(TL.getInnerLoc());
1504}
1505
1506bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1507 return Visit(TL.getPointeeLoc());
1508}
1509
1510bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1511 return Visit(TL.getPointeeLoc());
1512}
1513
1514bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1515 return Visit(TL.getPointeeLoc());
1516}
1517
1518bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1519 return Visit(TL.getPointeeLoc());
1520}
1521
1522bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1523 return Visit(TL.getPointeeLoc());
1524}
1525
1526bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1527 return Visit(TL.getModifiedLoc());
1528}
1529
1530bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1531 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001532 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001533 return true;
1534
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001535 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1536 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001537 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1538 return true;
1539
1540 return false;
1541}
1542
1543bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1544 if (Visit(TL.getElementLoc()))
1545 return true;
1546
1547 if (Expr *Size = TL.getSizeExpr())
1548 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1549
1550 return false;
1551}
1552
Reid Kleckner8a365022013-06-24 17:51:48 +00001553bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1554 return Visit(TL.getOriginalLoc());
1555}
1556
Reid Kleckner0503a872013-12-05 01:23:43 +00001557bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1558 return Visit(TL.getOriginalLoc());
1559}
1560
Guy Benyei11169dd2012-12-18 14:30:41 +00001561bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1562 TemplateSpecializationTypeLoc TL) {
1563 // Visit the template name.
1564 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1565 TL.getTemplateNameLoc()))
1566 return true;
1567
1568 // Visit the template arguments.
1569 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1570 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1571 return true;
1572
1573 return false;
1574}
1575
1576bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1577 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1578}
1579
1580bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1581 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1582 return Visit(TSInfo->getTypeLoc());
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1588 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1589 return Visit(TSInfo->getTypeLoc());
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1595 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1596 return true;
1597
1598 return false;
1599}
1600
1601bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1602 DependentTemplateSpecializationTypeLoc TL) {
1603 // Visit the nested-name-specifier, if there is one.
1604 if (TL.getQualifierLoc() &&
1605 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1606 return true;
1607
1608 // Visit the template arguments.
1609 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1610 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1611 return true;
1612
1613 return false;
1614}
1615
1616bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1617 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1618 return true;
1619
1620 return Visit(TL.getNamedTypeLoc());
1621}
1622
1623bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1624 return Visit(TL.getPatternLoc());
1625}
1626
1627bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1628 if (Expr *E = TL.getUnderlyingExpr())
1629 return Visit(MakeCXCursor(E, StmtParent, TU));
1630
1631 return false;
1632}
1633
1634bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1635 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1636}
1637
1638bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1639 return Visit(TL.getValueLoc());
1640}
1641
1642#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1643bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1644 return Visit##PARENT##Loc(TL); \
1645}
1646
1647DEFAULT_TYPELOC_IMPL(Complex, Type)
1648DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1652DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1653DEFAULT_TYPELOC_IMPL(Vector, Type)
1654DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1655DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1656DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1657DEFAULT_TYPELOC_IMPL(Record, TagType)
1658DEFAULT_TYPELOC_IMPL(Enum, TagType)
1659DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1660DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1661DEFAULT_TYPELOC_IMPL(Auto, Type)
1662
1663bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1664 // Visit the nested-name-specifier, if present.
1665 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1666 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1667 return true;
1668
1669 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001670 for (const auto &I : D->bases()) {
1671 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001672 return true;
1673 }
1674 }
1675
1676 return VisitTagDecl(D);
1677}
1678
1679bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001680 for (const auto *I : D->attrs())
1681 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001682 return true;
1683
1684 return false;
1685}
1686
1687//===----------------------------------------------------------------------===//
1688// Data-recursive visitor methods.
1689//===----------------------------------------------------------------------===//
1690
1691namespace {
1692#define DEF_JOB(NAME, DATA, KIND)\
1693class NAME : public VisitorJob {\
1694public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001695 NAME(const DATA *d, CXCursor parent) : \
1696 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001697 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001698 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001699};
1700
1701DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1702DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1703DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1704DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1705DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1706 ExplicitTemplateArgsVisitKind)
1707DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1708DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1709DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1710#undef DEF_JOB
1711
1712class DeclVisit : public VisitorJob {
1713public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001714 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001715 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001716 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001717 static bool classof(const VisitorJob *VJ) {
1718 return VJ->getKind() == DeclVisitKind;
1719 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001720 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001721 bool isFirst() const { return data[1] ? true : false; }
1722};
1723class TypeLocVisit : public VisitorJob {
1724public:
1725 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1726 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1727 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1728
1729 static bool classof(const VisitorJob *VJ) {
1730 return VJ->getKind() == TypeLocVisitKind;
1731 }
1732
1733 TypeLoc get() const {
1734 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001735 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001736 }
1737};
1738
1739class LabelRefVisit : public VisitorJob {
1740public:
1741 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1742 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1743 labelLoc.getPtrEncoding()) {}
1744
1745 static bool classof(const VisitorJob *VJ) {
1746 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1747 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 const LabelDecl *get() const {
1749 return static_cast<const LabelDecl *>(data[0]);
1750 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001751 SourceLocation getLoc() const {
1752 return SourceLocation::getFromPtrEncoding(data[1]); }
1753};
1754
1755class NestedNameSpecifierLocVisit : public VisitorJob {
1756public:
1757 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1758 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1759 Qualifier.getNestedNameSpecifier(),
1760 Qualifier.getOpaqueData()) { }
1761
1762 static bool classof(const VisitorJob *VJ) {
1763 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1764 }
1765
1766 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 return NestedNameSpecifierLoc(
1768 const_cast<NestedNameSpecifier *>(
1769 static_cast<const NestedNameSpecifier *>(data[0])),
1770 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001771 }
1772};
1773
1774class DeclarationNameInfoVisit : public VisitorJob {
1775public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001776 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001777 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 static bool classof(const VisitorJob *VJ) {
1779 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1780 }
1781 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001782 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001783 switch (S->getStmtClass()) {
1784 default:
1785 llvm_unreachable("Unhandled Stmt");
1786 case clang::Stmt::MSDependentExistsStmtClass:
1787 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1788 case Stmt::CXXDependentScopeMemberExprClass:
1789 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1790 case Stmt::DependentScopeDeclRefExprClass:
1791 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001792 case Stmt::OMPCriticalDirectiveClass:
1793 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001794 }
1795 }
1796};
1797class MemberRefVisit : public VisitorJob {
1798public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001799 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1801 L.getPtrEncoding()) {}
1802 static bool classof(const VisitorJob *VJ) {
1803 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1804 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001805 const FieldDecl *get() const {
1806 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001807 }
1808 SourceLocation getLoc() const {
1809 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1810 }
1811};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001812class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001813 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001814 VisitorWorkList &WL;
1815 CXCursor Parent;
1816public:
1817 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1818 : WL(wl), Parent(parent) {}
1819
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001820 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1821 void VisitBlockExpr(const BlockExpr *B);
1822 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1823 void VisitCompoundStmt(const CompoundStmt *S);
1824 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1825 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1826 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1827 void VisitCXXNewExpr(const CXXNewExpr *E);
1828 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1829 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1830 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1831 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1832 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1833 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1834 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1835 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001836 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001837 void VisitDeclRefExpr(const DeclRefExpr *D);
1838 void VisitDeclStmt(const DeclStmt *S);
1839 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1840 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1841 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1842 void VisitForStmt(const ForStmt *FS);
1843 void VisitGotoStmt(const GotoStmt *GS);
1844 void VisitIfStmt(const IfStmt *If);
1845 void VisitInitListExpr(const InitListExpr *IE);
1846 void VisitMemberExpr(const MemberExpr *M);
1847 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1848 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1849 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1850 void VisitOverloadExpr(const OverloadExpr *E);
1851 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1852 void VisitStmt(const Stmt *S);
1853 void VisitSwitchStmt(const SwitchStmt *S);
1854 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1856 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1857 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1858 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1859 void VisitVAArgExpr(const VAArgExpr *E);
1860 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1861 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1862 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1863 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001865 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001867 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001868 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001869 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001870 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001871 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001872 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001873 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001874 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001875 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001876 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001877 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001878 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001879 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001880 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001881 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001882 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001883 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001884 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001885 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001886 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887
Guy Benyei11169dd2012-12-18 14:30:41 +00001888private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1891 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1893 void AddStmt(const Stmt *S);
1894 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001897 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001898};
1899} // end anonyous namespace
1900
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 // 'S' should always be non-null, since it comes from the
1903 // statement we are visiting.
1904 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1905}
1906
1907void
1908EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1909 if (Qualifier)
1910 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1911}
1912
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 if (S)
1915 WL.push_back(StmtVisit(S, Parent));
1916}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001918 if (D)
1919 WL.push_back(DeclVisit(D, Parent, isFirst));
1920}
1921void EnqueueVisitor::
1922 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1923 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001924 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001925}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001926void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001927 if (D)
1928 WL.push_back(MemberRefVisit(D, L, Parent));
1929}
1930void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1931 if (TI)
1932 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1933 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001934void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001935 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001936 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 AddStmt(*Child);
1938 }
1939 if (size == WL.size())
1940 return;
1941 // Now reverse the entries we just added. This will match the DFS
1942 // ordering performed by the worklist.
1943 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1944 std::reverse(I, E);
1945}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946namespace {
1947class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1948 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001949 /// \brief Process clauses with list of variables.
1950 template <typename T>
1951 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001952public:
1953 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1954#define OPENMP_CLAUSE(Name, Class) \
1955 void Visit##Class(const Class *C);
1956#include "clang/Basic/OpenMPKinds.def"
1957};
1958
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001959void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1960 Visitor->AddStmt(C->getCondition());
1961}
1962
Alexey Bataev3778b602014-07-17 07:32:53 +00001963void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1964 Visitor->AddStmt(C->getCondition());
1965}
1966
Alexey Bataev568a8332014-03-06 06:15:19 +00001967void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1968 Visitor->AddStmt(C->getNumThreads());
1969}
1970
Alexey Bataev62c87d22014-03-21 04:51:18 +00001971void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1972 Visitor->AddStmt(C->getSafelen());
1973}
1974
Alexander Musman8bd31e62014-05-27 15:12:19 +00001975void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1976 Visitor->AddStmt(C->getNumForLoops());
1977}
1978
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001979void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001980
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001981void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1982
Alexey Bataev56dafe82014-06-20 07:16:17 +00001983void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1984 Visitor->AddStmt(C->getChunkSize());
1985}
1986
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001987void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1988
Alexey Bataev236070f2014-06-20 11:19:47 +00001989void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1990
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001991void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1992
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001993void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1994
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001995void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1996
Alexey Bataevdea47612014-07-23 07:46:59 +00001997void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1998
Alexey Bataev67a4f222014-07-23 10:25:33 +00001999void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2000
Alexey Bataev459dec02014-07-24 06:46:57 +00002001void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2002
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002003void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2004
Alexey Bataev756c1962013-09-24 03:17:45 +00002005template<typename T>
2006void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002007 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002008 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002009 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002010}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002011
2012void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002013 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002014 for (const auto *E : C->private_copies()) {
2015 Visitor->AddStmt(E);
2016 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002017}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002018void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2019 const OMPFirstprivateClause *C) {
2020 VisitOMPClauseList(C);
2021}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002022void OMPClauseEnqueue::VisitOMPLastprivateClause(
2023 const OMPLastprivateClause *C) {
2024 VisitOMPClauseList(C);
2025}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002026void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002027 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002028}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002029void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2030 VisitOMPClauseList(C);
2031}
Alexander Musman8dba6642014-04-22 13:09:42 +00002032void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2033 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002034 for (const auto *E : C->inits()) {
2035 Visitor->AddStmt(E);
2036 }
2037 for (const auto *E : C->updates()) {
2038 Visitor->AddStmt(E);
2039 }
2040 for (const auto *E : C->finals()) {
2041 Visitor->AddStmt(E);
2042 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002043 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002044 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002045}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002046void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2047 VisitOMPClauseList(C);
2048 Visitor->AddStmt(C->getAlignment());
2049}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002050void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2051 VisitOMPClauseList(C);
2052}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002053void
2054OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2055 VisitOMPClauseList(C);
2056}
Alexey Bataev6125da92014-07-21 11:26:11 +00002057void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2058 VisitOMPClauseList(C);
2059}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002060}
Alexey Bataev756c1962013-09-24 03:17:45 +00002061
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002062void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2063 unsigned size = WL.size();
2064 OMPClauseEnqueue Visitor(this);
2065 Visitor.Visit(S);
2066 if (size == WL.size())
2067 return;
2068 // Now reverse the entries we just added. This will match the DFS
2069 // ordering performed by the worklist.
2070 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2071 std::reverse(I, E);
2072}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2075}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002076void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002077 AddDecl(B->getBlockDecl());
2078}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 EnqueueChildren(E);
2081 AddTypeLoc(E->getTypeSourceInfo());
2082}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002083void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2084 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002085 E = S->body_rend(); I != E; ++I) {
2086 AddStmt(*I);
2087 }
2088}
2089void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002090VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002091 AddStmt(S->getSubStmt());
2092 AddDeclarationNameInfo(S);
2093 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2094 AddNestedNameSpecifierLoc(QualifierLoc);
2095}
2096
2097void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2100 AddDeclarationNameInfo(E);
2101 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2102 AddNestedNameSpecifierLoc(QualifierLoc);
2103 if (!E->isImplicitAccess())
2104 AddStmt(E->getBase());
2105}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002106void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002107 // Enqueue the initializer , if any.
2108 AddStmt(E->getInitializer());
2109 // Enqueue the array size, if any.
2110 AddStmt(E->getArraySize());
2111 // Enqueue the allocated type.
2112 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2113 // Enqueue the placement arguments.
2114 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2115 AddStmt(E->getPlacementArg(I-1));
2116}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002117void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2119 AddStmt(CE->getArg(I-1));
2120 AddStmt(CE->getCallee());
2121 AddStmt(CE->getArg(0));
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2124 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 // Visit the name of the type being destroyed.
2126 AddTypeLoc(E->getDestroyedTypeInfo());
2127 // Visit the scope type that looks disturbingly like the nested-name-specifier
2128 // but isn't.
2129 AddTypeLoc(E->getScopeTypeInfo());
2130 // Visit the nested-name-specifier.
2131 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2132 AddNestedNameSpecifierLoc(QualifierLoc);
2133 // Visit base expression.
2134 AddStmt(E->getBase());
2135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2137 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 AddTypeLoc(E->getTypeSourceInfo());
2139}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2141 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 EnqueueChildren(E);
2143 AddTypeLoc(E->getTypeSourceInfo());
2144}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002145void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002146 EnqueueChildren(E);
2147 if (E->isTypeOperand())
2148 AddTypeLoc(E->getTypeOperandSourceInfo());
2149}
2150
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2152 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 EnqueueChildren(E);
2154 AddTypeLoc(E->getTypeSourceInfo());
2155}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002157 EnqueueChildren(E);
2158 if (E->isTypeOperand())
2159 AddTypeLoc(E->getTypeOperandSourceInfo());
2160}
2161
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002162void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002163 EnqueueChildren(S);
2164 AddDecl(S->getExceptionDecl());
2165}
2166
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002167void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002168 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002169 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002170 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002171}
2172
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002173void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002174 if (DR->hasExplicitTemplateArgs()) {
2175 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2176 }
2177 WL.push_back(DeclRefExprParts(DR, Parent));
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2180 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2182 AddDeclarationNameInfo(E);
2183 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2184}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 unsigned size = WL.size();
2187 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002188 for (const auto *D : S->decls()) {
2189 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 isFirst = false;
2191 }
2192 if (size == WL.size())
2193 return;
2194 // Now reverse the entries we just added. This will match the DFS
2195 // ordering performed by the worklist.
2196 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2197 std::reverse(I, E);
2198}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002201 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002202 D = E->designators_rbegin(), DEnd = E->designators_rend();
2203 D != DEnd; ++D) {
2204 if (D->isFieldDesignator()) {
2205 if (FieldDecl *Field = D->getField())
2206 AddMemberRef(Field, D->getFieldLoc());
2207 continue;
2208 }
2209 if (D->isArrayDesignator()) {
2210 AddStmt(E->getArrayIndex(*D));
2211 continue;
2212 }
2213 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2214 AddStmt(E->getArrayRangeEnd(*D));
2215 AddStmt(E->getArrayRangeStart(*D));
2216 }
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 EnqueueChildren(E);
2220 AddTypeLoc(E->getTypeInfoAsWritten());
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 AddStmt(FS->getBody());
2224 AddStmt(FS->getInc());
2225 AddStmt(FS->getCond());
2226 AddDecl(FS->getConditionVariable());
2227 AddStmt(FS->getInit());
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2231}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 AddStmt(If->getElse());
2234 AddStmt(If->getThen());
2235 AddStmt(If->getCond());
2236 AddDecl(If->getConditionVariable());
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 // We care about the syntactic form of the initializer list, only.
2240 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2241 IE = Syntactic;
2242 EnqueueChildren(IE);
2243}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 WL.push_back(MemberExprParts(M, Parent));
2246
2247 // If the base of the member access expression is an implicit 'this', don't
2248 // visit it.
2249 // FIXME: If we ever want to show these implicit accesses, this will be
2250 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002251 if (M->isImplicitAccess())
2252 return;
2253
2254 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2255 // real field that that we are interested in.
2256 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2257 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2258 if (FD->isAnonymousStructOrUnion()) {
2259 AddStmt(SubME->getBase());
2260 return;
2261 }
2262 }
2263 }
2264
2265 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002266}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 AddTypeLoc(E->getEncodedTypeSourceInfo());
2269}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 EnqueueChildren(M);
2272 AddTypeLoc(M->getClassReceiverTypeInfo());
2273}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 // Visit the components of the offsetof expression.
2276 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2277 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2278 const OffsetOfNode &Node = E->getComponent(I-1);
2279 switch (Node.getKind()) {
2280 case OffsetOfNode::Array:
2281 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2282 break;
2283 case OffsetOfNode::Field:
2284 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2285 break;
2286 case OffsetOfNode::Identifier:
2287 case OffsetOfNode::Base:
2288 continue;
2289 }
2290 }
2291 // Visit the type into which we're computing the offset.
2292 AddTypeLoc(E->getTypeSourceInfo());
2293}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2296 WL.push_back(OverloadExprParts(E, Parent));
2297}
2298void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002299 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002300 EnqueueChildren(E);
2301 if (E->isArgumentType())
2302 AddTypeLoc(E->getArgumentTypeInfo());
2303}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002304void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002305 EnqueueChildren(S);
2306}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002307void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002308 AddStmt(S->getBody());
2309 AddStmt(S->getCond());
2310 AddDecl(S->getConditionVariable());
2311}
2312
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 AddStmt(W->getBody());
2315 AddStmt(W->getCond());
2316 AddDecl(W->getConditionVariable());
2317}
2318
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002319void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 for (unsigned I = E->getNumArgs(); I > 0; --I)
2321 AddTypeLoc(E->getArg(I-1));
2322}
2323
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002324void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002325 AddTypeLoc(E->getQueriedTypeSourceInfo());
2326}
2327
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002328void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002329 EnqueueChildren(E);
2330}
2331
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002332void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 VisitOverloadExpr(U);
2334 if (!U->isImplicitAccess())
2335 AddStmt(U->getBase());
2336}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002337void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002338 AddStmt(E->getSubExpr());
2339 AddTypeLoc(E->getWrittenTypeInfo());
2340}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002341void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002342 WL.push_back(SizeOfPackExprParts(E, Parent));
2343}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002344void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002345 // If the opaque value has a source expression, just transparently
2346 // visit that. This is useful for (e.g.) pseudo-object expressions.
2347 if (Expr *SourceExpr = E->getSourceExpr())
2348 return Visit(SourceExpr);
2349}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002350void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002351 AddStmt(E->getBody());
2352 WL.push_back(LambdaExprParts(E, Parent));
2353}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002354void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002355 // Treat the expression like its syntactic form.
2356 Visit(E->getSyntacticForm());
2357}
2358
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002359void EnqueueVisitor::VisitOMPExecutableDirective(
2360 const OMPExecutableDirective *D) {
2361 EnqueueChildren(D);
2362 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2363 E = D->clauses().end();
2364 I != E; ++I)
2365 EnqueueChildren(*I);
2366}
2367
Alexander Musman3aaab662014-08-19 11:27:13 +00002368void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2369 VisitOMPExecutableDirective(D);
2370}
2371
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002372void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2373 VisitOMPExecutableDirective(D);
2374}
2375
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002376void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002377 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002378}
2379
Alexey Bataevf29276e2014-06-18 04:14:57 +00002380void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002381 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002382}
2383
Alexander Musmanf82886e2014-09-18 05:12:34 +00002384void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2385 VisitOMPLoopDirective(D);
2386}
2387
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002388void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2389 VisitOMPExecutableDirective(D);
2390}
2391
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002392void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2393 VisitOMPExecutableDirective(D);
2394}
2395
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002396void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2397 VisitOMPExecutableDirective(D);
2398}
2399
Alexander Musman80c22892014-07-17 08:54:58 +00002400void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2401 VisitOMPExecutableDirective(D);
2402}
2403
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002404void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2405 VisitOMPExecutableDirective(D);
2406 AddDeclarationNameInfo(D);
2407}
2408
Alexey Bataev4acb8592014-07-07 13:01:15 +00002409void
2410EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002411 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002412}
2413
Alexander Musmane4e893b2014-09-23 09:33:00 +00002414void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2415 const OMPParallelForSimdDirective *D) {
2416 VisitOMPLoopDirective(D);
2417}
2418
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002419void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2420 const OMPParallelSectionsDirective *D) {
2421 VisitOMPExecutableDirective(D);
2422}
2423
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002424void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2425 VisitOMPExecutableDirective(D);
2426}
2427
Alexey Bataev68446b72014-07-18 07:47:19 +00002428void
2429EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2430 VisitOMPExecutableDirective(D);
2431}
2432
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002433void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2434 VisitOMPExecutableDirective(D);
2435}
2436
Alexey Bataev2df347a2014-07-18 10:17:07 +00002437void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2438 VisitOMPExecutableDirective(D);
2439}
2440
Alexey Bataev6125da92014-07-21 11:26:11 +00002441void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2442 VisitOMPExecutableDirective(D);
2443}
2444
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002445void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2446 VisitOMPExecutableDirective(D);
2447}
2448
Alexey Bataev0162e452014-07-22 10:10:35 +00002449void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2450 VisitOMPExecutableDirective(D);
2451}
2452
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002453void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2454 VisitOMPExecutableDirective(D);
2455}
2456
Alexey Bataev13314bf2014-10-09 04:18:56 +00002457void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2458 VisitOMPExecutableDirective(D);
2459}
2460
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002461void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002462 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2463}
2464
2465bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2466 if (RegionOfInterest.isValid()) {
2467 SourceRange Range = getRawCursorExtent(C);
2468 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2469 return false;
2470 }
2471 return true;
2472}
2473
2474bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2475 while (!WL.empty()) {
2476 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002477 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002478
2479 // Set the Parent field, then back to its old value once we're done.
2480 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2481
2482 switch (LI.getKind()) {
2483 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002484 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002485 if (!D)
2486 continue;
2487
2488 // For now, perform default visitation for Decls.
2489 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2490 cast<DeclVisit>(&LI)->isFirst())))
2491 return true;
2492
2493 continue;
2494 }
2495 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2496 const ASTTemplateArgumentListInfo *ArgList =
2497 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2498 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2499 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2500 Arg != ArgEnd; ++Arg) {
2501 if (VisitTemplateArgumentLoc(*Arg))
2502 return true;
2503 }
2504 continue;
2505 }
2506 case VisitorJob::TypeLocVisitKind: {
2507 // Perform default visitation for TypeLocs.
2508 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2509 return true;
2510 continue;
2511 }
2512 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002513 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002514 if (LabelStmt *stmt = LS->getStmt()) {
2515 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2516 TU))) {
2517 return true;
2518 }
2519 }
2520 continue;
2521 }
2522
2523 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2524 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2525 if (VisitNestedNameSpecifierLoc(V->get()))
2526 return true;
2527 continue;
2528 }
2529
2530 case VisitorJob::DeclarationNameInfoVisitKind: {
2531 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2532 ->get()))
2533 return true;
2534 continue;
2535 }
2536 case VisitorJob::MemberRefVisitKind: {
2537 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2538 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2539 return true;
2540 continue;
2541 }
2542 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002543 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002544 if (!S)
2545 continue;
2546
2547 // Update the current cursor.
2548 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2549 if (!IsInRegionOfInterest(Cursor))
2550 continue;
2551 switch (Visitor(Cursor, Parent, ClientData)) {
2552 case CXChildVisit_Break: return true;
2553 case CXChildVisit_Continue: break;
2554 case CXChildVisit_Recurse:
2555 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002556 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002557 EnqueueWorkList(WL, S);
2558 break;
2559 }
2560 continue;
2561 }
2562 case VisitorJob::MemberExprPartsKind: {
2563 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002564 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002565
2566 // Visit the nested-name-specifier
2567 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2568 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2569 return true;
2570
2571 // Visit the declaration name.
2572 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2573 return true;
2574
2575 // Visit the explicitly-specified template arguments, if any.
2576 if (M->hasExplicitTemplateArgs()) {
2577 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2578 *ArgEnd = Arg + M->getNumTemplateArgs();
2579 Arg != ArgEnd; ++Arg) {
2580 if (VisitTemplateArgumentLoc(*Arg))
2581 return true;
2582 }
2583 }
2584 continue;
2585 }
2586 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002587 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002588 // Visit nested-name-specifier, if present.
2589 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2590 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2591 return true;
2592 // Visit declaration name.
2593 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2594 return true;
2595 continue;
2596 }
2597 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002598 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002599 // Visit the nested-name-specifier.
2600 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2601 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2602 return true;
2603 // Visit the declaration name.
2604 if (VisitDeclarationNameInfo(O->getNameInfo()))
2605 return true;
2606 // Visit the overloaded declaration reference.
2607 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2608 return true;
2609 continue;
2610 }
2611 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002612 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002613 NamedDecl *Pack = E->getPack();
2614 if (isa<TemplateTypeParmDecl>(Pack)) {
2615 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2616 E->getPackLoc(), TU)))
2617 return true;
2618
2619 continue;
2620 }
2621
2622 if (isa<TemplateTemplateParmDecl>(Pack)) {
2623 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2624 E->getPackLoc(), TU)))
2625 return true;
2626
2627 continue;
2628 }
2629
2630 // Non-type template parameter packs and function parameter packs are
2631 // treated like DeclRefExpr cursors.
2632 continue;
2633 }
2634
2635 case VisitorJob::LambdaExprPartsKind: {
2636 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002637 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002638 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2639 CEnd = E->explicit_capture_end();
2640 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002641 // FIXME: Lambda init-captures.
2642 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002643 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002644
Guy Benyei11169dd2012-12-18 14:30:41 +00002645 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2646 C->getLocation(),
2647 TU)))
2648 return true;
2649 }
2650
2651 // Visit parameters and return type, if present.
2652 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2653 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2654 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2655 // Visit the whole type.
2656 if (Visit(TL))
2657 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002658 } else if (FunctionProtoTypeLoc Proto =
2659 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002660 if (E->hasExplicitParameters()) {
2661 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002662 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2663 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002664 return true;
2665 } else {
2666 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002667 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002668 return true;
2669 }
2670 }
2671 }
2672 break;
2673 }
2674
2675 case VisitorJob::PostChildrenVisitKind:
2676 if (PostChildrenVisitor(Parent, ClientData))
2677 return true;
2678 break;
2679 }
2680 }
2681 return false;
2682}
2683
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002684bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002685 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002686 if (!WorkListFreeList.empty()) {
2687 WL = WorkListFreeList.back();
2688 WL->clear();
2689 WorkListFreeList.pop_back();
2690 }
2691 else {
2692 WL = new VisitorWorkList();
2693 WorkListCache.push_back(WL);
2694 }
2695 EnqueueWorkList(*WL, S);
2696 bool result = RunVisitorWorkList(*WL);
2697 WorkListFreeList.push_back(WL);
2698 return result;
2699}
2700
2701namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002702typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002703RefNamePieces
2704buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2705 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2706 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002707 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2708 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2709 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2710
2711 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2712
2713 RefNamePieces Pieces;
2714
2715 if (WantQualifier && QLoc.isValid())
2716 Pieces.push_back(QLoc);
2717
2718 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2719 Pieces.push_back(NI.getLoc());
2720
2721 if (WantTemplateArgs && TemplateArgs)
2722 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2723 TemplateArgs->RAngleLoc));
2724
2725 if (Kind == DeclarationName::CXXOperatorName) {
2726 Pieces.push_back(SourceLocation::getFromRawEncoding(
2727 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2728 Pieces.push_back(SourceLocation::getFromRawEncoding(
2729 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2730 }
2731
2732 if (WantSinglePiece) {
2733 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2734 Pieces.clear();
2735 Pieces.push_back(R);
2736 }
2737
2738 return Pieces;
2739}
2740}
2741
2742//===----------------------------------------------------------------------===//
2743// Misc. API hooks.
2744//===----------------------------------------------------------------------===//
2745
Chad Rosier05c71aa2013-03-27 18:28:23 +00002746static void fatal_error_handler(void *user_data, const std::string& reason,
2747 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002748 // Write the result out to stderr avoiding errs() because raw_ostreams can
2749 // call report_fatal_error.
2750 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2751 ::abort();
2752}
2753
Chandler Carruth66660742014-06-27 16:37:27 +00002754namespace {
2755struct RegisterFatalErrorHandler {
2756 RegisterFatalErrorHandler() {
2757 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2758 }
2759};
2760}
2761
2762static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2763
Guy Benyei11169dd2012-12-18 14:30:41 +00002764extern "C" {
2765CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2766 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002767 // We use crash recovery to make some of our APIs more reliable, implicitly
2768 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002769 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2770 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002771
Chandler Carruth66660742014-06-27 16:37:27 +00002772 // Look through the managed static to trigger construction of the managed
2773 // static which registers our fatal error handler. This ensures it is only
2774 // registered once.
2775 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002776
2777 CIndexer *CIdxr = new CIndexer();
2778 if (excludeDeclarationsFromPCH)
2779 CIdxr->setOnlyLocalDecls();
2780 if (displayDiagnostics)
2781 CIdxr->setDisplayDiagnostics();
2782
2783 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2784 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2785 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2786 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2787 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2788 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2789
2790 return CIdxr;
2791}
2792
2793void clang_disposeIndex(CXIndex CIdx) {
2794 if (CIdx)
2795 delete static_cast<CIndexer *>(CIdx);
2796}
2797
2798void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2799 if (CIdx)
2800 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2801}
2802
2803unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2804 if (CIdx)
2805 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2806 return 0;
2807}
2808
2809void clang_toggleCrashRecovery(unsigned isEnabled) {
2810 if (isEnabled)
2811 llvm::CrashRecoveryContext::Enable();
2812 else
2813 llvm::CrashRecoveryContext::Disable();
2814}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002815
Guy Benyei11169dd2012-12-18 14:30:41 +00002816CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2817 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002818 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002819 enum CXErrorCode Result =
2820 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002821 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002822 assert((TU && Result == CXError_Success) ||
2823 (!TU && Result != CXError_Success));
2824 return TU;
2825}
2826
2827enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2828 const char *ast_filename,
2829 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002830 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002831 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002832
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002833 if (!CIdx || !ast_filename || !out_TU)
2834 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002835
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002836 LOG_FUNC_SECTION {
2837 *Log << ast_filename;
2838 }
2839
Guy Benyei11169dd2012-12-18 14:30:41 +00002840 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2841 FileSystemOptions FileSystemOpts;
2842
Justin Bognerd512c1e2014-10-15 00:33:06 +00002843 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2844 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002845 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2846 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2847 /*CaptureDiagnostics=*/true,
2848 /*AllowPCHWithCompilerErrors=*/true,
2849 /*UserFilesAreVolatile=*/true);
2850 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002851 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002852}
2853
2854unsigned clang_defaultEditingTranslationUnitOptions() {
2855 return CXTranslationUnit_PrecompiledPreamble |
2856 CXTranslationUnit_CacheCompletionResults;
2857}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002858
Guy Benyei11169dd2012-12-18 14:30:41 +00002859CXTranslationUnit
2860clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2861 const char *source_filename,
2862 int num_command_line_args,
2863 const char * const *command_line_args,
2864 unsigned num_unsaved_files,
2865 struct CXUnsavedFile *unsaved_files) {
2866 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2867 return clang_parseTranslationUnit(CIdx, source_filename,
2868 command_line_args, num_command_line_args,
2869 unsaved_files, num_unsaved_files,
2870 Options);
2871}
2872
2873struct ParseTranslationUnitInfo {
2874 CXIndex CIdx;
2875 const char *source_filename;
2876 const char *const *command_line_args;
2877 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002878 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002879 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002880 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002881 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002882};
2883static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002884 const ParseTranslationUnitInfo *PTUI =
2885 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002886 CXIndex CIdx = PTUI->CIdx;
2887 const char *source_filename = PTUI->source_filename;
2888 const char * const *command_line_args = PTUI->command_line_args;
2889 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002890 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002891 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002892
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002893 // Set up the initial return values.
2894 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002895 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002896
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002897 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002898 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002899 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002900 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002901 }
2902
Guy Benyei11169dd2012-12-18 14:30:41 +00002903 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2904
2905 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2906 setThreadBackgroundPriority();
2907
2908 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2909 // FIXME: Add a flag for modules.
2910 TranslationUnitKind TUKind
2911 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002912 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002913 = options & CXTranslationUnit_CacheCompletionResults;
2914 bool IncludeBriefCommentsInCodeCompletion
2915 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2916 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2917 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2918
2919 // Configure the diagnostics.
2920 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002921 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002922
2923 // Recover resources if we crash before exiting this function.
2924 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2925 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002926 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002927
Ahmed Charlesb8984322014-03-07 20:03:18 +00002928 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2929 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002930
2931 // Recover resources if we crash before exiting this function.
2932 llvm::CrashRecoveryContextCleanupRegistrar<
2933 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2934
Alp Toker9d85b182014-07-07 01:23:14 +00002935 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002936 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002937 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002938 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002939 }
2940
Ahmed Charlesb8984322014-03-07 20:03:18 +00002941 std::unique_ptr<std::vector<const char *>> Args(
2942 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002943
2944 // Recover resources if we crash before exiting this method.
2945 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2946 ArgsCleanup(Args.get());
2947
2948 // Since the Clang C library is primarily used by batch tools dealing with
2949 // (often very broken) source code, where spell-checking can have a
2950 // significant negative impact on performance (particularly when
2951 // precompiled headers are involved), we disable it by default.
2952 // Only do this if we haven't found a spell-checking-related argument.
2953 bool FoundSpellCheckingArgument = false;
2954 for (int I = 0; I != num_command_line_args; ++I) {
2955 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2956 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2957 FoundSpellCheckingArgument = true;
2958 break;
2959 }
2960 }
2961 if (!FoundSpellCheckingArgument)
2962 Args->push_back("-fno-spell-checking");
2963
2964 Args->insert(Args->end(), command_line_args,
2965 command_line_args + num_command_line_args);
2966
2967 // The 'source_filename' argument is optional. If the caller does not
2968 // specify it then it is assumed that the source file is specified
2969 // in the actual argument list.
2970 // Put the source file after command_line_args otherwise if '-x' flag is
2971 // present it will be unused.
2972 if (source_filename)
2973 Args->push_back(source_filename);
2974
2975 // Do we need the detailed preprocessing record?
2976 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2977 Args->push_back("-Xclang");
2978 Args->push_back("-detailed-preprocessing-record");
2979 }
2980
2981 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002982 std::unique_ptr<ASTUnit> ErrUnit;
2983 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002984 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002985 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2986 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2987 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2988 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2989 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2990 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002991
2992 if (NumErrors != Diags->getClient()->getNumErrors()) {
2993 // Make sure to check that 'Unit' is non-NULL.
2994 if (CXXIdx->getDisplayDiagnostics())
2995 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2996 }
2997
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2999 PTUI->result = CXError_ASTReadError;
3000 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003001 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003002 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3003 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003004}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003005
3006CXTranslationUnit
3007clang_parseTranslationUnit(CXIndex CIdx,
3008 const char *source_filename,
3009 const char *const *command_line_args,
3010 int num_command_line_args,
3011 struct CXUnsavedFile *unsaved_files,
3012 unsigned num_unsaved_files,
3013 unsigned options) {
3014 CXTranslationUnit TU;
3015 enum CXErrorCode Result = clang_parseTranslationUnit2(
3016 CIdx, source_filename, command_line_args, num_command_line_args,
3017 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003018 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003019 assert((TU && Result == CXError_Success) ||
3020 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003021 return TU;
3022}
3023
3024enum CXErrorCode clang_parseTranslationUnit2(
3025 CXIndex CIdx,
3026 const char *source_filename,
3027 const char *const *command_line_args,
3028 int num_command_line_args,
3029 struct CXUnsavedFile *unsaved_files,
3030 unsigned num_unsaved_files,
3031 unsigned options,
3032 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003033 LOG_FUNC_SECTION {
3034 *Log << source_filename << ": ";
3035 for (int i = 0; i != num_command_line_args; ++i)
3036 *Log << command_line_args[i] << " ";
3037 }
3038
Alp Toker9d85b182014-07-07 01:23:14 +00003039 if (num_unsaved_files && !unsaved_files)
3040 return CXError_InvalidArguments;
3041
Alp Toker5c532982014-07-07 22:42:03 +00003042 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003043 ParseTranslationUnitInfo PTUI = {
3044 CIdx,
3045 source_filename,
3046 command_line_args,
3047 num_command_line_args,
3048 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3049 options,
3050 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003051 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003052 llvm::CrashRecoveryContext CRC;
3053
3054 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3055 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3056 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3057 fprintf(stderr, " 'command_line_args' : [");
3058 for (int i = 0; i != num_command_line_args; ++i) {
3059 if (i)
3060 fprintf(stderr, ", ");
3061 fprintf(stderr, "'%s'", command_line_args[i]);
3062 }
3063 fprintf(stderr, "],\n");
3064 fprintf(stderr, " 'unsaved_files' : [");
3065 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3066 if (i)
3067 fprintf(stderr, ", ");
3068 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3069 unsaved_files[i].Length);
3070 }
3071 fprintf(stderr, "],\n");
3072 fprintf(stderr, " 'options' : %d,\n", options);
3073 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003074
3075 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003076 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003077 if (CXTranslationUnit *TU = PTUI.out_TU)
3078 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003079 }
Alp Toker5c532982014-07-07 22:42:03 +00003080
3081 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003082}
3083
3084unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3085 return CXSaveTranslationUnit_None;
3086}
3087
3088namespace {
3089
3090struct SaveTranslationUnitInfo {
3091 CXTranslationUnit TU;
3092 const char *FileName;
3093 unsigned options;
3094 CXSaveError result;
3095};
3096
3097}
3098
3099static void clang_saveTranslationUnit_Impl(void *UserData) {
3100 SaveTranslationUnitInfo *STUI =
3101 static_cast<SaveTranslationUnitInfo*>(UserData);
3102
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003103 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003104 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3105 setThreadBackgroundPriority();
3106
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003107 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003108 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3109}
3110
3111int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3112 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003113 LOG_FUNC_SECTION {
3114 *Log << TU << ' ' << FileName;
3115 }
3116
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003117 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003118 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003119 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003120 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003121
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003122 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003123 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3124 if (!CXXUnit->hasSema())
3125 return CXSaveError_InvalidTU;
3126
3127 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3128
3129 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3130 getenv("LIBCLANG_NOTHREADS")) {
3131 clang_saveTranslationUnit_Impl(&STUI);
3132
3133 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3134 PrintLibclangResourceUsage(TU);
3135
3136 return STUI.result;
3137 }
3138
3139 // We have an AST that has invalid nodes due to compiler errors.
3140 // Use a crash recovery thread for protection.
3141
3142 llvm::CrashRecoveryContext CRC;
3143
3144 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3145 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3146 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3147 fprintf(stderr, " 'options' : %d,\n", options);
3148 fprintf(stderr, "}\n");
3149
3150 return CXSaveError_Unknown;
3151
3152 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3153 PrintLibclangResourceUsage(TU);
3154 }
3155
3156 return STUI.result;
3157}
3158
3159void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3160 if (CTUnit) {
3161 // If the translation unit has been marked as unsafe to free, just discard
3162 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003163 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3164 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 return;
3166
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003167 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003168 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003169 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3170 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003171 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003172 delete CTUnit;
3173 }
3174}
3175
3176unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3177 return CXReparse_None;
3178}
3179
3180struct ReparseTranslationUnitInfo {
3181 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003182 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003184 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003185};
3186
3187static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003188 const ReparseTranslationUnitInfo *RTUI =
3189 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003191 unsigned options = RTUI->options;
3192 (void) options;
3193
3194 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003195 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003196 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003197 RTUI->result = CXError_InvalidArguments;
3198 return;
3199 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003200
3201 // Reset the associated diagnostics.
3202 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003203 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003204
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003205 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3207 setThreadBackgroundPriority();
3208
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003209 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003211
3212 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3213 new std::vector<ASTUnit::RemappedFile>());
3214
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 // Recover resources if we crash before exiting this function.
3216 llvm::CrashRecoveryContextCleanupRegistrar<
3217 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003218
3219 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003220 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003221 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003222 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003224
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003225 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003226 RTUI->result = CXError_Success;
3227 else if (isASTReadError(CXXUnit))
3228 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003229}
3230
3231int clang_reparseTranslationUnit(CXTranslationUnit TU,
3232 unsigned num_unsaved_files,
3233 struct CXUnsavedFile *unsaved_files,
3234 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003235 LOG_FUNC_SECTION {
3236 *Log << TU;
3237 }
3238
Alp Toker9d85b182014-07-07 01:23:14 +00003239 if (num_unsaved_files && !unsaved_files)
3240 return CXError_InvalidArguments;
3241
Alp Toker5c532982014-07-07 22:42:03 +00003242 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003243 ReparseTranslationUnitInfo RTUI = {
3244 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003245 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003246
3247 if (getenv("LIBCLANG_NOTHREADS")) {
3248 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003249 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003250 }
3251
3252 llvm::CrashRecoveryContext CRC;
3253
3254 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3255 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003256 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003257 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003258 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3259 PrintLibclangResourceUsage(TU);
3260
Alp Toker5c532982014-07-07 22:42:03 +00003261 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003262}
3263
3264
3265CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003266 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003267 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003268 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003269 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003270
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003271 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003272 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003273}
3274
3275CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003276 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003277 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003278 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003279 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003280
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003281 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3283}
3284
3285} // end: extern "C"
3286
3287//===----------------------------------------------------------------------===//
3288// CXFile Operations.
3289//===----------------------------------------------------------------------===//
3290
3291extern "C" {
3292CXString clang_getFileName(CXFile SFile) {
3293 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003294 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003295
3296 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003297 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003298}
3299
3300time_t clang_getFileTime(CXFile SFile) {
3301 if (!SFile)
3302 return 0;
3303
3304 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3305 return FEnt->getModificationTime();
3306}
3307
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003308CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003309 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003310 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003311 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003312 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003313
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003314 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003315
3316 FileManager &FMgr = CXXUnit->getFileManager();
3317 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3318}
3319
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003320unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3321 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003322 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003323 LOG_BAD_TU(TU);
3324 return 0;
3325 }
3326
3327 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 return 0;
3329
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003330 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 FileEntry *FEnt = static_cast<FileEntry *>(file);
3332 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3333 .isFileMultipleIncludeGuarded(FEnt);
3334}
3335
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003336int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3337 if (!file || !outID)
3338 return 1;
3339
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003340 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003341 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3342 outID->data[0] = ID.getDevice();
3343 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003344 outID->data[2] = FEnt->getModificationTime();
3345 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003346}
3347
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003348int clang_File_isEqual(CXFile file1, CXFile file2) {
3349 if (file1 == file2)
3350 return true;
3351
3352 if (!file1 || !file2)
3353 return false;
3354
3355 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3356 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3357 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3358}
3359
Guy Benyei11169dd2012-12-18 14:30:41 +00003360} // end: extern "C"
3361
3362//===----------------------------------------------------------------------===//
3363// CXCursor Operations.
3364//===----------------------------------------------------------------------===//
3365
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003366static const Decl *getDeclFromExpr(const Stmt *E) {
3367 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 return getDeclFromExpr(CE->getSubExpr());
3369
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003370 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003372 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003374 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003376 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 if (PRE->isExplicitProperty())
3378 return PRE->getExplicitProperty();
3379 // It could be messaging both getter and setter as in:
3380 // ++myobj.myprop;
3381 // in which case prefer to associate the setter since it is less obvious
3382 // from inspecting the source that the setter is going to get called.
3383 if (PRE->isMessagingSetter())
3384 return PRE->getImplicitPropertySetter();
3385 return PRE->getImplicitPropertyGetter();
3386 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003387 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003389 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 if (Expr *Src = OVE->getSourceExpr())
3391 return getDeclFromExpr(Src);
3392
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003393 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003395 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 if (!CE->isElidable())
3397 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003398 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 return OME->getMethodDecl();
3400
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003401 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003402 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003403 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3405 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003406 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3408 isa<ParmVarDecl>(SizeOfPack->getPack()))
3409 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003410
3411 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003412}
3413
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003414static SourceLocation getLocationFromExpr(const Expr *E) {
3415 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 return getLocationFromExpr(CE->getSubExpr());
3417
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003418 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003420 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003422 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003424 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003426 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003428 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 return PropRef->getLocation();
3430
3431 return E->getLocStart();
3432}
3433
3434extern "C" {
3435
3436unsigned clang_visitChildren(CXCursor parent,
3437 CXCursorVisitor visitor,
3438 CXClientData client_data) {
3439 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3440 /*VisitPreprocessorLast=*/false);
3441 return CursorVis.VisitChildren(parent);
3442}
3443
3444#ifndef __has_feature
3445#define __has_feature(x) 0
3446#endif
3447#if __has_feature(blocks)
3448typedef enum CXChildVisitResult
3449 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3450
3451static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3452 CXClientData client_data) {
3453 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3454 return block(cursor, parent);
3455}
3456#else
3457// If we are compiled with a compiler that doesn't have native blocks support,
3458// define and call the block manually, so the
3459typedef struct _CXChildVisitResult
3460{
3461 void *isa;
3462 int flags;
3463 int reserved;
3464 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3465 CXCursor);
3466} *CXCursorVisitorBlock;
3467
3468static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3469 CXClientData client_data) {
3470 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3471 return block->invoke(block, cursor, parent);
3472}
3473#endif
3474
3475
3476unsigned clang_visitChildrenWithBlock(CXCursor parent,
3477 CXCursorVisitorBlock block) {
3478 return clang_visitChildren(parent, visitWithBlock, block);
3479}
3480
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003481static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003482 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003483 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003484
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003485 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003487 if (const ObjCPropertyImplDecl *PropImpl =
3488 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003490 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003491
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003492 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003494 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003495
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003496 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 }
3498
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003499 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003500 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003501
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003502 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3504 // and returns different names. NamedDecl returns the class name and
3505 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003506 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003507
3508 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003509 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003510
3511 SmallString<1024> S;
3512 llvm::raw_svector_ostream os(S);
3513 ND->printName(os);
3514
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003515 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003516}
3517
3518CXString clang_getCursorSpelling(CXCursor C) {
3519 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003520 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003521
3522 if (clang_isReference(C.kind)) {
3523 switch (C.kind) {
3524 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003525 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003526 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 }
3528 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003529 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003530 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 }
3532 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003533 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003535 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 }
3537 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003538 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003539 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 }
3541 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003542 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 assert(Type && "Missing type decl");
3544
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003545 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 getAsString());
3547 }
3548 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003549 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003550 assert(Template && "Missing template decl");
3551
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003552 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 }
3554
3555 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003556 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 assert(NS && "Missing namespace decl");
3558
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003559 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 }
3561
3562 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003563 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 assert(Field && "Missing member decl");
3565
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003566 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 }
3568
3569 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003570 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 assert(Label && "Missing label");
3572
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003573 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 }
3575
3576 case CXCursor_OverloadedDeclRef: {
3577 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003578 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3579 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003580 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003581 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003583 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003584 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 OverloadedTemplateStorage *Ovl
3586 = Storage.get<OverloadedTemplateStorage*>();
3587 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003588 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003589 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 }
3591
3592 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003593 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 assert(Var && "Missing variable decl");
3595
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003596 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 }
3598
3599 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003600 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 }
3602 }
3603
3604 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003605 const Expr *E = getCursorExpr(C);
3606
3607 if (C.kind == CXCursor_ObjCStringLiteral ||
3608 C.kind == CXCursor_StringLiteral) {
3609 const StringLiteral *SLit;
3610 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3611 SLit = OSL->getString();
3612 } else {
3613 SLit = cast<StringLiteral>(E);
3614 }
3615 SmallString<256> Buf;
3616 llvm::raw_svector_ostream OS(Buf);
3617 SLit->outputString(OS);
3618 return cxstring::createDup(OS.str());
3619 }
3620
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003621 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 if (D)
3623 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003624 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 }
3626
3627 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003628 const Stmt *S = getCursorStmt(C);
3629 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003631
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003632 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 }
3634
3635 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 ->getNameStart());
3638
3639 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 ->getNameStart());
3642
3643 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003644 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003645
3646 if (clang_isDeclaration(C.kind))
3647 return getDeclSpelling(getCursorDecl(C));
3648
3649 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003650 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003651 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 }
3653
3654 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003655 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003656 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 }
3658
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003659 if (C.kind == CXCursor_PackedAttr) {
3660 return cxstring::createRef("packed");
3661 }
3662
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003663 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003664}
3665
3666CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3667 unsigned pieceIndex,
3668 unsigned options) {
3669 if (clang_Cursor_isNull(C))
3670 return clang_getNullRange();
3671
3672 ASTContext &Ctx = getCursorContext(C);
3673
3674 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003675 const Stmt *S = getCursorStmt(C);
3676 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 if (pieceIndex > 0)
3678 return clang_getNullRange();
3679 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3680 }
3681
3682 return clang_getNullRange();
3683 }
3684
3685 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003686 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3688 if (pieceIndex >= ME->getNumSelectorLocs())
3689 return clang_getNullRange();
3690 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3691 }
3692 }
3693
3694 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3695 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003696 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3698 if (pieceIndex >= MD->getNumSelectorLocs())
3699 return clang_getNullRange();
3700 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3701 }
3702 }
3703
3704 if (C.kind == CXCursor_ObjCCategoryDecl ||
3705 C.kind == CXCursor_ObjCCategoryImplDecl) {
3706 if (pieceIndex > 0)
3707 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003708 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3710 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003711 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3713 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3714 }
3715
3716 if (C.kind == CXCursor_ModuleImportDecl) {
3717 if (pieceIndex > 0)
3718 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003719 if (const ImportDecl *ImportD =
3720 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3722 if (!Locs.empty())
3723 return cxloc::translateSourceRange(Ctx,
3724 SourceRange(Locs.front(), Locs.back()));
3725 }
3726 return clang_getNullRange();
3727 }
3728
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003729 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3730 C.kind == CXCursor_ConversionFunction) {
3731 if (pieceIndex > 0)
3732 return clang_getNullRange();
3733 if (const FunctionDecl *FD =
3734 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3735 DeclarationNameInfo FunctionName = FD->getNameInfo();
3736 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3737 }
3738 return clang_getNullRange();
3739 }
3740
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 // FIXME: A CXCursor_InclusionDirective should give the location of the
3742 // filename, but we don't keep track of this.
3743
3744 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3745 // but we don't keep track of this.
3746
3747 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3748 // but we don't keep track of this.
3749
3750 // Default handling, give the location of the cursor.
3751
3752 if (pieceIndex > 0)
3753 return clang_getNullRange();
3754
3755 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3756 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3757 return cxloc::translateSourceRange(Ctx, Loc);
3758}
3759
Eli Bendersky44a206f2014-07-31 18:04:56 +00003760CXString clang_Cursor_getMangling(CXCursor C) {
3761 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3762 return cxstring::createEmpty();
3763
Eli Bendersky44a206f2014-07-31 18:04:56 +00003764 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003765 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003766 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3767 return cxstring::createEmpty();
3768
Eli Bendersky79759592014-08-01 15:01:10 +00003769 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003770 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003771 ASTContext &Ctx = ND->getASTContext();
3772 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003773
Eli Bendersky79759592014-08-01 15:01:10 +00003774 std::string FrontendBuf;
3775 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3776 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003777
Eli Bendersky79759592014-08-01 15:01:10 +00003778 // Now apply backend mangling.
3779 std::unique_ptr<llvm::DataLayout> DL(
3780 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3781 llvm::Mangler BackendMangler(DL.get());
3782
3783 std::string FinalBuf;
3784 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3785 BackendMangler.getNameWithPrefix(FinalBufOS,
3786 llvm::Twine(FrontendBufOS.str()));
3787
3788 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003789}
3790
Guy Benyei11169dd2012-12-18 14:30:41 +00003791CXString clang_getCursorDisplayName(CXCursor C) {
3792 if (!clang_isDeclaration(C.kind))
3793 return clang_getCursorSpelling(C);
3794
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003795 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003797 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003798
3799 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003800 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 D = FunTmpl->getTemplatedDecl();
3802
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003803 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 SmallString<64> Str;
3805 llvm::raw_svector_ostream OS(Str);
3806 OS << *Function;
3807 if (Function->getPrimaryTemplate())
3808 OS << "<>";
3809 OS << "(";
3810 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3811 if (I)
3812 OS << ", ";
3813 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3814 }
3815
3816 if (Function->isVariadic()) {
3817 if (Function->getNumParams())
3818 OS << ", ";
3819 OS << "...";
3820 }
3821 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003822 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 }
3824
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003825 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 SmallString<64> Str;
3827 llvm::raw_svector_ostream OS(Str);
3828 OS << *ClassTemplate;
3829 OS << "<";
3830 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3831 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3832 if (I)
3833 OS << ", ";
3834
3835 NamedDecl *Param = Params->getParam(I);
3836 if (Param->getIdentifier()) {
3837 OS << Param->getIdentifier()->getName();
3838 continue;
3839 }
3840
3841 // There is no parameter name, which makes this tricky. Try to come up
3842 // with something useful that isn't too long.
3843 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3844 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3845 else if (NonTypeTemplateParmDecl *NTTP
3846 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3847 OS << NTTP->getType().getAsString(Policy);
3848 else
3849 OS << "template<...> class";
3850 }
3851
3852 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003853 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 }
3855
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003856 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3858 // If the type was explicitly written, use that.
3859 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003860 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003861
Benjamin Kramer9170e912013-02-22 15:46:01 +00003862 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 llvm::raw_svector_ostream OS(Str);
3864 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003865 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 ClassSpec->getTemplateArgs().data(),
3867 ClassSpec->getTemplateArgs().size(),
3868 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003869 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 }
3871
3872 return clang_getCursorSpelling(C);
3873}
3874
3875CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3876 switch (Kind) {
3877 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004005 case CXCursor_ObjCSelfExpr:
4006 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004095 case CXCursor_SEHLeaveStmt:
4096 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004125 case CXCursor_PackedAttr:
4126 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004127 case CXCursor_PureAttr:
4128 return cxstring::createRef("attribute(pure)");
4129 case CXCursor_ConstAttr:
4130 return cxstring::createRef("attribute(const)");
4131 case CXCursor_NoDuplicateAttr:
4132 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004133 case CXCursor_CUDAConstantAttr:
4134 return cxstring::createRef("attribute(constant)");
4135 case CXCursor_CUDADeviceAttr:
4136 return cxstring::createRef("attribute(device)");
4137 case CXCursor_CUDAGlobalAttr:
4138 return cxstring::createRef("attribute(global)");
4139 case CXCursor_CUDAHostAttr:
4140 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004141 case CXCursor_CUDASharedAttr:
4142 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004191 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004192 return cxstring::createRef("OMPParallelDirective");
4193 case CXCursor_OMPSimdDirective:
4194 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004195 case CXCursor_OMPForDirective:
4196 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004197 case CXCursor_OMPForSimdDirective:
4198 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004199 case CXCursor_OMPSectionsDirective:
4200 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004201 case CXCursor_OMPSectionDirective:
4202 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004203 case CXCursor_OMPSingleDirective:
4204 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004205 case CXCursor_OMPMasterDirective:
4206 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004207 case CXCursor_OMPCriticalDirective:
4208 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004209 case CXCursor_OMPParallelForDirective:
4210 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004211 case CXCursor_OMPParallelForSimdDirective:
4212 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004213 case CXCursor_OMPParallelSectionsDirective:
4214 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004215 case CXCursor_OMPTaskDirective:
4216 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004217 case CXCursor_OMPTaskyieldDirective:
4218 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004219 case CXCursor_OMPBarrierDirective:
4220 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004221 case CXCursor_OMPTaskwaitDirective:
4222 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004223 case CXCursor_OMPFlushDirective:
4224 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004225 case CXCursor_OMPOrderedDirective:
4226 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004227 case CXCursor_OMPAtomicDirective:
4228 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004229 case CXCursor_OMPTargetDirective:
4230 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004231 case CXCursor_OMPTeamsDirective:
4232 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004233 case CXCursor_OverloadCandidate:
4234 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 }
4236
4237 llvm_unreachable("Unhandled CXCursorKind");
4238}
4239
4240struct GetCursorData {
4241 SourceLocation TokenBeginLoc;
4242 bool PointsAtMacroArgExpansion;
4243 bool VisitedObjCPropertyImplDecl;
4244 SourceLocation VisitedDeclaratorDeclStartLoc;
4245 CXCursor &BestCursor;
4246
4247 GetCursorData(SourceManager &SM,
4248 SourceLocation tokenBegin, CXCursor &outputCursor)
4249 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4250 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4251 VisitedObjCPropertyImplDecl = false;
4252 }
4253};
4254
4255static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4256 CXCursor parent,
4257 CXClientData client_data) {
4258 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4259 CXCursor *BestCursor = &Data->BestCursor;
4260
4261 // If we point inside a macro argument we should provide info of what the
4262 // token is so use the actual cursor, don't replace it with a macro expansion
4263 // cursor.
4264 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4265 return CXChildVisit_Recurse;
4266
4267 if (clang_isDeclaration(cursor.kind)) {
4268 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004269 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4271 if (MD->isImplicit())
4272 return CXChildVisit_Break;
4273
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004274 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4276 // Check that when we have multiple @class references in the same line,
4277 // that later ones do not override the previous ones.
4278 // If we have:
4279 // @class Foo, Bar;
4280 // source ranges for both start at '@', so 'Bar' will end up overriding
4281 // 'Foo' even though the cursor location was at 'Foo'.
4282 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4283 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004284 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4286 if (PrevID != ID &&
4287 !PrevID->isThisDeclarationADefinition() &&
4288 !ID->isThisDeclarationADefinition())
4289 return CXChildVisit_Break;
4290 }
4291
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004292 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4294 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4295 // Check that when we have multiple declarators in the same line,
4296 // that later ones do not override the previous ones.
4297 // If we have:
4298 // int Foo, Bar;
4299 // source ranges for both start at 'int', so 'Bar' will end up overriding
4300 // 'Foo' even though the cursor location was at 'Foo'.
4301 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4302 return CXChildVisit_Break;
4303 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4304
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004305 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4307 (void)PropImp;
4308 // Check that when we have multiple @synthesize in the same line,
4309 // that later ones do not override the previous ones.
4310 // If we have:
4311 // @synthesize Foo, Bar;
4312 // source ranges for both start at '@', so 'Bar' will end up overriding
4313 // 'Foo' even though the cursor location was at 'Foo'.
4314 if (Data->VisitedObjCPropertyImplDecl)
4315 return CXChildVisit_Break;
4316 Data->VisitedObjCPropertyImplDecl = true;
4317 }
4318 }
4319
4320 if (clang_isExpression(cursor.kind) &&
4321 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004322 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 // Avoid having the cursor of an expression replace the declaration cursor
4324 // when the expression source range overlaps the declaration range.
4325 // This can happen for C++ constructor expressions whose range generally
4326 // include the variable declaration, e.g.:
4327 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4328 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4329 D->getLocation() == Data->TokenBeginLoc)
4330 return CXChildVisit_Break;
4331 }
4332 }
4333
4334 // If our current best cursor is the construction of a temporary object,
4335 // don't replace that cursor with a type reference, because we want
4336 // clang_getCursor() to point at the constructor.
4337 if (clang_isExpression(BestCursor->kind) &&
4338 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4339 cursor.kind == CXCursor_TypeRef) {
4340 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4341 // as having the actual point on the type reference.
4342 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4343 return CXChildVisit_Recurse;
4344 }
4345
4346 *BestCursor = cursor;
4347 return CXChildVisit_Recurse;
4348}
4349
4350CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004351 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004352 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004353 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004354 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004355
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004356 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004357 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4358
4359 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4360 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4361
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004362 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 CXFile SearchFile;
4364 unsigned SearchLine, SearchColumn;
4365 CXFile ResultFile;
4366 unsigned ResultLine, ResultColumn;
4367 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4368 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4369 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004370
4371 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4372 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004373 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004374 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004375 SearchFileName = clang_getFileName(SearchFile);
4376 ResultFileName = clang_getFileName(ResultFile);
4377 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4378 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004379 *Log << llvm::format("(%s:%d:%d) = %s",
4380 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4381 clang_getCString(KindSpelling))
4382 << llvm::format("(%s:%d:%d):%s%s",
4383 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4384 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004385 clang_disposeString(SearchFileName);
4386 clang_disposeString(ResultFileName);
4387 clang_disposeString(KindSpelling);
4388 clang_disposeString(USR);
4389
4390 CXCursor Definition = clang_getCursorDefinition(Result);
4391 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4392 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4393 CXString DefinitionKindSpelling
4394 = clang_getCursorKindSpelling(Definition.kind);
4395 CXFile DefinitionFile;
4396 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004397 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004398 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004400 *Log << llvm::format(" -> %s(%s:%d:%d)",
4401 clang_getCString(DefinitionKindSpelling),
4402 clang_getCString(DefinitionFileName),
4403 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 clang_disposeString(DefinitionFileName);
4405 clang_disposeString(DefinitionKindSpelling);
4406 }
4407 }
4408
4409 return Result;
4410}
4411
4412CXCursor clang_getNullCursor(void) {
4413 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4414}
4415
4416unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004417 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4418 // can't set consistently. For example, when visiting a DeclStmt we will set
4419 // it but we don't set it on the result of clang_getCursorDefinition for
4420 // a reference of the same declaration.
4421 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4422 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4423 // to provide that kind of info.
4424 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004425 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004426 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004427 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004428
Guy Benyei11169dd2012-12-18 14:30:41 +00004429 return X == Y;
4430}
4431
4432unsigned clang_hashCursor(CXCursor C) {
4433 unsigned Index = 0;
4434 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4435 Index = 1;
4436
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004437 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 std::make_pair(C.kind, C.data[Index]));
4439}
4440
4441unsigned clang_isInvalid(enum CXCursorKind K) {
4442 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4443}
4444
4445unsigned clang_isDeclaration(enum CXCursorKind K) {
4446 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4447 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4448}
4449
4450unsigned clang_isReference(enum CXCursorKind K) {
4451 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4452}
4453
4454unsigned clang_isExpression(enum CXCursorKind K) {
4455 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4456}
4457
4458unsigned clang_isStatement(enum CXCursorKind K) {
4459 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4460}
4461
4462unsigned clang_isAttribute(enum CXCursorKind K) {
4463 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4464}
4465
4466unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4467 return K == CXCursor_TranslationUnit;
4468}
4469
4470unsigned clang_isPreprocessing(enum CXCursorKind K) {
4471 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4472}
4473
4474unsigned clang_isUnexposed(enum CXCursorKind K) {
4475 switch (K) {
4476 case CXCursor_UnexposedDecl:
4477 case CXCursor_UnexposedExpr:
4478 case CXCursor_UnexposedStmt:
4479 case CXCursor_UnexposedAttr:
4480 return true;
4481 default:
4482 return false;
4483 }
4484}
4485
4486CXCursorKind clang_getCursorKind(CXCursor C) {
4487 return C.kind;
4488}
4489
4490CXSourceLocation clang_getCursorLocation(CXCursor C) {
4491 if (clang_isReference(C.kind)) {
4492 switch (C.kind) {
4493 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004494 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 = getCursorObjCSuperClassRef(C);
4496 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4497 }
4498
4499 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004500 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 = getCursorObjCProtocolRef(C);
4502 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4503 }
4504
4505 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004506 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 = getCursorObjCClassRef(C);
4508 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4509 }
4510
4511 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004512 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4514 }
4515
4516 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004517 std::pair<const TemplateDecl *, SourceLocation> P =
4518 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4520 }
4521
4522 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004523 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4525 }
4526
4527 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004528 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4530 }
4531
4532 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004533 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4535 }
4536
4537 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004538 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 if (!BaseSpec)
4540 return clang_getNullLocation();
4541
4542 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4543 return cxloc::translateSourceLocation(getCursorContext(C),
4544 TSInfo->getTypeLoc().getBeginLoc());
4545
4546 return cxloc::translateSourceLocation(getCursorContext(C),
4547 BaseSpec->getLocStart());
4548 }
4549
4550 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004551 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4553 }
4554
4555 case CXCursor_OverloadedDeclRef:
4556 return cxloc::translateSourceLocation(getCursorContext(C),
4557 getCursorOverloadedDeclRef(C).second);
4558
4559 default:
4560 // FIXME: Need a way to enumerate all non-reference cases.
4561 llvm_unreachable("Missed a reference kind");
4562 }
4563 }
4564
4565 if (clang_isExpression(C.kind))
4566 return cxloc::translateSourceLocation(getCursorContext(C),
4567 getLocationFromExpr(getCursorExpr(C)));
4568
4569 if (clang_isStatement(C.kind))
4570 return cxloc::translateSourceLocation(getCursorContext(C),
4571 getCursorStmt(C)->getLocStart());
4572
4573 if (C.kind == CXCursor_PreprocessingDirective) {
4574 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4575 return cxloc::translateSourceLocation(getCursorContext(C), L);
4576 }
4577
4578 if (C.kind == CXCursor_MacroExpansion) {
4579 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004580 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 return cxloc::translateSourceLocation(getCursorContext(C), L);
4582 }
4583
4584 if (C.kind == CXCursor_MacroDefinition) {
4585 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4586 return cxloc::translateSourceLocation(getCursorContext(C), L);
4587 }
4588
4589 if (C.kind == CXCursor_InclusionDirective) {
4590 SourceLocation L
4591 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4592 return cxloc::translateSourceLocation(getCursorContext(C), L);
4593 }
4594
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004595 if (clang_isAttribute(C.kind)) {
4596 SourceLocation L
4597 = cxcursor::getCursorAttr(C)->getLocation();
4598 return cxloc::translateSourceLocation(getCursorContext(C), L);
4599 }
4600
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 if (!clang_isDeclaration(C.kind))
4602 return clang_getNullLocation();
4603
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004604 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 if (!D)
4606 return clang_getNullLocation();
4607
4608 SourceLocation Loc = D->getLocation();
4609 // FIXME: Multiple variables declared in a single declaration
4610 // currently lack the information needed to correctly determine their
4611 // ranges when accounting for the type-specifier. We use context
4612 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4613 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004614 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 if (!cxcursor::isFirstInDeclGroup(C))
4616 Loc = VD->getLocation();
4617 }
4618
4619 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004620 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 Loc = MD->getSelectorStartLoc();
4622
4623 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4624}
4625
4626} // end extern "C"
4627
4628CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4629 assert(TU);
4630
4631 // Guard against an invalid SourceLocation, or we may assert in one
4632 // of the following calls.
4633 if (SLoc.isInvalid())
4634 return clang_getNullCursor();
4635
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004636 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004637
4638 // Translate the given source location to make it point at the beginning of
4639 // the token under the cursor.
4640 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4641 CXXUnit->getASTContext().getLangOpts());
4642
4643 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4644 if (SLoc.isValid()) {
4645 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4646 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4647 /*VisitPreprocessorLast=*/true,
4648 /*VisitIncludedEntities=*/false,
4649 SourceLocation(SLoc));
4650 CursorVis.visitFileRegion();
4651 }
4652
4653 return Result;
4654}
4655
4656static SourceRange getRawCursorExtent(CXCursor C) {
4657 if (clang_isReference(C.kind)) {
4658 switch (C.kind) {
4659 case CXCursor_ObjCSuperClassRef:
4660 return getCursorObjCSuperClassRef(C).second;
4661
4662 case CXCursor_ObjCProtocolRef:
4663 return getCursorObjCProtocolRef(C).second;
4664
4665 case CXCursor_ObjCClassRef:
4666 return getCursorObjCClassRef(C).second;
4667
4668 case CXCursor_TypeRef:
4669 return getCursorTypeRef(C).second;
4670
4671 case CXCursor_TemplateRef:
4672 return getCursorTemplateRef(C).second;
4673
4674 case CXCursor_NamespaceRef:
4675 return getCursorNamespaceRef(C).second;
4676
4677 case CXCursor_MemberRef:
4678 return getCursorMemberRef(C).second;
4679
4680 case CXCursor_CXXBaseSpecifier:
4681 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4682
4683 case CXCursor_LabelRef:
4684 return getCursorLabelRef(C).second;
4685
4686 case CXCursor_OverloadedDeclRef:
4687 return getCursorOverloadedDeclRef(C).second;
4688
4689 case CXCursor_VariableRef:
4690 return getCursorVariableRef(C).second;
4691
4692 default:
4693 // FIXME: Need a way to enumerate all non-reference cases.
4694 llvm_unreachable("Missed a reference kind");
4695 }
4696 }
4697
4698 if (clang_isExpression(C.kind))
4699 return getCursorExpr(C)->getSourceRange();
4700
4701 if (clang_isStatement(C.kind))
4702 return getCursorStmt(C)->getSourceRange();
4703
4704 if (clang_isAttribute(C.kind))
4705 return getCursorAttr(C)->getRange();
4706
4707 if (C.kind == CXCursor_PreprocessingDirective)
4708 return cxcursor::getCursorPreprocessingDirective(C);
4709
4710 if (C.kind == CXCursor_MacroExpansion) {
4711 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004712 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 return TU->mapRangeFromPreamble(Range);
4714 }
4715
4716 if (C.kind == CXCursor_MacroDefinition) {
4717 ASTUnit *TU = getCursorASTUnit(C);
4718 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4719 return TU->mapRangeFromPreamble(Range);
4720 }
4721
4722 if (C.kind == CXCursor_InclusionDirective) {
4723 ASTUnit *TU = getCursorASTUnit(C);
4724 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4725 return TU->mapRangeFromPreamble(Range);
4726 }
4727
4728 if (C.kind == CXCursor_TranslationUnit) {
4729 ASTUnit *TU = getCursorASTUnit(C);
4730 FileID MainID = TU->getSourceManager().getMainFileID();
4731 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4732 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4733 return SourceRange(Start, End);
4734 }
4735
4736 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004737 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 if (!D)
4739 return SourceRange();
4740
4741 SourceRange R = D->getSourceRange();
4742 // FIXME: Multiple variables declared in a single declaration
4743 // currently lack the information needed to correctly determine their
4744 // ranges when accounting for the type-specifier. We use context
4745 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4746 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004747 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 if (!cxcursor::isFirstInDeclGroup(C))
4749 R.setBegin(VD->getLocation());
4750 }
4751 return R;
4752 }
4753 return SourceRange();
4754}
4755
4756/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4757/// the decl-specifier-seq for declarations.
4758static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4759 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004760 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 if (!D)
4762 return SourceRange();
4763
4764 SourceRange R = D->getSourceRange();
4765
4766 // Adjust the start of the location for declarations preceded by
4767 // declaration specifiers.
4768 SourceLocation StartLoc;
4769 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4770 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4771 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004772 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4774 StartLoc = TI->getTypeLoc().getLocStart();
4775 }
4776
4777 if (StartLoc.isValid() && R.getBegin().isValid() &&
4778 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4779 R.setBegin(StartLoc);
4780
4781 // FIXME: Multiple variables declared in a single declaration
4782 // currently lack the information needed to correctly determine their
4783 // ranges when accounting for the type-specifier. We use context
4784 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4785 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004786 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 if (!cxcursor::isFirstInDeclGroup(C))
4788 R.setBegin(VD->getLocation());
4789 }
4790
4791 return R;
4792 }
4793
4794 return getRawCursorExtent(C);
4795}
4796
4797extern "C" {
4798
4799CXSourceRange clang_getCursorExtent(CXCursor C) {
4800 SourceRange R = getRawCursorExtent(C);
4801 if (R.isInvalid())
4802 return clang_getNullRange();
4803
4804 return cxloc::translateSourceRange(getCursorContext(C), R);
4805}
4806
4807CXCursor clang_getCursorReferenced(CXCursor C) {
4808 if (clang_isInvalid(C.kind))
4809 return clang_getNullCursor();
4810
4811 CXTranslationUnit tu = getCursorTU(C);
4812 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004813 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 if (!D)
4815 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004816 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004818 if (const ObjCPropertyImplDecl *PropImpl =
4819 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004820 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4821 return MakeCXCursor(Property, tu);
4822
4823 return C;
4824 }
4825
4826 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004827 const Expr *E = getCursorExpr(C);
4828 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004829 if (D) {
4830 CXCursor declCursor = MakeCXCursor(D, tu);
4831 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4832 declCursor);
4833 return declCursor;
4834 }
4835
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004836 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 return MakeCursorOverloadedDeclRef(Ovl, tu);
4838
4839 return clang_getNullCursor();
4840 }
4841
4842 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004843 const Stmt *S = getCursorStmt(C);
4844 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 if (LabelDecl *label = Goto->getLabel())
4846 if (LabelStmt *labelS = label->getStmt())
4847 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4848
4849 return clang_getNullCursor();
4850 }
4851
4852 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004853 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004854 return MakeMacroDefinitionCursor(Def, tu);
4855 }
4856
4857 if (!clang_isReference(C.kind))
4858 return clang_getNullCursor();
4859
4860 switch (C.kind) {
4861 case CXCursor_ObjCSuperClassRef:
4862 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4863
4864 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004865 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4866 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004867 return MakeCXCursor(Def, tu);
4868
4869 return MakeCXCursor(Prot, tu);
4870 }
4871
4872 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004873 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4874 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004875 return MakeCXCursor(Def, tu);
4876
4877 return MakeCXCursor(Class, tu);
4878 }
4879
4880 case CXCursor_TypeRef:
4881 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4882
4883 case CXCursor_TemplateRef:
4884 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4885
4886 case CXCursor_NamespaceRef:
4887 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4888
4889 case CXCursor_MemberRef:
4890 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4891
4892 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004893 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4895 tu ));
4896 }
4897
4898 case CXCursor_LabelRef:
4899 // FIXME: We end up faking the "parent" declaration here because we
4900 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004901 return MakeCXCursor(getCursorLabelRef(C).first,
4902 cxtu::getASTUnit(tu)->getASTContext()
4903 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004904 tu);
4905
4906 case CXCursor_OverloadedDeclRef:
4907 return C;
4908
4909 case CXCursor_VariableRef:
4910 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4911
4912 default:
4913 // We would prefer to enumerate all non-reference cursor kinds here.
4914 llvm_unreachable("Unhandled reference cursor kind");
4915 }
4916}
4917
4918CXCursor clang_getCursorDefinition(CXCursor C) {
4919 if (clang_isInvalid(C.kind))
4920 return clang_getNullCursor();
4921
4922 CXTranslationUnit TU = getCursorTU(C);
4923
4924 bool WasReference = false;
4925 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4926 C = clang_getCursorReferenced(C);
4927 WasReference = true;
4928 }
4929
4930 if (C.kind == CXCursor_MacroExpansion)
4931 return clang_getCursorReferenced(C);
4932
4933 if (!clang_isDeclaration(C.kind))
4934 return clang_getNullCursor();
4935
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004936 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004937 if (!D)
4938 return clang_getNullCursor();
4939
4940 switch (D->getKind()) {
4941 // Declaration kinds that don't really separate the notions of
4942 // declaration and definition.
4943 case Decl::Namespace:
4944 case Decl::Typedef:
4945 case Decl::TypeAlias:
4946 case Decl::TypeAliasTemplate:
4947 case Decl::TemplateTypeParm:
4948 case Decl::EnumConstant:
4949 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004950 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004951 case Decl::IndirectField:
4952 case Decl::ObjCIvar:
4953 case Decl::ObjCAtDefsField:
4954 case Decl::ImplicitParam:
4955 case Decl::ParmVar:
4956 case Decl::NonTypeTemplateParm:
4957 case Decl::TemplateTemplateParm:
4958 case Decl::ObjCCategoryImpl:
4959 case Decl::ObjCImplementation:
4960 case Decl::AccessSpec:
4961 case Decl::LinkageSpec:
4962 case Decl::ObjCPropertyImpl:
4963 case Decl::FileScopeAsm:
4964 case Decl::StaticAssert:
4965 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004966 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004967 case Decl::Label: // FIXME: Is this right??
4968 case Decl::ClassScopeFunctionSpecialization:
4969 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004970 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004971 return C;
4972
4973 // Declaration kinds that don't make any sense here, but are
4974 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004975 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004976 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00004977 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00004978 break;
4979
4980 // Declaration kinds for which the definition is not resolvable.
4981 case Decl::UnresolvedUsingTypename:
4982 case Decl::UnresolvedUsingValue:
4983 break;
4984
4985 case Decl::UsingDirective:
4986 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4987 TU);
4988
4989 case Decl::NamespaceAlias:
4990 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4991
4992 case Decl::Enum:
4993 case Decl::Record:
4994 case Decl::CXXRecord:
4995 case Decl::ClassTemplateSpecialization:
4996 case Decl::ClassTemplatePartialSpecialization:
4997 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4998 return MakeCXCursor(Def, TU);
4999 return clang_getNullCursor();
5000
5001 case Decl::Function:
5002 case Decl::CXXMethod:
5003 case Decl::CXXConstructor:
5004 case Decl::CXXDestructor:
5005 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005006 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005008 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005009 return clang_getNullCursor();
5010 }
5011
Larisse Voufo39a1e502013-08-06 01:03:05 +00005012 case Decl::Var:
5013 case Decl::VarTemplateSpecialization:
5014 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005015 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005016 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 return MakeCXCursor(Def, TU);
5018 return clang_getNullCursor();
5019 }
5020
5021 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005022 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005023 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5024 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5025 return clang_getNullCursor();
5026 }
5027
5028 case Decl::ClassTemplate: {
5029 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5030 ->getDefinition())
5031 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5032 TU);
5033 return clang_getNullCursor();
5034 }
5035
Larisse Voufo39a1e502013-08-06 01:03:05 +00005036 case Decl::VarTemplate: {
5037 if (VarDecl *Def =
5038 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5039 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5040 return clang_getNullCursor();
5041 }
5042
Guy Benyei11169dd2012-12-18 14:30:41 +00005043 case Decl::Using:
5044 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5045 D->getLocation(), TU);
5046
5047 case Decl::UsingShadow:
5048 return clang_getCursorDefinition(
5049 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5050 TU));
5051
5052 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005053 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005054 if (Method->isThisDeclarationADefinition())
5055 return C;
5056
5057 // Dig out the method definition in the associated
5058 // @implementation, if we have it.
5059 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005060 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005061 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5062 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5063 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5064 Method->isInstanceMethod()))
5065 if (Def->isThisDeclarationADefinition())
5066 return MakeCXCursor(Def, TU);
5067
5068 return clang_getNullCursor();
5069 }
5070
5071 case Decl::ObjCCategory:
5072 if (ObjCCategoryImplDecl *Impl
5073 = cast<ObjCCategoryDecl>(D)->getImplementation())
5074 return MakeCXCursor(Impl, TU);
5075 return clang_getNullCursor();
5076
5077 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005078 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005079 return MakeCXCursor(Def, TU);
5080 return clang_getNullCursor();
5081
5082 case Decl::ObjCInterface: {
5083 // There are two notions of a "definition" for an Objective-C
5084 // class: the interface and its implementation. When we resolved a
5085 // reference to an Objective-C class, produce the @interface as
5086 // the definition; when we were provided with the interface,
5087 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005088 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005089 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005090 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005091 return MakeCXCursor(Def, TU);
5092 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5093 return MakeCXCursor(Impl, TU);
5094 return clang_getNullCursor();
5095 }
5096
5097 case Decl::ObjCProperty:
5098 // FIXME: We don't really know where to find the
5099 // ObjCPropertyImplDecls that implement this property.
5100 return clang_getNullCursor();
5101
5102 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005103 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005104 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005105 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 return MakeCXCursor(Def, TU);
5107
5108 return clang_getNullCursor();
5109
5110 case Decl::Friend:
5111 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5112 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5113 return clang_getNullCursor();
5114
5115 case Decl::FriendTemplate:
5116 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5117 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5118 return clang_getNullCursor();
5119 }
5120
5121 return clang_getNullCursor();
5122}
5123
5124unsigned clang_isCursorDefinition(CXCursor C) {
5125 if (!clang_isDeclaration(C.kind))
5126 return 0;
5127
5128 return clang_getCursorDefinition(C) == C;
5129}
5130
5131CXCursor clang_getCanonicalCursor(CXCursor C) {
5132 if (!clang_isDeclaration(C.kind))
5133 return C;
5134
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005135 if (const Decl *D = getCursorDecl(C)) {
5136 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005137 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5138 return MakeCXCursor(CatD, getCursorTU(C));
5139
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005140 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5141 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 return MakeCXCursor(IFD, getCursorTU(C));
5143
5144 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5145 }
5146
5147 return C;
5148}
5149
5150int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5151 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5152}
5153
5154unsigned clang_getNumOverloadedDecls(CXCursor C) {
5155 if (C.kind != CXCursor_OverloadedDeclRef)
5156 return 0;
5157
5158 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005159 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 return E->getNumDecls();
5161
5162 if (OverloadedTemplateStorage *S
5163 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5164 return S->size();
5165
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005166 const Decl *D = Storage.get<const Decl *>();
5167 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005168 return Using->shadow_size();
5169
5170 return 0;
5171}
5172
5173CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5174 if (cursor.kind != CXCursor_OverloadedDeclRef)
5175 return clang_getNullCursor();
5176
5177 if (index >= clang_getNumOverloadedDecls(cursor))
5178 return clang_getNullCursor();
5179
5180 CXTranslationUnit TU = getCursorTU(cursor);
5181 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005182 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005183 return MakeCXCursor(E->decls_begin()[index], TU);
5184
5185 if (OverloadedTemplateStorage *S
5186 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5187 return MakeCXCursor(S->begin()[index], TU);
5188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005189 const Decl *D = Storage.get<const Decl *>();
5190 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005191 // FIXME: This is, unfortunately, linear time.
5192 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5193 std::advance(Pos, index);
5194 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5195 }
5196
5197 return clang_getNullCursor();
5198}
5199
5200void clang_getDefinitionSpellingAndExtent(CXCursor C,
5201 const char **startBuf,
5202 const char **endBuf,
5203 unsigned *startLine,
5204 unsigned *startColumn,
5205 unsigned *endLine,
5206 unsigned *endColumn) {
5207 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005208 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5210
5211 SourceManager &SM = FD->getASTContext().getSourceManager();
5212 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5213 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5214 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5215 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5216 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5217 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5218}
5219
5220
5221CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5222 unsigned PieceIndex) {
5223 RefNamePieces Pieces;
5224
5225 switch (C.kind) {
5226 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005227 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5229 E->getQualifierLoc().getSourceRange());
5230 break;
5231
5232 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005233 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5235 E->getQualifierLoc().getSourceRange(),
5236 E->getOptionalExplicitTemplateArgs());
5237 break;
5238
5239 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005240 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005241 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005242 const Expr *Callee = OCE->getCallee();
5243 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 Callee = ICE->getSubExpr();
5245
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005246 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005247 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5248 DRE->getQualifierLoc().getSourceRange());
5249 }
5250 break;
5251
5252 default:
5253 break;
5254 }
5255
5256 if (Pieces.empty()) {
5257 if (PieceIndex == 0)
5258 return clang_getCursorExtent(C);
5259 } else if (PieceIndex < Pieces.size()) {
5260 SourceRange R = Pieces[PieceIndex];
5261 if (R.isValid())
5262 return cxloc::translateSourceRange(getCursorContext(C), R);
5263 }
5264
5265 return clang_getNullRange();
5266}
5267
5268void clang_enableStackTraces(void) {
5269 llvm::sys::PrintStackTraceOnErrorSignal();
5270}
5271
5272void clang_executeOnThread(void (*fn)(void*), void *user_data,
5273 unsigned stack_size) {
5274 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5275}
5276
5277} // end: extern "C"
5278
5279//===----------------------------------------------------------------------===//
5280// Token-based Operations.
5281//===----------------------------------------------------------------------===//
5282
5283/* CXToken layout:
5284 * int_data[0]: a CXTokenKind
5285 * int_data[1]: starting token location
5286 * int_data[2]: token length
5287 * int_data[3]: reserved
5288 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5289 * otherwise unused.
5290 */
5291extern "C" {
5292
5293CXTokenKind clang_getTokenKind(CXToken CXTok) {
5294 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5295}
5296
5297CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5298 switch (clang_getTokenKind(CXTok)) {
5299 case CXToken_Identifier:
5300 case CXToken_Keyword:
5301 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005302 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 ->getNameStart());
5304
5305 case CXToken_Literal: {
5306 // We have stashed the starting pointer in the ptr_data field. Use it.
5307 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005308 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005309 }
5310
5311 case CXToken_Punctuation:
5312 case CXToken_Comment:
5313 break;
5314 }
5315
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005316 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005317 LOG_BAD_TU(TU);
5318 return cxstring::createEmpty();
5319 }
5320
Guy Benyei11169dd2012-12-18 14:30:41 +00005321 // We have to find the starting buffer pointer the hard way, by
5322 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005323 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005325 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005326
5327 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5328 std::pair<FileID, unsigned> LocInfo
5329 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5330 bool Invalid = false;
5331 StringRef Buffer
5332 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5333 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005334 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005335
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005336 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005337}
5338
5339CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005340 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005341 LOG_BAD_TU(TU);
5342 return clang_getNullLocation();
5343 }
5344
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005345 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 if (!CXXUnit)
5347 return clang_getNullLocation();
5348
5349 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5350 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5351}
5352
5353CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005354 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005355 LOG_BAD_TU(TU);
5356 return clang_getNullRange();
5357 }
5358
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005359 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 if (!CXXUnit)
5361 return clang_getNullRange();
5362
5363 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5364 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5365}
5366
5367static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5368 SmallVectorImpl<CXToken> &CXTokens) {
5369 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5370 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005371 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005373 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005374
5375 // Cannot tokenize across files.
5376 if (BeginLocInfo.first != EndLocInfo.first)
5377 return;
5378
5379 // Create a lexer
5380 bool Invalid = false;
5381 StringRef Buffer
5382 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5383 if (Invalid)
5384 return;
5385
5386 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5387 CXXUnit->getASTContext().getLangOpts(),
5388 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5389 Lex.SetCommentRetentionState(true);
5390
5391 // Lex tokens until we hit the end of the range.
5392 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5393 Token Tok;
5394 bool previousWasAt = false;
5395 do {
5396 // Lex the next token
5397 Lex.LexFromRawLexer(Tok);
5398 if (Tok.is(tok::eof))
5399 break;
5400
5401 // Initialize the CXToken.
5402 CXToken CXTok;
5403
5404 // - Common fields
5405 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5406 CXTok.int_data[2] = Tok.getLength();
5407 CXTok.int_data[3] = 0;
5408
5409 // - Kind-specific fields
5410 if (Tok.isLiteral()) {
5411 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005412 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005413 } else if (Tok.is(tok::raw_identifier)) {
5414 // Lookup the identifier to determine whether we have a keyword.
5415 IdentifierInfo *II
5416 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5417
5418 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5419 CXTok.int_data[0] = CXToken_Keyword;
5420 }
5421 else {
5422 CXTok.int_data[0] = Tok.is(tok::identifier)
5423 ? CXToken_Identifier
5424 : CXToken_Keyword;
5425 }
5426 CXTok.ptr_data = II;
5427 } else if (Tok.is(tok::comment)) {
5428 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005429 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005430 } else {
5431 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005432 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 }
5434 CXTokens.push_back(CXTok);
5435 previousWasAt = Tok.is(tok::at);
5436 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5437}
5438
5439void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5440 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005441 LOG_FUNC_SECTION {
5442 *Log << TU << ' ' << Range;
5443 }
5444
Guy Benyei11169dd2012-12-18 14:30:41 +00005445 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005446 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 if (NumTokens)
5448 *NumTokens = 0;
5449
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005450 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005451 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005452 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005453 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005454
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005455 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 if (!CXXUnit || !Tokens || !NumTokens)
5457 return;
5458
5459 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5460
5461 SourceRange R = cxloc::translateCXSourceRange(Range);
5462 if (R.isInvalid())
5463 return;
5464
5465 SmallVector<CXToken, 32> CXTokens;
5466 getTokens(CXXUnit, R, CXTokens);
5467
5468 if (CXTokens.empty())
5469 return;
5470
5471 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5472 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5473 *NumTokens = CXTokens.size();
5474}
5475
5476void clang_disposeTokens(CXTranslationUnit TU,
5477 CXToken *Tokens, unsigned NumTokens) {
5478 free(Tokens);
5479}
5480
5481} // end: extern "C"
5482
5483//===----------------------------------------------------------------------===//
5484// Token annotation APIs.
5485//===----------------------------------------------------------------------===//
5486
Guy Benyei11169dd2012-12-18 14:30:41 +00005487static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5488 CXCursor parent,
5489 CXClientData client_data);
5490static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5491 CXClientData client_data);
5492
5493namespace {
5494class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005495 CXToken *Tokens;
5496 CXCursor *Cursors;
5497 unsigned NumTokens;
5498 unsigned TokIdx;
5499 unsigned PreprocessingTokIdx;
5500 CursorVisitor AnnotateVis;
5501 SourceManager &SrcMgr;
5502 bool HasContextSensitiveKeywords;
5503
5504 struct PostChildrenInfo {
5505 CXCursor Cursor;
5506 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005507 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005508 unsigned BeforeChildrenTokenIdx;
5509 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005510 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005511
5512 CXToken &getTok(unsigned Idx) {
5513 assert(Idx < NumTokens);
5514 return Tokens[Idx];
5515 }
5516 const CXToken &getTok(unsigned Idx) const {
5517 assert(Idx < NumTokens);
5518 return Tokens[Idx];
5519 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005520 bool MoreTokens() const { return TokIdx < NumTokens; }
5521 unsigned NextToken() const { return TokIdx; }
5522 void AdvanceToken() { ++TokIdx; }
5523 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005524 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 }
5526 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005527 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005528 }
5529 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005530 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005531 }
5532
5533 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005534 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005535 SourceRange);
5536
5537public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005538 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005539 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005540 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005541 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005542 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005543 AnnotateTokensVisitor, this,
5544 /*VisitPreprocessorLast=*/true,
5545 /*VisitIncludedEntities=*/false,
5546 RegionOfInterest,
5547 /*VisitDeclsOnly=*/false,
5548 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005549 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005550 HasContextSensitiveKeywords(false) { }
5551
5552 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5553 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5554 bool postVisitChildren(CXCursor cursor);
5555 void AnnotateTokens();
5556
5557 /// \brief Determine whether the annotator saw any cursors that have
5558 /// context-sensitive keywords.
5559 bool hasContextSensitiveKeywords() const {
5560 return HasContextSensitiveKeywords;
5561 }
5562
5563 ~AnnotateTokensWorker() {
5564 assert(PostChildrenInfos.empty());
5565 }
5566};
5567}
5568
5569void AnnotateTokensWorker::AnnotateTokens() {
5570 // Walk the AST within the region of interest, annotating tokens
5571 // along the way.
5572 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005573}
Guy Benyei11169dd2012-12-18 14:30:41 +00005574
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005575static inline void updateCursorAnnotation(CXCursor &Cursor,
5576 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005577 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005578 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005579 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005580}
5581
5582/// \brief It annotates and advances tokens with a cursor until the comparison
5583//// between the cursor location and the source range is the same as
5584/// \arg compResult.
5585///
5586/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5587/// Pass RangeOverlap to annotate tokens inside a range.
5588void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5589 RangeComparisonResult compResult,
5590 SourceRange range) {
5591 while (MoreTokens()) {
5592 const unsigned I = NextToken();
5593 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005594 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5595 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005596
5597 SourceLocation TokLoc = GetTokenLoc(I);
5598 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005599 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005600 AdvanceToken();
5601 continue;
5602 }
5603 break;
5604 }
5605}
5606
5607/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005608/// \returns true if it advanced beyond all macro tokens, false otherwise.
5609bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005610 CXCursor updateC,
5611 RangeComparisonResult compResult,
5612 SourceRange range) {
5613 assert(MoreTokens());
5614 assert(isFunctionMacroToken(NextToken()) &&
5615 "Should be called only for macro arg tokens");
5616
5617 // This works differently than annotateAndAdvanceTokens; because expanded
5618 // macro arguments can have arbitrary translation-unit source order, we do not
5619 // advance the token index one by one until a token fails the range test.
5620 // We only advance once past all of the macro arg tokens if all of them
5621 // pass the range test. If one of them fails we keep the token index pointing
5622 // at the start of the macro arg tokens so that the failing token will be
5623 // annotated by a subsequent annotation try.
5624
5625 bool atLeastOneCompFail = false;
5626
5627 unsigned I = NextToken();
5628 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5629 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5630 if (TokLoc.isFileID())
5631 continue; // not macro arg token, it's parens or comma.
5632 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5633 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5634 Cursors[I] = updateC;
5635 } else
5636 atLeastOneCompFail = true;
5637 }
5638
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005639 if (atLeastOneCompFail)
5640 return false;
5641
5642 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5643 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005644}
5645
5646enum CXChildVisitResult
5647AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 SourceRange cursorRange = getRawCursorExtent(cursor);
5649 if (cursorRange.isInvalid())
5650 return CXChildVisit_Recurse;
5651
5652 if (!HasContextSensitiveKeywords) {
5653 // Objective-C properties can have context-sensitive keywords.
5654 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005655 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005656 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5657 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5658 }
5659 // Objective-C methods can have context-sensitive keywords.
5660 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5661 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005662 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5664 if (Method->getObjCDeclQualifier())
5665 HasContextSensitiveKeywords = true;
5666 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005667 for (const auto *P : Method->params()) {
5668 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005669 HasContextSensitiveKeywords = true;
5670 break;
5671 }
5672 }
5673 }
5674 }
5675 }
5676 // C++ methods can have context-sensitive keywords.
5677 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005678 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005679 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5680 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5681 HasContextSensitiveKeywords = true;
5682 }
5683 }
5684 // C++ classes can have context-sensitive keywords.
5685 else if (cursor.kind == CXCursor_StructDecl ||
5686 cursor.kind == CXCursor_ClassDecl ||
5687 cursor.kind == CXCursor_ClassTemplate ||
5688 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005689 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 if (D->hasAttr<FinalAttr>())
5691 HasContextSensitiveKeywords = true;
5692 }
5693 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005694
5695 // Don't override a property annotation with its getter/setter method.
5696 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5697 parent.kind == CXCursor_ObjCPropertyDecl)
5698 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005699
5700 if (clang_isPreprocessing(cursor.kind)) {
5701 // Items in the preprocessing record are kept separate from items in
5702 // declarations, so we keep a separate token index.
5703 unsigned SavedTokIdx = TokIdx;
5704 TokIdx = PreprocessingTokIdx;
5705
5706 // Skip tokens up until we catch up to the beginning of the preprocessing
5707 // entry.
5708 while (MoreTokens()) {
5709 const unsigned I = NextToken();
5710 SourceLocation TokLoc = GetTokenLoc(I);
5711 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5712 case RangeBefore:
5713 AdvanceToken();
5714 continue;
5715 case RangeAfter:
5716 case RangeOverlap:
5717 break;
5718 }
5719 break;
5720 }
5721
5722 // Look at all of the tokens within this range.
5723 while (MoreTokens()) {
5724 const unsigned I = NextToken();
5725 SourceLocation TokLoc = GetTokenLoc(I);
5726 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5727 case RangeBefore:
5728 llvm_unreachable("Infeasible");
5729 case RangeAfter:
5730 break;
5731 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005732 // For macro expansions, just note where the beginning of the macro
5733 // expansion occurs.
5734 if (cursor.kind == CXCursor_MacroExpansion) {
5735 if (TokLoc == cursorRange.getBegin())
5736 Cursors[I] = cursor;
5737 AdvanceToken();
5738 break;
5739 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005740 // We may have already annotated macro names inside macro definitions.
5741 if (Cursors[I].kind != CXCursor_MacroExpansion)
5742 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005743 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005744 continue;
5745 }
5746 break;
5747 }
5748
5749 // Save the preprocessing token index; restore the non-preprocessing
5750 // token index.
5751 PreprocessingTokIdx = TokIdx;
5752 TokIdx = SavedTokIdx;
5753 return CXChildVisit_Recurse;
5754 }
5755
5756 if (cursorRange.isInvalid())
5757 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005758
5759 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005760 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 const enum CXCursorKind K = clang_getCursorKind(parent);
5762 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005763 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5764 // Attributes are annotated out-of-order, skip tokens until we reach it.
5765 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005766 ? clang_getNullCursor() : parent;
5767
5768 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5769
5770 // Avoid having the cursor of an expression "overwrite" the annotation of the
5771 // variable declaration that it belongs to.
5772 // This can happen for C++ constructor expressions whose range generally
5773 // include the variable declaration, e.g.:
5774 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005775 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005776 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005777 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 const unsigned I = NextToken();
5779 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5780 E->getLocStart() == D->getLocation() &&
5781 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005782 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005783 AdvanceToken();
5784 }
5785 }
5786 }
5787
5788 // Before recursing into the children keep some state that we are going
5789 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5790 // extra work after the child nodes are visited.
5791 // Note that we don't call VisitChildren here to avoid traversing statements
5792 // code-recursively which can blow the stack.
5793
5794 PostChildrenInfo Info;
5795 Info.Cursor = cursor;
5796 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005797 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005798 Info.BeforeChildrenTokenIdx = NextToken();
5799 PostChildrenInfos.push_back(Info);
5800
5801 return CXChildVisit_Recurse;
5802}
5803
5804bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5805 if (PostChildrenInfos.empty())
5806 return false;
5807 const PostChildrenInfo &Info = PostChildrenInfos.back();
5808 if (!clang_equalCursors(Info.Cursor, cursor))
5809 return false;
5810
5811 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5812 const unsigned AfterChildren = NextToken();
5813 SourceRange cursorRange = Info.CursorRange;
5814
5815 // Scan the tokens that are at the end of the cursor, but are not captured
5816 // but the child cursors.
5817 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5818
5819 // Scan the tokens that are at the beginning of the cursor, but are not
5820 // capture by the child cursors.
5821 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5822 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5823 break;
5824
5825 Cursors[I] = cursor;
5826 }
5827
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005828 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5829 // encountered the attribute cursor.
5830 if (clang_isAttribute(cursor.kind))
5831 TokIdx = Info.BeforeReachingCursorIdx;
5832
Guy Benyei11169dd2012-12-18 14:30:41 +00005833 PostChildrenInfos.pop_back();
5834 return false;
5835}
5836
5837static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5838 CXCursor parent,
5839 CXClientData client_data) {
5840 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5841}
5842
5843static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5844 CXClientData client_data) {
5845 return static_cast<AnnotateTokensWorker*>(client_data)->
5846 postVisitChildren(cursor);
5847}
5848
5849namespace {
5850
5851/// \brief Uses the macro expansions in the preprocessing record to find
5852/// and mark tokens that are macro arguments. This info is used by the
5853/// AnnotateTokensWorker.
5854class MarkMacroArgTokensVisitor {
5855 SourceManager &SM;
5856 CXToken *Tokens;
5857 unsigned NumTokens;
5858 unsigned CurIdx;
5859
5860public:
5861 MarkMacroArgTokensVisitor(SourceManager &SM,
5862 CXToken *tokens, unsigned numTokens)
5863 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5864
5865 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5866 if (cursor.kind != CXCursor_MacroExpansion)
5867 return CXChildVisit_Continue;
5868
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005869 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005870 if (macroRange.getBegin() == macroRange.getEnd())
5871 return CXChildVisit_Continue; // it's not a function macro.
5872
5873 for (; CurIdx < NumTokens; ++CurIdx) {
5874 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5875 macroRange.getBegin()))
5876 break;
5877 }
5878
5879 if (CurIdx == NumTokens)
5880 return CXChildVisit_Break;
5881
5882 for (; CurIdx < NumTokens; ++CurIdx) {
5883 SourceLocation tokLoc = getTokenLoc(CurIdx);
5884 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5885 break;
5886
5887 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5888 }
5889
5890 if (CurIdx == NumTokens)
5891 return CXChildVisit_Break;
5892
5893 return CXChildVisit_Continue;
5894 }
5895
5896private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005897 CXToken &getTok(unsigned Idx) {
5898 assert(Idx < NumTokens);
5899 return Tokens[Idx];
5900 }
5901 const CXToken &getTok(unsigned Idx) const {
5902 assert(Idx < NumTokens);
5903 return Tokens[Idx];
5904 }
5905
Guy Benyei11169dd2012-12-18 14:30:41 +00005906 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005907 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005908 }
5909
5910 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5911 // The third field is reserved and currently not used. Use it here
5912 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005913 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005914 }
5915};
5916
5917} // end anonymous namespace
5918
5919static CXChildVisitResult
5920MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5921 CXClientData client_data) {
5922 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5923 parent);
5924}
5925
5926namespace {
5927 struct clang_annotateTokens_Data {
5928 CXTranslationUnit TU;
5929 ASTUnit *CXXUnit;
5930 CXToken *Tokens;
5931 unsigned NumTokens;
5932 CXCursor *Cursors;
5933 };
5934}
5935
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005936/// \brief Used by \c annotatePreprocessorTokens.
5937/// \returns true if lexing was finished, false otherwise.
5938static bool lexNext(Lexer &Lex, Token &Tok,
5939 unsigned &NextIdx, unsigned NumTokens) {
5940 if (NextIdx >= NumTokens)
5941 return true;
5942
5943 ++NextIdx;
5944 Lex.LexFromRawLexer(Tok);
5945 if (Tok.is(tok::eof))
5946 return true;
5947
5948 return false;
5949}
5950
Guy Benyei11169dd2012-12-18 14:30:41 +00005951static void annotatePreprocessorTokens(CXTranslationUnit TU,
5952 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005953 CXCursor *Cursors,
5954 CXToken *Tokens,
5955 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005956 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005957
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005958 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005959 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5960 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005961 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005962 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005963 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005964
5965 if (BeginLocInfo.first != EndLocInfo.first)
5966 return;
5967
5968 StringRef Buffer;
5969 bool Invalid = false;
5970 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5971 if (Buffer.empty() || Invalid)
5972 return;
5973
5974 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5975 CXXUnit->getASTContext().getLangOpts(),
5976 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5977 Buffer.end());
5978 Lex.SetCommentRetentionState(true);
5979
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005980 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005981 // Lex tokens in raw mode until we hit the end of the range, to avoid
5982 // entering #includes or expanding macros.
5983 while (true) {
5984 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005985 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5986 break;
5987 unsigned TokIdx = NextIdx-1;
5988 assert(Tok.getLocation() ==
5989 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005990
5991 reprocess:
5992 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005993 // We have found a preprocessing directive. Annotate the tokens
5994 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005995 //
5996 // FIXME: Some simple tests here could identify macro definitions and
5997 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005998
5999 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006000 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6001 break;
6002
Craig Topper69186e72014-06-08 08:38:04 +00006003 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006004 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006005 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6006 break;
6007
6008 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006009 IdentifierInfo &II =
6010 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006011 SourceLocation MappedTokLoc =
6012 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6013 MI = getMacroInfo(II, MappedTokLoc, TU);
6014 }
6015 }
6016
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006017 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006019 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6020 finished = true;
6021 break;
6022 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006023 // If we are in a macro definition, check if the token was ever a
6024 // macro name and annotate it if that's the case.
6025 if (MI) {
6026 SourceLocation SaveLoc = Tok.getLocation();
6027 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6028 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
6029 Tok.setLocation(SaveLoc);
6030 if (MacroDef)
6031 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6032 Tok.getLocation(), TU);
6033 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006034 } while (!Tok.isAtStartOfLine());
6035
6036 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6037 assert(TokIdx <= LastIdx);
6038 SourceLocation EndLoc =
6039 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6040 CXCursor Cursor =
6041 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6042
6043 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006044 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006045
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006046 if (finished)
6047 break;
6048 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006049 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006050 }
6051}
6052
6053// This gets run a separate thread to avoid stack blowout.
6054static void clang_annotateTokensImpl(void *UserData) {
6055 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6056 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6057 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6058 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6059 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6060
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006061 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006062 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6063 setThreadBackgroundPriority();
6064
6065 // Determine the region of interest, which contains all of the tokens.
6066 SourceRange RegionOfInterest;
6067 RegionOfInterest.setBegin(
6068 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6069 RegionOfInterest.setEnd(
6070 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6071 Tokens[NumTokens-1])));
6072
Guy Benyei11169dd2012-12-18 14:30:41 +00006073 // Relex the tokens within the source range to look for preprocessing
6074 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006075 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006076
6077 // If begin location points inside a macro argument, set it to the expansion
6078 // location so we can have the full context when annotating semantically.
6079 {
6080 SourceManager &SM = CXXUnit->getSourceManager();
6081 SourceLocation Loc =
6082 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6083 if (Loc.isMacroID())
6084 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6085 }
6086
Guy Benyei11169dd2012-12-18 14:30:41 +00006087 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6088 // Search and mark tokens that are macro argument expansions.
6089 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6090 Tokens, NumTokens);
6091 CursorVisitor MacroArgMarker(TU,
6092 MarkMacroArgTokensVisitorDelegate, &Visitor,
6093 /*VisitPreprocessorLast=*/true,
6094 /*VisitIncludedEntities=*/false,
6095 RegionOfInterest);
6096 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6097 }
6098
6099 // Annotate all of the source locations in the region of interest that map to
6100 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006101 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006102
6103 // FIXME: We use a ridiculous stack size here because the data-recursion
6104 // algorithm uses a large stack frame than the non-data recursive version,
6105 // and AnnotationTokensWorker currently transforms the data-recursion
6106 // algorithm back into a traditional recursion by explicitly calling
6107 // VisitChildren(). We will need to remove this explicit recursive call.
6108 W.AnnotateTokens();
6109
6110 // If we ran into any entities that involve context-sensitive keywords,
6111 // take another pass through the tokens to mark them as such.
6112 if (W.hasContextSensitiveKeywords()) {
6113 for (unsigned I = 0; I != NumTokens; ++I) {
6114 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6115 continue;
6116
6117 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6118 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006119 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006120 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6121 if (Property->getPropertyAttributesAsWritten() != 0 &&
6122 llvm::StringSwitch<bool>(II->getName())
6123 .Case("readonly", true)
6124 .Case("assign", true)
6125 .Case("unsafe_unretained", true)
6126 .Case("readwrite", true)
6127 .Case("retain", true)
6128 .Case("copy", true)
6129 .Case("nonatomic", true)
6130 .Case("atomic", true)
6131 .Case("getter", true)
6132 .Case("setter", true)
6133 .Case("strong", true)
6134 .Case("weak", true)
6135 .Default(false))
6136 Tokens[I].int_data[0] = CXToken_Keyword;
6137 }
6138 continue;
6139 }
6140
6141 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6142 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6143 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6144 if (llvm::StringSwitch<bool>(II->getName())
6145 .Case("in", true)
6146 .Case("out", true)
6147 .Case("inout", true)
6148 .Case("oneway", true)
6149 .Case("bycopy", true)
6150 .Case("byref", true)
6151 .Default(false))
6152 Tokens[I].int_data[0] = CXToken_Keyword;
6153 continue;
6154 }
6155
6156 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6157 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6158 Tokens[I].int_data[0] = CXToken_Keyword;
6159 continue;
6160 }
6161 }
6162 }
6163}
6164
6165extern "C" {
6166
6167void clang_annotateTokens(CXTranslationUnit TU,
6168 CXToken *Tokens, unsigned NumTokens,
6169 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006170 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006171 LOG_BAD_TU(TU);
6172 return;
6173 }
6174 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006175 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006177 }
6178
6179 LOG_FUNC_SECTION {
6180 *Log << TU << ' ';
6181 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6182 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6183 *Log << clang_getRange(bloc, eloc);
6184 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006185
6186 // Any token we don't specifically annotate will have a NULL cursor.
6187 CXCursor C = clang_getNullCursor();
6188 for (unsigned I = 0; I != NumTokens; ++I)
6189 Cursors[I] = C;
6190
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006191 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006192 if (!CXXUnit)
6193 return;
6194
6195 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6196
6197 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6198 llvm::CrashRecoveryContext CRC;
6199 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6200 GetSafetyThreadStackSize() * 2)) {
6201 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6202 }
6203}
6204
6205} // end: extern "C"
6206
6207//===----------------------------------------------------------------------===//
6208// Operations for querying linkage of a cursor.
6209//===----------------------------------------------------------------------===//
6210
6211extern "C" {
6212CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6213 if (!clang_isDeclaration(cursor.kind))
6214 return CXLinkage_Invalid;
6215
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006216 const Decl *D = cxcursor::getCursorDecl(cursor);
6217 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006218 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006219 case NoLinkage:
6220 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006221 case InternalLinkage: return CXLinkage_Internal;
6222 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6223 case ExternalLinkage: return CXLinkage_External;
6224 };
6225
6226 return CXLinkage_Invalid;
6227}
6228} // end: extern "C"
6229
6230//===----------------------------------------------------------------------===//
6231// Operations for querying language of a cursor.
6232//===----------------------------------------------------------------------===//
6233
6234static CXLanguageKind getDeclLanguage(const Decl *D) {
6235 if (!D)
6236 return CXLanguage_C;
6237
6238 switch (D->getKind()) {
6239 default:
6240 break;
6241 case Decl::ImplicitParam:
6242 case Decl::ObjCAtDefsField:
6243 case Decl::ObjCCategory:
6244 case Decl::ObjCCategoryImpl:
6245 case Decl::ObjCCompatibleAlias:
6246 case Decl::ObjCImplementation:
6247 case Decl::ObjCInterface:
6248 case Decl::ObjCIvar:
6249 case Decl::ObjCMethod:
6250 case Decl::ObjCProperty:
6251 case Decl::ObjCPropertyImpl:
6252 case Decl::ObjCProtocol:
6253 return CXLanguage_ObjC;
6254 case Decl::CXXConstructor:
6255 case Decl::CXXConversion:
6256 case Decl::CXXDestructor:
6257 case Decl::CXXMethod:
6258 case Decl::CXXRecord:
6259 case Decl::ClassTemplate:
6260 case Decl::ClassTemplatePartialSpecialization:
6261 case Decl::ClassTemplateSpecialization:
6262 case Decl::Friend:
6263 case Decl::FriendTemplate:
6264 case Decl::FunctionTemplate:
6265 case Decl::LinkageSpec:
6266 case Decl::Namespace:
6267 case Decl::NamespaceAlias:
6268 case Decl::NonTypeTemplateParm:
6269 case Decl::StaticAssert:
6270 case Decl::TemplateTemplateParm:
6271 case Decl::TemplateTypeParm:
6272 case Decl::UnresolvedUsingTypename:
6273 case Decl::UnresolvedUsingValue:
6274 case Decl::Using:
6275 case Decl::UsingDirective:
6276 case Decl::UsingShadow:
6277 return CXLanguage_CPlusPlus;
6278 }
6279
6280 return CXLanguage_C;
6281}
6282
6283extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006284
6285static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6286 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6287 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006288
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006289 switch (D->getAvailability()) {
6290 case AR_Available:
6291 case AR_NotYetIntroduced:
6292 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006293 return getCursorAvailabilityForDecl(
6294 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006295 return CXAvailability_Available;
6296
6297 case AR_Deprecated:
6298 return CXAvailability_Deprecated;
6299
6300 case AR_Unavailable:
6301 return CXAvailability_NotAvailable;
6302 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006303
6304 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006305}
6306
Guy Benyei11169dd2012-12-18 14:30:41 +00006307enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6308 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006309 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6310 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006311
6312 return CXAvailability_Available;
6313}
6314
6315static CXVersion convertVersion(VersionTuple In) {
6316 CXVersion Out = { -1, -1, -1 };
6317 if (In.empty())
6318 return Out;
6319
6320 Out.Major = In.getMajor();
6321
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006322 Optional<unsigned> Minor = In.getMinor();
6323 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006324 Out.Minor = *Minor;
6325 else
6326 return Out;
6327
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006328 Optional<unsigned> Subminor = In.getSubminor();
6329 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006330 Out.Subminor = *Subminor;
6331
6332 return Out;
6333}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006334
6335static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6336 int *always_deprecated,
6337 CXString *deprecated_message,
6338 int *always_unavailable,
6339 CXString *unavailable_message,
6340 CXPlatformAvailability *availability,
6341 int availability_size) {
6342 bool HadAvailAttr = false;
6343 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006344 for (auto A : D->attrs()) {
6345 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006346 HadAvailAttr = true;
6347 if (always_deprecated)
6348 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006349 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006350 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006351 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006352 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006353 continue;
6354 }
6355
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006356 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006357 HadAvailAttr = true;
6358 if (always_unavailable)
6359 *always_unavailable = 1;
6360 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006361 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006362 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6363 }
6364 continue;
6365 }
6366
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006367 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006368 HadAvailAttr = true;
6369 if (N < availability_size) {
6370 availability[N].Platform
6371 = cxstring::createDup(Avail->getPlatform()->getName());
6372 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6373 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6374 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6375 availability[N].Unavailable = Avail->getUnavailable();
6376 availability[N].Message = cxstring::createDup(Avail->getMessage());
6377 }
6378 ++N;
6379 }
6380 }
6381
6382 if (!HadAvailAttr)
6383 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6384 return getCursorPlatformAvailabilityForDecl(
6385 cast<Decl>(EnumConst->getDeclContext()),
6386 always_deprecated,
6387 deprecated_message,
6388 always_unavailable,
6389 unavailable_message,
6390 availability,
6391 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006392
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006393 return N;
6394}
6395
Guy Benyei11169dd2012-12-18 14:30:41 +00006396int clang_getCursorPlatformAvailability(CXCursor cursor,
6397 int *always_deprecated,
6398 CXString *deprecated_message,
6399 int *always_unavailable,
6400 CXString *unavailable_message,
6401 CXPlatformAvailability *availability,
6402 int availability_size) {
6403 if (always_deprecated)
6404 *always_deprecated = 0;
6405 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006406 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006407 if (always_unavailable)
6408 *always_unavailable = 0;
6409 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006410 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006411
Guy Benyei11169dd2012-12-18 14:30:41 +00006412 if (!clang_isDeclaration(cursor.kind))
6413 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006414
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006415 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006416 if (!D)
6417 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006418
6419 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6420 deprecated_message,
6421 always_unavailable,
6422 unavailable_message,
6423 availability,
6424 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006425}
6426
6427void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6428 clang_disposeString(availability->Platform);
6429 clang_disposeString(availability->Message);
6430}
6431
6432CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6433 if (clang_isDeclaration(cursor.kind))
6434 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6435
6436 return CXLanguage_Invalid;
6437}
6438
6439 /// \brief If the given cursor is the "templated" declaration
6440 /// descibing a class or function template, return the class or
6441 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006442static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006443 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006444 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006445
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006446 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006447 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6448 return FunTmpl;
6449
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006450 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006451 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6452 return ClassTmpl;
6453
6454 return D;
6455}
6456
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006457
6458enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6459 StorageClass sc = SC_None;
6460 const Decl *D = getCursorDecl(C);
6461 if (D) {
6462 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6463 sc = FD->getStorageClass();
6464 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6465 sc = VD->getStorageClass();
6466 } else {
6467 return CX_SC_Invalid;
6468 }
6469 } else {
6470 return CX_SC_Invalid;
6471 }
6472 switch (sc) {
6473 case SC_None:
6474 return CX_SC_None;
6475 case SC_Extern:
6476 return CX_SC_Extern;
6477 case SC_Static:
6478 return CX_SC_Static;
6479 case SC_PrivateExtern:
6480 return CX_SC_PrivateExtern;
6481 case SC_OpenCLWorkGroupLocal:
6482 return CX_SC_OpenCLWorkGroupLocal;
6483 case SC_Auto:
6484 return CX_SC_Auto;
6485 case SC_Register:
6486 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006487 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006488 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006489}
6490
Guy Benyei11169dd2012-12-18 14:30:41 +00006491CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6492 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006493 if (const Decl *D = getCursorDecl(cursor)) {
6494 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006495 if (!DC)
6496 return clang_getNullCursor();
6497
6498 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6499 getCursorTU(cursor));
6500 }
6501 }
6502
6503 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006504 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006505 return MakeCXCursor(D, getCursorTU(cursor));
6506 }
6507
6508 return clang_getNullCursor();
6509}
6510
6511CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6512 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006513 if (const Decl *D = getCursorDecl(cursor)) {
6514 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006515 if (!DC)
6516 return clang_getNullCursor();
6517
6518 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6519 getCursorTU(cursor));
6520 }
6521 }
6522
6523 // FIXME: Note that we can't easily compute the lexical context of a
6524 // statement or expression, so we return nothing.
6525 return clang_getNullCursor();
6526}
6527
6528CXFile clang_getIncludedFile(CXCursor cursor) {
6529 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006530 return nullptr;
6531
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006532 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006533 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006534}
6535
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006536unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6537 if (C.kind != CXCursor_ObjCPropertyDecl)
6538 return CXObjCPropertyAttr_noattr;
6539
6540 unsigned Result = CXObjCPropertyAttr_noattr;
6541 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6542 ObjCPropertyDecl::PropertyAttributeKind Attr =
6543 PD->getPropertyAttributesAsWritten();
6544
6545#define SET_CXOBJCPROP_ATTR(A) \
6546 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6547 Result |= CXObjCPropertyAttr_##A
6548 SET_CXOBJCPROP_ATTR(readonly);
6549 SET_CXOBJCPROP_ATTR(getter);
6550 SET_CXOBJCPROP_ATTR(assign);
6551 SET_CXOBJCPROP_ATTR(readwrite);
6552 SET_CXOBJCPROP_ATTR(retain);
6553 SET_CXOBJCPROP_ATTR(copy);
6554 SET_CXOBJCPROP_ATTR(nonatomic);
6555 SET_CXOBJCPROP_ATTR(setter);
6556 SET_CXOBJCPROP_ATTR(atomic);
6557 SET_CXOBJCPROP_ATTR(weak);
6558 SET_CXOBJCPROP_ATTR(strong);
6559 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6560#undef SET_CXOBJCPROP_ATTR
6561
6562 return Result;
6563}
6564
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006565unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6566 if (!clang_isDeclaration(C.kind))
6567 return CXObjCDeclQualifier_None;
6568
6569 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6570 const Decl *D = getCursorDecl(C);
6571 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6572 QT = MD->getObjCDeclQualifier();
6573 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6574 QT = PD->getObjCDeclQualifier();
6575 if (QT == Decl::OBJC_TQ_None)
6576 return CXObjCDeclQualifier_None;
6577
6578 unsigned Result = CXObjCDeclQualifier_None;
6579 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6580 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6581 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6582 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6583 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6584 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6585
6586 return Result;
6587}
6588
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006589unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6590 if (!clang_isDeclaration(C.kind))
6591 return 0;
6592
6593 const Decl *D = getCursorDecl(C);
6594 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6595 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6596 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6597 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6598
6599 return 0;
6600}
6601
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006602unsigned clang_Cursor_isVariadic(CXCursor C) {
6603 if (!clang_isDeclaration(C.kind))
6604 return 0;
6605
6606 const Decl *D = getCursorDecl(C);
6607 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6608 return FD->isVariadic();
6609 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6610 return MD->isVariadic();
6611
6612 return 0;
6613}
6614
Guy Benyei11169dd2012-12-18 14:30:41 +00006615CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6616 if (!clang_isDeclaration(C.kind))
6617 return clang_getNullRange();
6618
6619 const Decl *D = getCursorDecl(C);
6620 ASTContext &Context = getCursorContext(C);
6621 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6622 if (!RC)
6623 return clang_getNullRange();
6624
6625 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6626}
6627
6628CXString clang_Cursor_getRawCommentText(CXCursor C) {
6629 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006630 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006631
6632 const Decl *D = getCursorDecl(C);
6633 ASTContext &Context = getCursorContext(C);
6634 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6635 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6636 StringRef();
6637
6638 // Don't duplicate the string because RawText points directly into source
6639 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006640 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006641}
6642
6643CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6644 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006645 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006646
6647 const Decl *D = getCursorDecl(C);
6648 const ASTContext &Context = getCursorContext(C);
6649 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6650
6651 if (RC) {
6652 StringRef BriefText = RC->getBriefText(Context);
6653
6654 // Don't duplicate the string because RawComment ensures that this memory
6655 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006656 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006657 }
6658
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006659 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006660}
6661
Guy Benyei11169dd2012-12-18 14:30:41 +00006662CXModule clang_Cursor_getModule(CXCursor C) {
6663 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006664 if (const ImportDecl *ImportD =
6665 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006666 return ImportD->getImportedModule();
6667 }
6668
Craig Topper69186e72014-06-08 08:38:04 +00006669 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006670}
6671
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006672CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6673 if (isNotUsableTU(TU)) {
6674 LOG_BAD_TU(TU);
6675 return nullptr;
6676 }
6677 if (!File)
6678 return nullptr;
6679 FileEntry *FE = static_cast<FileEntry *>(File);
6680
6681 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6682 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6683 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6684
Richard Smithfeb54b62014-10-23 02:01:19 +00006685 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006686}
6687
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006688CXFile clang_Module_getASTFile(CXModule CXMod) {
6689 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006690 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006691 Module *Mod = static_cast<Module*>(CXMod);
6692 return const_cast<FileEntry *>(Mod->getASTFile());
6693}
6694
Guy Benyei11169dd2012-12-18 14:30:41 +00006695CXModule clang_Module_getParent(CXModule CXMod) {
6696 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006697 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006698 Module *Mod = static_cast<Module*>(CXMod);
6699 return Mod->Parent;
6700}
6701
6702CXString clang_Module_getName(CXModule CXMod) {
6703 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006704 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006705 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006706 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006707}
6708
6709CXString clang_Module_getFullName(CXModule CXMod) {
6710 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006711 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006712 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006713 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006714}
6715
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006716int clang_Module_isSystem(CXModule CXMod) {
6717 if (!CXMod)
6718 return 0;
6719 Module *Mod = static_cast<Module*>(CXMod);
6720 return Mod->IsSystem;
6721}
6722
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006723unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6724 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006725 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006726 LOG_BAD_TU(TU);
6727 return 0;
6728 }
6729 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006730 return 0;
6731 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006732 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6733 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6734 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006735}
6736
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006737CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6738 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006739 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006740 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006741 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006742 }
6743 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006744 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006745 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006746 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006747
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006748 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6749 if (Index < TopHeaders.size())
6750 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006751
Craig Topper69186e72014-06-08 08:38:04 +00006752 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006753}
6754
6755} // end: extern "C"
6756
6757//===----------------------------------------------------------------------===//
6758// C++ AST instrospection.
6759//===----------------------------------------------------------------------===//
6760
6761extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006762unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6763 if (!clang_isDeclaration(C.kind))
6764 return 0;
6765
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006766 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006767 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006768 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006769 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6770}
6771
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006772unsigned clang_CXXMethod_isConst(CXCursor C) {
6773 if (!clang_isDeclaration(C.kind))
6774 return 0;
6775
6776 const Decl *D = cxcursor::getCursorDecl(C);
6777 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006778 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006779 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6780}
6781
Guy Benyei11169dd2012-12-18 14:30:41 +00006782unsigned clang_CXXMethod_isStatic(CXCursor C) {
6783 if (!clang_isDeclaration(C.kind))
6784 return 0;
6785
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006786 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006787 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006788 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006789 return (Method && Method->isStatic()) ? 1 : 0;
6790}
6791
6792unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6793 if (!clang_isDeclaration(C.kind))
6794 return 0;
6795
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006796 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006797 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006798 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006799 return (Method && Method->isVirtual()) ? 1 : 0;
6800}
6801} // end: extern "C"
6802
6803//===----------------------------------------------------------------------===//
6804// Attribute introspection.
6805//===----------------------------------------------------------------------===//
6806
6807extern "C" {
6808CXType clang_getIBOutletCollectionType(CXCursor C) {
6809 if (C.kind != CXCursor_IBOutletCollectionAttr)
6810 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6811
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006812 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006813 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6814
6815 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6816}
6817} // end: extern "C"
6818
6819//===----------------------------------------------------------------------===//
6820// Inspecting memory usage.
6821//===----------------------------------------------------------------------===//
6822
6823typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6824
6825static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6826 enum CXTUResourceUsageKind k,
6827 unsigned long amount) {
6828 CXTUResourceUsageEntry entry = { k, amount };
6829 entries.push_back(entry);
6830}
6831
6832extern "C" {
6833
6834const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6835 const char *str = "";
6836 switch (kind) {
6837 case CXTUResourceUsage_AST:
6838 str = "ASTContext: expressions, declarations, and types";
6839 break;
6840 case CXTUResourceUsage_Identifiers:
6841 str = "ASTContext: identifiers";
6842 break;
6843 case CXTUResourceUsage_Selectors:
6844 str = "ASTContext: selectors";
6845 break;
6846 case CXTUResourceUsage_GlobalCompletionResults:
6847 str = "Code completion: cached global results";
6848 break;
6849 case CXTUResourceUsage_SourceManagerContentCache:
6850 str = "SourceManager: content cache allocator";
6851 break;
6852 case CXTUResourceUsage_AST_SideTables:
6853 str = "ASTContext: side tables";
6854 break;
6855 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6856 str = "SourceManager: malloc'ed memory buffers";
6857 break;
6858 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6859 str = "SourceManager: mmap'ed memory buffers";
6860 break;
6861 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6862 str = "ExternalASTSource: malloc'ed memory buffers";
6863 break;
6864 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6865 str = "ExternalASTSource: mmap'ed memory buffers";
6866 break;
6867 case CXTUResourceUsage_Preprocessor:
6868 str = "Preprocessor: malloc'ed memory";
6869 break;
6870 case CXTUResourceUsage_PreprocessingRecord:
6871 str = "Preprocessor: PreprocessingRecord";
6872 break;
6873 case CXTUResourceUsage_SourceManager_DataStructures:
6874 str = "SourceManager: data structures and tables";
6875 break;
6876 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6877 str = "Preprocessor: header search tables";
6878 break;
6879 }
6880 return str;
6881}
6882
6883CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006884 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006885 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006886 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006887 return usage;
6888 }
6889
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006890 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006891 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006892 ASTContext &astContext = astUnit->getASTContext();
6893
6894 // How much memory is used by AST nodes and types?
6895 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6896 (unsigned long) astContext.getASTAllocatedMemory());
6897
6898 // How much memory is used by identifiers?
6899 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6900 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6901
6902 // How much memory is used for selectors?
6903 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6904 (unsigned long) astContext.Selectors.getTotalMemory());
6905
6906 // How much memory is used by ASTContext's side tables?
6907 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6908 (unsigned long) astContext.getSideTableAllocatedMemory());
6909
6910 // How much memory is used for caching global code completion results?
6911 unsigned long completionBytes = 0;
6912 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006913 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006914 completionBytes = completionAllocator->getTotalMemory();
6915 }
6916 createCXTUResourceUsageEntry(*entries,
6917 CXTUResourceUsage_GlobalCompletionResults,
6918 completionBytes);
6919
6920 // How much memory is being used by SourceManager's content cache?
6921 createCXTUResourceUsageEntry(*entries,
6922 CXTUResourceUsage_SourceManagerContentCache,
6923 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6924
6925 // How much memory is being used by the MemoryBuffer's in SourceManager?
6926 const SourceManager::MemoryBufferSizes &srcBufs =
6927 astUnit->getSourceManager().getMemoryBufferSizes();
6928
6929 createCXTUResourceUsageEntry(*entries,
6930 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6931 (unsigned long) srcBufs.malloc_bytes);
6932 createCXTUResourceUsageEntry(*entries,
6933 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6934 (unsigned long) srcBufs.mmap_bytes);
6935 createCXTUResourceUsageEntry(*entries,
6936 CXTUResourceUsage_SourceManager_DataStructures,
6937 (unsigned long) astContext.getSourceManager()
6938 .getDataStructureSizes());
6939
6940 // How much memory is being used by the ExternalASTSource?
6941 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6942 const ExternalASTSource::MemoryBufferSizes &sizes =
6943 esrc->getMemoryBufferSizes();
6944
6945 createCXTUResourceUsageEntry(*entries,
6946 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6947 (unsigned long) sizes.malloc_bytes);
6948 createCXTUResourceUsageEntry(*entries,
6949 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6950 (unsigned long) sizes.mmap_bytes);
6951 }
6952
6953 // How much memory is being used by the Preprocessor?
6954 Preprocessor &pp = astUnit->getPreprocessor();
6955 createCXTUResourceUsageEntry(*entries,
6956 CXTUResourceUsage_Preprocessor,
6957 pp.getTotalMemory());
6958
6959 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6960 createCXTUResourceUsageEntry(*entries,
6961 CXTUResourceUsage_PreprocessingRecord,
6962 pRec->getTotalMemory());
6963 }
6964
6965 createCXTUResourceUsageEntry(*entries,
6966 CXTUResourceUsage_Preprocessor_HeaderSearch,
6967 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006968
Guy Benyei11169dd2012-12-18 14:30:41 +00006969 CXTUResourceUsage usage = { (void*) entries.get(),
6970 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00006971 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006972 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006973 return usage;
6974}
6975
6976void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6977 if (usage.data)
6978 delete (MemUsageEntries*) usage.data;
6979}
6980
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006981CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6982 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006983 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006984 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006985
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006986 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006987 LOG_BAD_TU(TU);
6988 return skipped;
6989 }
6990
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006991 if (!file)
6992 return skipped;
6993
6994 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6995 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6996 if (!ppRec)
6997 return skipped;
6998
6999 ASTContext &Ctx = astUnit->getASTContext();
7000 SourceManager &sm = Ctx.getSourceManager();
7001 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7002 FileID wantedFileID = sm.translateFile(fileEntry);
7003
7004 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7005 std::vector<SourceRange> wantedRanges;
7006 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7007 i != ei; ++i) {
7008 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7009 wantedRanges.push_back(*i);
7010 }
7011
7012 skipped->count = wantedRanges.size();
7013 skipped->ranges = new CXSourceRange[skipped->count];
7014 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7015 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7016
7017 return skipped;
7018}
7019
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007020void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7021 if (ranges) {
7022 delete[] ranges->ranges;
7023 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007024 }
7025}
7026
Guy Benyei11169dd2012-12-18 14:30:41 +00007027} // end extern "C"
7028
7029void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7030 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7031 for (unsigned I = 0; I != Usage.numEntries; ++I)
7032 fprintf(stderr, " %s: %lu\n",
7033 clang_getTUResourceUsageName(Usage.entries[I].kind),
7034 Usage.entries[I].amount);
7035
7036 clang_disposeCXTUResourceUsage(Usage);
7037}
7038
7039//===----------------------------------------------------------------------===//
7040// Misc. utility functions.
7041//===----------------------------------------------------------------------===//
7042
7043/// Default to using an 8 MB stack size on "safety" threads.
7044static unsigned SafetyStackThreadSize = 8 << 20;
7045
7046namespace clang {
7047
7048bool RunSafely(llvm::CrashRecoveryContext &CRC,
7049 void (*Fn)(void*), void *UserData,
7050 unsigned Size) {
7051 if (!Size)
7052 Size = GetSafetyThreadStackSize();
7053 if (Size)
7054 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7055 return CRC.RunSafely(Fn, UserData);
7056}
7057
7058unsigned GetSafetyThreadStackSize() {
7059 return SafetyStackThreadSize;
7060}
7061
7062void SetSafetyThreadStackSize(unsigned Value) {
7063 SafetyStackThreadSize = Value;
7064}
7065
7066}
7067
7068void clang::setThreadBackgroundPriority() {
7069 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7070 return;
7071
Alp Toker1a86ad22014-07-06 06:24:00 +00007072#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007073 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7074#endif
7075}
7076
7077void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7078 if (!Unit)
7079 return;
7080
7081 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7082 DEnd = Unit->stored_diag_end();
7083 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007084 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007085 CXString Msg = clang_formatDiagnostic(&Diag,
7086 clang_defaultDiagnosticDisplayOptions());
7087 fprintf(stderr, "%s\n", clang_getCString(Msg));
7088 clang_disposeString(Msg);
7089 }
7090#ifdef LLVM_ON_WIN32
7091 // On Windows, force a flush, since there may be multiple copies of
7092 // stderr and stdout in the file system, all with different buffers
7093 // but writing to the same device.
7094 fflush(stderr);
7095#endif
7096}
7097
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007098MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7099 SourceLocation MacroDefLoc,
7100 CXTranslationUnit TU){
7101 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007102 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007103 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007104 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007105
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007106 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007107 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007108 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007109 if (MD) {
7110 for (MacroDirective::DefInfo
7111 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7112 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7113 return Def.getMacroInfo();
7114 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007115 }
7116
Craig Topper69186e72014-06-08 08:38:04 +00007117 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007118}
7119
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007120const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7121 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007122 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007123 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007124 const IdentifierInfo *II = MacroDef->getName();
7125 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007126 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007127
7128 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7129}
7130
7131MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7132 const Token &Tok,
7133 CXTranslationUnit TU) {
7134 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007135 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007136 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007137 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007138
7139 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007140 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007141 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7142 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007143 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007144
7145 // Check that the token is inside the definition and not its argument list.
7146 SourceManager &SM = Unit->getSourceManager();
7147 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007148 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007149 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007150 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007151
7152 Preprocessor &PP = Unit->getPreprocessor();
7153 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7154 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007155 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007156
Alp Toker2d57cea2014-05-17 04:53:25 +00007157 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007158 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007159 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007160
7161 // Check that the identifier is not one of the macro arguments.
7162 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007163 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007164
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007165 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7166 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007167 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007168
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007169 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007170}
7171
7172MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7173 SourceLocation Loc,
7174 CXTranslationUnit TU) {
7175 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007176 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007177
7178 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007179 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007180 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007181 Preprocessor &PP = Unit->getPreprocessor();
7182 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007183 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007184 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7185 Token Tok;
7186 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007187 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007188
7189 return checkForMacroInMacroDefinition(MI, Tok, TU);
7190}
7191
Guy Benyei11169dd2012-12-18 14:30:41 +00007192extern "C" {
7193
7194CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007195 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007196}
7197
7198} // end: extern "C"
7199
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007200Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7201 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007202 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007203 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007204 if (Unit->isMainFileAST())
7205 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007206 return *this;
7207 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007208 } else {
7209 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007210 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007211 return *this;
7212}
7213
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007214Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7215 *this << FE->getName();
7216 return *this;
7217}
7218
7219Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7220 CXString cursorName = clang_getCursorDisplayName(cursor);
7221 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7222 clang_disposeString(cursorName);
7223 return *this;
7224}
7225
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007226Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7227 CXFile File;
7228 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007229 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007230 CXString FileName = clang_getFileName(File);
7231 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7232 clang_disposeString(FileName);
7233 return *this;
7234}
7235
7236Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7237 CXSourceLocation BLoc = clang_getRangeStart(range);
7238 CXSourceLocation ELoc = clang_getRangeEnd(range);
7239
7240 CXFile BFile;
7241 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007242 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007243
7244 CXFile EFile;
7245 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007246 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007247
7248 CXString BFileName = clang_getFileName(BFile);
7249 if (BFile == EFile) {
7250 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7251 BLine, BColumn, ELine, EColumn);
7252 } else {
7253 CXString EFileName = clang_getFileName(EFile);
7254 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7255 BLine, BColumn)
7256 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7257 ELine, EColumn);
7258 clang_disposeString(EFileName);
7259 }
7260 clang_disposeString(BFileName);
7261 return *this;
7262}
7263
7264Logger &cxindex::Logger::operator<<(CXString Str) {
7265 *this << clang_getCString(Str);
7266 return *this;
7267}
7268
7269Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7270 LogOS << Fmt;
7271 return *this;
7272}
7273
Chandler Carruth37ad2582014-06-27 15:14:39 +00007274static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7275
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007276cxindex::Logger::~Logger() {
7277 LogOS.flush();
7278
Chandler Carruth37ad2582014-06-27 15:14:39 +00007279 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007280
7281 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7282
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007283 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007284 OS << "[libclang:" << Name << ':';
7285
Alp Toker1a86ad22014-07-06 06:24:00 +00007286#ifdef USE_DARWIN_THREADS
7287 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007288 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7289 OS << tid << ':';
7290#endif
7291
7292 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7293 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007294 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007295
7296 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007297 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007298 OS << "--------------------------------------------------\n";
7299 }
7300}