blob: 0ce86728df2d8e66a078949e1ecdb6ea1c9a0502 [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);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002056 for (auto *E : C->source_exprs()) {
2057 Visitor->AddStmt(E);
2058 }
2059 for (auto *E : C->destination_exprs()) {
2060 Visitor->AddStmt(E);
2061 }
2062 for (auto *E : C->assignment_ops()) {
2063 Visitor->AddStmt(E);
2064 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002065}
Alexey Bataev6125da92014-07-21 11:26:11 +00002066void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2067 VisitOMPClauseList(C);
2068}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002069}
Alexey Bataev756c1962013-09-24 03:17:45 +00002070
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002071void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2072 unsigned size = WL.size();
2073 OMPClauseEnqueue Visitor(this);
2074 Visitor.Visit(S);
2075 if (size == WL.size())
2076 return;
2077 // Now reverse the entries we just added. This will match the DFS
2078 // ordering performed by the worklist.
2079 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2080 std::reverse(I, E);
2081}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2084}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002085void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002086 AddDecl(B->getBlockDecl());
2087}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 EnqueueChildren(E);
2090 AddTypeLoc(E->getTypeSourceInfo());
2091}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2093 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 E = S->body_rend(); I != E; ++I) {
2095 AddStmt(*I);
2096 }
2097}
2098void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002100 AddStmt(S->getSubStmt());
2101 AddDeclarationNameInfo(S);
2102 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2103 AddNestedNameSpecifierLoc(QualifierLoc);
2104}
2105
2106void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002107VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002108 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2109 AddDeclarationNameInfo(E);
2110 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2111 AddNestedNameSpecifierLoc(QualifierLoc);
2112 if (!E->isImplicitAccess())
2113 AddStmt(E->getBase());
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 // Enqueue the initializer , if any.
2117 AddStmt(E->getInitializer());
2118 // Enqueue the array size, if any.
2119 AddStmt(E->getArraySize());
2120 // Enqueue the allocated type.
2121 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2122 // Enqueue the placement arguments.
2123 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2124 AddStmt(E->getPlacementArg(I-1));
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2128 AddStmt(CE->getArg(I-1));
2129 AddStmt(CE->getCallee());
2130 AddStmt(CE->getArg(0));
2131}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2133 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002134 // Visit the name of the type being destroyed.
2135 AddTypeLoc(E->getDestroyedTypeInfo());
2136 // Visit the scope type that looks disturbingly like the nested-name-specifier
2137 // but isn't.
2138 AddTypeLoc(E->getScopeTypeInfo());
2139 // Visit the nested-name-specifier.
2140 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2141 AddNestedNameSpecifierLoc(QualifierLoc);
2142 // Visit base expression.
2143 AddStmt(E->getBase());
2144}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002145void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2146 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 AddTypeLoc(E->getTypeSourceInfo());
2148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2150 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002151 EnqueueChildren(E);
2152 AddTypeLoc(E->getTypeSourceInfo());
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 EnqueueChildren(E);
2156 if (E->isTypeOperand())
2157 AddTypeLoc(E->getTypeOperandSourceInfo());
2158}
2159
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002160void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2161 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002162 EnqueueChildren(E);
2163 AddTypeLoc(E->getTypeSourceInfo());
2164}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002165void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002166 EnqueueChildren(E);
2167 if (E->isTypeOperand())
2168 AddTypeLoc(E->getTypeOperandSourceInfo());
2169}
2170
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002171void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 EnqueueChildren(S);
2173 AddDecl(S->getExceptionDecl());
2174}
2175
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002176void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002177 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002178 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002179 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002180}
2181
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 if (DR->hasExplicitTemplateArgs()) {
2184 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2185 }
2186 WL.push_back(DeclRefExprParts(DR, Parent));
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2189 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2191 AddDeclarationNameInfo(E);
2192 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2193}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 unsigned size = WL.size();
2196 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002197 for (const auto *D : S->decls()) {
2198 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 isFirst = false;
2200 }
2201 if (size == WL.size())
2202 return;
2203 // Now reverse the entries we just added. This will match the DFS
2204 // ordering performed by the worklist.
2205 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2206 std::reverse(I, E);
2207}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002210 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002211 D = E->designators_rbegin(), DEnd = E->designators_rend();
2212 D != DEnd; ++D) {
2213 if (D->isFieldDesignator()) {
2214 if (FieldDecl *Field = D->getField())
2215 AddMemberRef(Field, D->getFieldLoc());
2216 continue;
2217 }
2218 if (D->isArrayDesignator()) {
2219 AddStmt(E->getArrayIndex(*D));
2220 continue;
2221 }
2222 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2223 AddStmt(E->getArrayRangeEnd(*D));
2224 AddStmt(E->getArrayRangeStart(*D));
2225 }
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 EnqueueChildren(E);
2229 AddTypeLoc(E->getTypeInfoAsWritten());
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddStmt(FS->getBody());
2233 AddStmt(FS->getInc());
2234 AddStmt(FS->getCond());
2235 AddDecl(FS->getConditionVariable());
2236 AddStmt(FS->getInit());
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2240}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002242 AddStmt(If->getElse());
2243 AddStmt(If->getThen());
2244 AddStmt(If->getCond());
2245 AddDecl(If->getConditionVariable());
2246}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 // We care about the syntactic form of the initializer list, only.
2249 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2250 IE = Syntactic;
2251 EnqueueChildren(IE);
2252}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 WL.push_back(MemberExprParts(M, Parent));
2255
2256 // If the base of the member access expression is an implicit 'this', don't
2257 // visit it.
2258 // FIXME: If we ever want to show these implicit accesses, this will be
2259 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002260 if (M->isImplicitAccess())
2261 return;
2262
2263 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2264 // real field that that we are interested in.
2265 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2266 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2267 if (FD->isAnonymousStructOrUnion()) {
2268 AddStmt(SubME->getBase());
2269 return;
2270 }
2271 }
2272 }
2273
2274 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002275}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 AddTypeLoc(E->getEncodedTypeSourceInfo());
2278}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 EnqueueChildren(M);
2281 AddTypeLoc(M->getClassReceiverTypeInfo());
2282}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002283void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 // Visit the components of the offsetof expression.
2285 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2286 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2287 const OffsetOfNode &Node = E->getComponent(I-1);
2288 switch (Node.getKind()) {
2289 case OffsetOfNode::Array:
2290 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2291 break;
2292 case OffsetOfNode::Field:
2293 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2294 break;
2295 case OffsetOfNode::Identifier:
2296 case OffsetOfNode::Base:
2297 continue;
2298 }
2299 }
2300 // Visit the type into which we're computing the offset.
2301 AddTypeLoc(E->getTypeSourceInfo());
2302}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002303void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002304 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2305 WL.push_back(OverloadExprParts(E, Parent));
2306}
2307void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 EnqueueChildren(E);
2310 if (E->isArgumentType())
2311 AddTypeLoc(E->getArgumentTypeInfo());
2312}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 EnqueueChildren(S);
2315}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002316void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002317 AddStmt(S->getBody());
2318 AddStmt(S->getCond());
2319 AddDecl(S->getConditionVariable());
2320}
2321
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002322void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 AddStmt(W->getBody());
2324 AddStmt(W->getCond());
2325 AddDecl(W->getConditionVariable());
2326}
2327
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002328void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002329 for (unsigned I = E->getNumArgs(); I > 0; --I)
2330 AddTypeLoc(E->getArg(I-1));
2331}
2332
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002333void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002334 AddTypeLoc(E->getQueriedTypeSourceInfo());
2335}
2336
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002337void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002338 EnqueueChildren(E);
2339}
2340
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002341void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002342 VisitOverloadExpr(U);
2343 if (!U->isImplicitAccess())
2344 AddStmt(U->getBase());
2345}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002346void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002347 AddStmt(E->getSubExpr());
2348 AddTypeLoc(E->getWrittenTypeInfo());
2349}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002350void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002351 WL.push_back(SizeOfPackExprParts(E, Parent));
2352}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002353void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002354 // If the opaque value has a source expression, just transparently
2355 // visit that. This is useful for (e.g.) pseudo-object expressions.
2356 if (Expr *SourceExpr = E->getSourceExpr())
2357 return Visit(SourceExpr);
2358}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002359void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002360 AddStmt(E->getBody());
2361 WL.push_back(LambdaExprParts(E, Parent));
2362}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002363void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002364 // Treat the expression like its syntactic form.
2365 Visit(E->getSyntacticForm());
2366}
2367
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002368void EnqueueVisitor::VisitOMPExecutableDirective(
2369 const OMPExecutableDirective *D) {
2370 EnqueueChildren(D);
2371 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2372 E = D->clauses().end();
2373 I != E; ++I)
2374 EnqueueChildren(*I);
2375}
2376
Alexander Musman3aaab662014-08-19 11:27:13 +00002377void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2378 VisitOMPExecutableDirective(D);
2379}
2380
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002381void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2382 VisitOMPExecutableDirective(D);
2383}
2384
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002385void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002386 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002387}
2388
Alexey Bataevf29276e2014-06-18 04:14:57 +00002389void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002390 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002391}
2392
Alexander Musmanf82886e2014-09-18 05:12:34 +00002393void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2394 VisitOMPLoopDirective(D);
2395}
2396
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002397void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2398 VisitOMPExecutableDirective(D);
2399}
2400
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002401void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2402 VisitOMPExecutableDirective(D);
2403}
2404
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002405void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2406 VisitOMPExecutableDirective(D);
2407}
2408
Alexander Musman80c22892014-07-17 08:54:58 +00002409void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2410 VisitOMPExecutableDirective(D);
2411}
2412
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002413void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2414 VisitOMPExecutableDirective(D);
2415 AddDeclarationNameInfo(D);
2416}
2417
Alexey Bataev4acb8592014-07-07 13:01:15 +00002418void
2419EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002420 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002421}
2422
Alexander Musmane4e893b2014-09-23 09:33:00 +00002423void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2424 const OMPParallelForSimdDirective *D) {
2425 VisitOMPLoopDirective(D);
2426}
2427
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002428void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2429 const OMPParallelSectionsDirective *D) {
2430 VisitOMPExecutableDirective(D);
2431}
2432
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002433void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2434 VisitOMPExecutableDirective(D);
2435}
2436
Alexey Bataev68446b72014-07-18 07:47:19 +00002437void
2438EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2439 VisitOMPExecutableDirective(D);
2440}
2441
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002442void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2443 VisitOMPExecutableDirective(D);
2444}
2445
Alexey Bataev2df347a2014-07-18 10:17:07 +00002446void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2447 VisitOMPExecutableDirective(D);
2448}
2449
Alexey Bataev6125da92014-07-21 11:26:11 +00002450void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2451 VisitOMPExecutableDirective(D);
2452}
2453
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002454void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2455 VisitOMPExecutableDirective(D);
2456}
2457
Alexey Bataev0162e452014-07-22 10:10:35 +00002458void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2459 VisitOMPExecutableDirective(D);
2460}
2461
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002462void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2463 VisitOMPExecutableDirective(D);
2464}
2465
Alexey Bataev13314bf2014-10-09 04:18:56 +00002466void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2467 VisitOMPExecutableDirective(D);
2468}
2469
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002470void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002471 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2472}
2473
2474bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2475 if (RegionOfInterest.isValid()) {
2476 SourceRange Range = getRawCursorExtent(C);
2477 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2478 return false;
2479 }
2480 return true;
2481}
2482
2483bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2484 while (!WL.empty()) {
2485 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002486 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002487
2488 // Set the Parent field, then back to its old value once we're done.
2489 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2490
2491 switch (LI.getKind()) {
2492 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002493 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002494 if (!D)
2495 continue;
2496
2497 // For now, perform default visitation for Decls.
2498 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2499 cast<DeclVisit>(&LI)->isFirst())))
2500 return true;
2501
2502 continue;
2503 }
2504 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2505 const ASTTemplateArgumentListInfo *ArgList =
2506 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2507 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2508 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2509 Arg != ArgEnd; ++Arg) {
2510 if (VisitTemplateArgumentLoc(*Arg))
2511 return true;
2512 }
2513 continue;
2514 }
2515 case VisitorJob::TypeLocVisitKind: {
2516 // Perform default visitation for TypeLocs.
2517 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2518 return true;
2519 continue;
2520 }
2521 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002522 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002523 if (LabelStmt *stmt = LS->getStmt()) {
2524 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2525 TU))) {
2526 return true;
2527 }
2528 }
2529 continue;
2530 }
2531
2532 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2533 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2534 if (VisitNestedNameSpecifierLoc(V->get()))
2535 return true;
2536 continue;
2537 }
2538
2539 case VisitorJob::DeclarationNameInfoVisitKind: {
2540 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2541 ->get()))
2542 return true;
2543 continue;
2544 }
2545 case VisitorJob::MemberRefVisitKind: {
2546 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2547 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2548 return true;
2549 continue;
2550 }
2551 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002552 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002553 if (!S)
2554 continue;
2555
2556 // Update the current cursor.
2557 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2558 if (!IsInRegionOfInterest(Cursor))
2559 continue;
2560 switch (Visitor(Cursor, Parent, ClientData)) {
2561 case CXChildVisit_Break: return true;
2562 case CXChildVisit_Continue: break;
2563 case CXChildVisit_Recurse:
2564 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002565 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002566 EnqueueWorkList(WL, S);
2567 break;
2568 }
2569 continue;
2570 }
2571 case VisitorJob::MemberExprPartsKind: {
2572 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002573 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002574
2575 // Visit the nested-name-specifier
2576 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2577 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2578 return true;
2579
2580 // Visit the declaration name.
2581 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2582 return true;
2583
2584 // Visit the explicitly-specified template arguments, if any.
2585 if (M->hasExplicitTemplateArgs()) {
2586 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2587 *ArgEnd = Arg + M->getNumTemplateArgs();
2588 Arg != ArgEnd; ++Arg) {
2589 if (VisitTemplateArgumentLoc(*Arg))
2590 return true;
2591 }
2592 }
2593 continue;
2594 }
2595 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002596 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002597 // Visit nested-name-specifier, if present.
2598 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2599 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2600 return true;
2601 // Visit declaration name.
2602 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2603 return true;
2604 continue;
2605 }
2606 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002607 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002608 // Visit the nested-name-specifier.
2609 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2610 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2611 return true;
2612 // Visit the declaration name.
2613 if (VisitDeclarationNameInfo(O->getNameInfo()))
2614 return true;
2615 // Visit the overloaded declaration reference.
2616 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2617 return true;
2618 continue;
2619 }
2620 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002621 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002622 NamedDecl *Pack = E->getPack();
2623 if (isa<TemplateTypeParmDecl>(Pack)) {
2624 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2625 E->getPackLoc(), TU)))
2626 return true;
2627
2628 continue;
2629 }
2630
2631 if (isa<TemplateTemplateParmDecl>(Pack)) {
2632 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2633 E->getPackLoc(), TU)))
2634 return true;
2635
2636 continue;
2637 }
2638
2639 // Non-type template parameter packs and function parameter packs are
2640 // treated like DeclRefExpr cursors.
2641 continue;
2642 }
2643
2644 case VisitorJob::LambdaExprPartsKind: {
2645 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002646 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002647 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2648 CEnd = E->explicit_capture_end();
2649 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002650 // FIXME: Lambda init-captures.
2651 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002652 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002653
Guy Benyei11169dd2012-12-18 14:30:41 +00002654 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2655 C->getLocation(),
2656 TU)))
2657 return true;
2658 }
2659
2660 // Visit parameters and return type, if present.
2661 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2662 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2663 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2664 // Visit the whole type.
2665 if (Visit(TL))
2666 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002667 } else if (FunctionProtoTypeLoc Proto =
2668 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002669 if (E->hasExplicitParameters()) {
2670 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002671 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2672 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002673 return true;
2674 } else {
2675 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002676 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002677 return true;
2678 }
2679 }
2680 }
2681 break;
2682 }
2683
2684 case VisitorJob::PostChildrenVisitKind:
2685 if (PostChildrenVisitor(Parent, ClientData))
2686 return true;
2687 break;
2688 }
2689 }
2690 return false;
2691}
2692
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002693bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002694 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002695 if (!WorkListFreeList.empty()) {
2696 WL = WorkListFreeList.back();
2697 WL->clear();
2698 WorkListFreeList.pop_back();
2699 }
2700 else {
2701 WL = new VisitorWorkList();
2702 WorkListCache.push_back(WL);
2703 }
2704 EnqueueWorkList(*WL, S);
2705 bool result = RunVisitorWorkList(*WL);
2706 WorkListFreeList.push_back(WL);
2707 return result;
2708}
2709
2710namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002711typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002712RefNamePieces
2713buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2714 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2715 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002716 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2717 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2718 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2719
2720 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2721
2722 RefNamePieces Pieces;
2723
2724 if (WantQualifier && QLoc.isValid())
2725 Pieces.push_back(QLoc);
2726
2727 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2728 Pieces.push_back(NI.getLoc());
2729
2730 if (WantTemplateArgs && TemplateArgs)
2731 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2732 TemplateArgs->RAngleLoc));
2733
2734 if (Kind == DeclarationName::CXXOperatorName) {
2735 Pieces.push_back(SourceLocation::getFromRawEncoding(
2736 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2737 Pieces.push_back(SourceLocation::getFromRawEncoding(
2738 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2739 }
2740
2741 if (WantSinglePiece) {
2742 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2743 Pieces.clear();
2744 Pieces.push_back(R);
2745 }
2746
2747 return Pieces;
2748}
2749}
2750
2751//===----------------------------------------------------------------------===//
2752// Misc. API hooks.
2753//===----------------------------------------------------------------------===//
2754
Chad Rosier05c71aa2013-03-27 18:28:23 +00002755static void fatal_error_handler(void *user_data, const std::string& reason,
2756 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002757 // Write the result out to stderr avoiding errs() because raw_ostreams can
2758 // call report_fatal_error.
2759 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2760 ::abort();
2761}
2762
Chandler Carruth66660742014-06-27 16:37:27 +00002763namespace {
2764struct RegisterFatalErrorHandler {
2765 RegisterFatalErrorHandler() {
2766 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2767 }
2768};
2769}
2770
2771static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2772
Guy Benyei11169dd2012-12-18 14:30:41 +00002773extern "C" {
2774CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2775 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002776 // We use crash recovery to make some of our APIs more reliable, implicitly
2777 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002778 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2779 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002780
Chandler Carruth66660742014-06-27 16:37:27 +00002781 // Look through the managed static to trigger construction of the managed
2782 // static which registers our fatal error handler. This ensures it is only
2783 // registered once.
2784 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002785
2786 CIndexer *CIdxr = new CIndexer();
2787 if (excludeDeclarationsFromPCH)
2788 CIdxr->setOnlyLocalDecls();
2789 if (displayDiagnostics)
2790 CIdxr->setDisplayDiagnostics();
2791
2792 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2793 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2794 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2795 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2796 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2797 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2798
2799 return CIdxr;
2800}
2801
2802void clang_disposeIndex(CXIndex CIdx) {
2803 if (CIdx)
2804 delete static_cast<CIndexer *>(CIdx);
2805}
2806
2807void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2808 if (CIdx)
2809 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2810}
2811
2812unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2813 if (CIdx)
2814 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2815 return 0;
2816}
2817
2818void clang_toggleCrashRecovery(unsigned isEnabled) {
2819 if (isEnabled)
2820 llvm::CrashRecoveryContext::Enable();
2821 else
2822 llvm::CrashRecoveryContext::Disable();
2823}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002824
Guy Benyei11169dd2012-12-18 14:30:41 +00002825CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2826 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002827 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002828 enum CXErrorCode Result =
2829 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002830 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002831 assert((TU && Result == CXError_Success) ||
2832 (!TU && Result != CXError_Success));
2833 return TU;
2834}
2835
2836enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2837 const char *ast_filename,
2838 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002839 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002840 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002841
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002842 if (!CIdx || !ast_filename || !out_TU)
2843 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002844
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002845 LOG_FUNC_SECTION {
2846 *Log << ast_filename;
2847 }
2848
Guy Benyei11169dd2012-12-18 14:30:41 +00002849 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2850 FileSystemOptions FileSystemOpts;
2851
Justin Bognerd512c1e2014-10-15 00:33:06 +00002852 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2853 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002854 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2855 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2856 /*CaptureDiagnostics=*/true,
2857 /*AllowPCHWithCompilerErrors=*/true,
2858 /*UserFilesAreVolatile=*/true);
2859 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002860 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002861}
2862
2863unsigned clang_defaultEditingTranslationUnitOptions() {
2864 return CXTranslationUnit_PrecompiledPreamble |
2865 CXTranslationUnit_CacheCompletionResults;
2866}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002867
Guy Benyei11169dd2012-12-18 14:30:41 +00002868CXTranslationUnit
2869clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2870 const char *source_filename,
2871 int num_command_line_args,
2872 const char * const *command_line_args,
2873 unsigned num_unsaved_files,
2874 struct CXUnsavedFile *unsaved_files) {
2875 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2876 return clang_parseTranslationUnit(CIdx, source_filename,
2877 command_line_args, num_command_line_args,
2878 unsaved_files, num_unsaved_files,
2879 Options);
2880}
2881
2882struct ParseTranslationUnitInfo {
2883 CXIndex CIdx;
2884 const char *source_filename;
2885 const char *const *command_line_args;
2886 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002887 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002888 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002889 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002890 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002891};
2892static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002893 const ParseTranslationUnitInfo *PTUI =
2894 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002895 CXIndex CIdx = PTUI->CIdx;
2896 const char *source_filename = PTUI->source_filename;
2897 const char * const *command_line_args = PTUI->command_line_args;
2898 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002899 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002900 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002901
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002902 // Set up the initial return values.
2903 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002904 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002905
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002906 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002907 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002908 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002909 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002910 }
2911
Guy Benyei11169dd2012-12-18 14:30:41 +00002912 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2913
2914 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2915 setThreadBackgroundPriority();
2916
2917 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2918 // FIXME: Add a flag for modules.
2919 TranslationUnitKind TUKind
2920 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002921 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002922 = options & CXTranslationUnit_CacheCompletionResults;
2923 bool IncludeBriefCommentsInCodeCompletion
2924 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2925 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2926 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2927
2928 // Configure the diagnostics.
2929 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002930 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002931
2932 // Recover resources if we crash before exiting this function.
2933 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2934 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002935 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002936
Ahmed Charlesb8984322014-03-07 20:03:18 +00002937 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2938 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002939
2940 // Recover resources if we crash before exiting this function.
2941 llvm::CrashRecoveryContextCleanupRegistrar<
2942 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2943
Alp Toker9d85b182014-07-07 01:23:14 +00002944 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002945 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002946 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002947 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002948 }
2949
Ahmed Charlesb8984322014-03-07 20:03:18 +00002950 std::unique_ptr<std::vector<const char *>> Args(
2951 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002952
2953 // Recover resources if we crash before exiting this method.
2954 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2955 ArgsCleanup(Args.get());
2956
2957 // Since the Clang C library is primarily used by batch tools dealing with
2958 // (often very broken) source code, where spell-checking can have a
2959 // significant negative impact on performance (particularly when
2960 // precompiled headers are involved), we disable it by default.
2961 // Only do this if we haven't found a spell-checking-related argument.
2962 bool FoundSpellCheckingArgument = false;
2963 for (int I = 0; I != num_command_line_args; ++I) {
2964 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2965 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2966 FoundSpellCheckingArgument = true;
2967 break;
2968 }
2969 }
2970 if (!FoundSpellCheckingArgument)
2971 Args->push_back("-fno-spell-checking");
2972
2973 Args->insert(Args->end(), command_line_args,
2974 command_line_args + num_command_line_args);
2975
2976 // The 'source_filename' argument is optional. If the caller does not
2977 // specify it then it is assumed that the source file is specified
2978 // in the actual argument list.
2979 // Put the source file after command_line_args otherwise if '-x' flag is
2980 // present it will be unused.
2981 if (source_filename)
2982 Args->push_back(source_filename);
2983
2984 // Do we need the detailed preprocessing record?
2985 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2986 Args->push_back("-Xclang");
2987 Args->push_back("-detailed-preprocessing-record");
2988 }
2989
2990 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002991 std::unique_ptr<ASTUnit> ErrUnit;
2992 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002993 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002994 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2995 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2996 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2997 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2998 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2999 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003000
3001 if (NumErrors != Diags->getClient()->getNumErrors()) {
3002 // Make sure to check that 'Unit' is non-NULL.
3003 if (CXXIdx->getDisplayDiagnostics())
3004 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3005 }
3006
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003007 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3008 PTUI->result = CXError_ASTReadError;
3009 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003010 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003011 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3012 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003013}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003014
3015CXTranslationUnit
3016clang_parseTranslationUnit(CXIndex CIdx,
3017 const char *source_filename,
3018 const char *const *command_line_args,
3019 int num_command_line_args,
3020 struct CXUnsavedFile *unsaved_files,
3021 unsigned num_unsaved_files,
3022 unsigned options) {
3023 CXTranslationUnit TU;
3024 enum CXErrorCode Result = clang_parseTranslationUnit2(
3025 CIdx, source_filename, command_line_args, num_command_line_args,
3026 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003027 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003028 assert((TU && Result == CXError_Success) ||
3029 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003030 return TU;
3031}
3032
3033enum CXErrorCode clang_parseTranslationUnit2(
3034 CXIndex CIdx,
3035 const char *source_filename,
3036 const char *const *command_line_args,
3037 int num_command_line_args,
3038 struct CXUnsavedFile *unsaved_files,
3039 unsigned num_unsaved_files,
3040 unsigned options,
3041 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003042 LOG_FUNC_SECTION {
3043 *Log << source_filename << ": ";
3044 for (int i = 0; i != num_command_line_args; ++i)
3045 *Log << command_line_args[i] << " ";
3046 }
3047
Alp Toker9d85b182014-07-07 01:23:14 +00003048 if (num_unsaved_files && !unsaved_files)
3049 return CXError_InvalidArguments;
3050
Alp Toker5c532982014-07-07 22:42:03 +00003051 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003052 ParseTranslationUnitInfo PTUI = {
3053 CIdx,
3054 source_filename,
3055 command_line_args,
3056 num_command_line_args,
3057 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3058 options,
3059 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003060 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003061 llvm::CrashRecoveryContext CRC;
3062
3063 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3064 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3065 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3066 fprintf(stderr, " 'command_line_args' : [");
3067 for (int i = 0; i != num_command_line_args; ++i) {
3068 if (i)
3069 fprintf(stderr, ", ");
3070 fprintf(stderr, "'%s'", command_line_args[i]);
3071 }
3072 fprintf(stderr, "],\n");
3073 fprintf(stderr, " 'unsaved_files' : [");
3074 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3075 if (i)
3076 fprintf(stderr, ", ");
3077 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3078 unsaved_files[i].Length);
3079 }
3080 fprintf(stderr, "],\n");
3081 fprintf(stderr, " 'options' : %d,\n", options);
3082 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003083
3084 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003085 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003086 if (CXTranslationUnit *TU = PTUI.out_TU)
3087 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003088 }
Alp Toker5c532982014-07-07 22:42:03 +00003089
3090 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003091}
3092
3093unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3094 return CXSaveTranslationUnit_None;
3095}
3096
3097namespace {
3098
3099struct SaveTranslationUnitInfo {
3100 CXTranslationUnit TU;
3101 const char *FileName;
3102 unsigned options;
3103 CXSaveError result;
3104};
3105
3106}
3107
3108static void clang_saveTranslationUnit_Impl(void *UserData) {
3109 SaveTranslationUnitInfo *STUI =
3110 static_cast<SaveTranslationUnitInfo*>(UserData);
3111
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003112 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003113 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3114 setThreadBackgroundPriority();
3115
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003116 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003117 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3118}
3119
3120int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3121 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003122 LOG_FUNC_SECTION {
3123 *Log << TU << ' ' << FileName;
3124 }
3125
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003126 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003127 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003129 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003130
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003131 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003132 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3133 if (!CXXUnit->hasSema())
3134 return CXSaveError_InvalidTU;
3135
3136 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3137
3138 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3139 getenv("LIBCLANG_NOTHREADS")) {
3140 clang_saveTranslationUnit_Impl(&STUI);
3141
3142 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3143 PrintLibclangResourceUsage(TU);
3144
3145 return STUI.result;
3146 }
3147
3148 // We have an AST that has invalid nodes due to compiler errors.
3149 // Use a crash recovery thread for protection.
3150
3151 llvm::CrashRecoveryContext CRC;
3152
3153 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3154 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3155 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3156 fprintf(stderr, " 'options' : %d,\n", options);
3157 fprintf(stderr, "}\n");
3158
3159 return CXSaveError_Unknown;
3160
3161 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3162 PrintLibclangResourceUsage(TU);
3163 }
3164
3165 return STUI.result;
3166}
3167
3168void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3169 if (CTUnit) {
3170 // If the translation unit has been marked as unsafe to free, just discard
3171 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003172 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3173 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003174 return;
3175
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003176 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003177 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003178 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3179 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003180 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 delete CTUnit;
3182 }
3183}
3184
3185unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3186 return CXReparse_None;
3187}
3188
3189struct ReparseTranslationUnitInfo {
3190 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003191 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003193 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003194};
3195
3196static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003197 const ReparseTranslationUnitInfo *RTUI =
3198 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003199 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003200 unsigned options = RTUI->options;
3201 (void) options;
3202
3203 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003204 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003205 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003206 RTUI->result = CXError_InvalidArguments;
3207 return;
3208 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003209
3210 // Reset the associated diagnostics.
3211 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003212 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003213
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003214 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3216 setThreadBackgroundPriority();
3217
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003218 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003220
3221 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3222 new std::vector<ASTUnit::RemappedFile>());
3223
Guy Benyei11169dd2012-12-18 14:30:41 +00003224 // Recover resources if we crash before exiting this function.
3225 llvm::CrashRecoveryContextCleanupRegistrar<
3226 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003227
3228 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003229 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003230 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003231 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003232 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003233
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003234 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003235 RTUI->result = CXError_Success;
3236 else if (isASTReadError(CXXUnit))
3237 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003238}
3239
3240int clang_reparseTranslationUnit(CXTranslationUnit TU,
3241 unsigned num_unsaved_files,
3242 struct CXUnsavedFile *unsaved_files,
3243 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003244 LOG_FUNC_SECTION {
3245 *Log << TU;
3246 }
3247
Alp Toker9d85b182014-07-07 01:23:14 +00003248 if (num_unsaved_files && !unsaved_files)
3249 return CXError_InvalidArguments;
3250
Alp Toker5c532982014-07-07 22:42:03 +00003251 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003252 ReparseTranslationUnitInfo RTUI = {
3253 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003254 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003255
3256 if (getenv("LIBCLANG_NOTHREADS")) {
3257 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003258 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 }
3260
3261 llvm::CrashRecoveryContext CRC;
3262
3263 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3264 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003265 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003266 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3268 PrintLibclangResourceUsage(TU);
3269
Alp Toker5c532982014-07-07 22:42:03 +00003270 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003271}
3272
3273
3274CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003275 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003276 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003277 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003278 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003279
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003280 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003281 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003282}
3283
3284CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003285 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003286 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003287 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003288 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003289
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003290 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3292}
3293
3294} // end: extern "C"
3295
3296//===----------------------------------------------------------------------===//
3297// CXFile Operations.
3298//===----------------------------------------------------------------------===//
3299
3300extern "C" {
3301CXString clang_getFileName(CXFile SFile) {
3302 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003303 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003304
3305 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003306 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003307}
3308
3309time_t clang_getFileTime(CXFile SFile) {
3310 if (!SFile)
3311 return 0;
3312
3313 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3314 return FEnt->getModificationTime();
3315}
3316
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003317CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003318 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003319 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003320 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003321 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003322
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003323 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003324
3325 FileManager &FMgr = CXXUnit->getFileManager();
3326 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3327}
3328
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003329unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3330 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003331 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003332 LOG_BAD_TU(TU);
3333 return 0;
3334 }
3335
3336 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 return 0;
3338
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003339 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 FileEntry *FEnt = static_cast<FileEntry *>(file);
3341 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3342 .isFileMultipleIncludeGuarded(FEnt);
3343}
3344
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003345int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3346 if (!file || !outID)
3347 return 1;
3348
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003349 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003350 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3351 outID->data[0] = ID.getDevice();
3352 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003353 outID->data[2] = FEnt->getModificationTime();
3354 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003355}
3356
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003357int clang_File_isEqual(CXFile file1, CXFile file2) {
3358 if (file1 == file2)
3359 return true;
3360
3361 if (!file1 || !file2)
3362 return false;
3363
3364 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3365 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3366 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3367}
3368
Guy Benyei11169dd2012-12-18 14:30:41 +00003369} // end: extern "C"
3370
3371//===----------------------------------------------------------------------===//
3372// CXCursor Operations.
3373//===----------------------------------------------------------------------===//
3374
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003375static const Decl *getDeclFromExpr(const Stmt *E) {
3376 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 return getDeclFromExpr(CE->getSubExpr());
3378
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003379 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003381 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003383 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003385 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 if (PRE->isExplicitProperty())
3387 return PRE->getExplicitProperty();
3388 // It could be messaging both getter and setter as in:
3389 // ++myobj.myprop;
3390 // in which case prefer to associate the setter since it is less obvious
3391 // from inspecting the source that the setter is going to get called.
3392 if (PRE->isMessagingSetter())
3393 return PRE->getImplicitPropertySetter();
3394 return PRE->getImplicitPropertyGetter();
3395 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003396 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003398 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 if (Expr *Src = OVE->getSourceExpr())
3400 return getDeclFromExpr(Src);
3401
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003402 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003404 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 if (!CE->isElidable())
3406 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003407 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 return OME->getMethodDecl();
3409
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003410 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003412 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3414 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003415 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3417 isa<ParmVarDecl>(SizeOfPack->getPack()))
3418 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003419
3420 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003421}
3422
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003423static SourceLocation getLocationFromExpr(const Expr *E) {
3424 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 return getLocationFromExpr(CE->getSubExpr());
3426
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003427 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003428 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003429 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003430 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003431 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003433 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003435 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003437 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 return PropRef->getLocation();
3439
3440 return E->getLocStart();
3441}
3442
3443extern "C" {
3444
3445unsigned clang_visitChildren(CXCursor parent,
3446 CXCursorVisitor visitor,
3447 CXClientData client_data) {
3448 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3449 /*VisitPreprocessorLast=*/false);
3450 return CursorVis.VisitChildren(parent);
3451}
3452
3453#ifndef __has_feature
3454#define __has_feature(x) 0
3455#endif
3456#if __has_feature(blocks)
3457typedef enum CXChildVisitResult
3458 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3459
3460static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3461 CXClientData client_data) {
3462 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3463 return block(cursor, parent);
3464}
3465#else
3466// If we are compiled with a compiler that doesn't have native blocks support,
3467// define and call the block manually, so the
3468typedef struct _CXChildVisitResult
3469{
3470 void *isa;
3471 int flags;
3472 int reserved;
3473 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3474 CXCursor);
3475} *CXCursorVisitorBlock;
3476
3477static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3478 CXClientData client_data) {
3479 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3480 return block->invoke(block, cursor, parent);
3481}
3482#endif
3483
3484
3485unsigned clang_visitChildrenWithBlock(CXCursor parent,
3486 CXCursorVisitorBlock block) {
3487 return clang_visitChildren(parent, visitWithBlock, block);
3488}
3489
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003490static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003492 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003493
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const ObjCPropertyImplDecl *PropImpl =
3497 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003499 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003500
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003501 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003503 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003504
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003505 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 }
3507
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003508 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003509 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003510
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003511 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3513 // and returns different names. NamedDecl returns the class name and
3514 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003515 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003516
3517 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003518 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003519
3520 SmallString<1024> S;
3521 llvm::raw_svector_ostream os(S);
3522 ND->printName(os);
3523
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003524 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003525}
3526
3527CXString clang_getCursorSpelling(CXCursor C) {
3528 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003529 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003530
3531 if (clang_isReference(C.kind)) {
3532 switch (C.kind) {
3533 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003534 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003535 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 }
3537 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003538 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003539 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 }
3541 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003542 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003544 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 }
3546 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003547 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003548 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 }
3550 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003551 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 assert(Type && "Missing type decl");
3553
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003554 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 getAsString());
3556 }
3557 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003558 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 assert(Template && "Missing template decl");
3560
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003561 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 }
3563
3564 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003565 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 assert(NS && "Missing namespace decl");
3567
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003568 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 }
3570
3571 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003572 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 assert(Field && "Missing member decl");
3574
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003575 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 }
3577
3578 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003579 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 assert(Label && "Missing label");
3581
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003582 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 }
3584
3585 case CXCursor_OverloadedDeclRef: {
3586 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003587 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3588 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003589 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003590 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003592 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003593 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 OverloadedTemplateStorage *Ovl
3595 = Storage.get<OverloadedTemplateStorage*>();
3596 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003597 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003598 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 }
3600
3601 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003602 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 assert(Var && "Missing variable decl");
3604
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003605 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 }
3607
3608 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003609 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 }
3611 }
3612
3613 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003614 const Expr *E = getCursorExpr(C);
3615
3616 if (C.kind == CXCursor_ObjCStringLiteral ||
3617 C.kind == CXCursor_StringLiteral) {
3618 const StringLiteral *SLit;
3619 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3620 SLit = OSL->getString();
3621 } else {
3622 SLit = cast<StringLiteral>(E);
3623 }
3624 SmallString<256> Buf;
3625 llvm::raw_svector_ostream OS(Buf);
3626 SLit->outputString(OS);
3627 return cxstring::createDup(OS.str());
3628 }
3629
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003630 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 if (D)
3632 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003633 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 }
3635
3636 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003637 const Stmt *S = getCursorStmt(C);
3638 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003640
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003641 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 }
3643
3644 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 ->getNameStart());
3647
3648 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 ->getNameStart());
3651
3652 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003653 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003654
3655 if (clang_isDeclaration(C.kind))
3656 return getDeclSpelling(getCursorDecl(C));
3657
3658 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003659 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003660 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 }
3662
3663 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003664 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003665 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 }
3667
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003668 if (C.kind == CXCursor_PackedAttr) {
3669 return cxstring::createRef("packed");
3670 }
3671
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003672 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003673}
3674
3675CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3676 unsigned pieceIndex,
3677 unsigned options) {
3678 if (clang_Cursor_isNull(C))
3679 return clang_getNullRange();
3680
3681 ASTContext &Ctx = getCursorContext(C);
3682
3683 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003684 const Stmt *S = getCursorStmt(C);
3685 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 if (pieceIndex > 0)
3687 return clang_getNullRange();
3688 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3689 }
3690
3691 return clang_getNullRange();
3692 }
3693
3694 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003695 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3697 if (pieceIndex >= ME->getNumSelectorLocs())
3698 return clang_getNullRange();
3699 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3700 }
3701 }
3702
3703 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3704 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003705 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3707 if (pieceIndex >= MD->getNumSelectorLocs())
3708 return clang_getNullRange();
3709 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3710 }
3711 }
3712
3713 if (C.kind == CXCursor_ObjCCategoryDecl ||
3714 C.kind == CXCursor_ObjCCategoryImplDecl) {
3715 if (pieceIndex > 0)
3716 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003717 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3719 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003720 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3722 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3723 }
3724
3725 if (C.kind == CXCursor_ModuleImportDecl) {
3726 if (pieceIndex > 0)
3727 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003728 if (const ImportDecl *ImportD =
3729 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3731 if (!Locs.empty())
3732 return cxloc::translateSourceRange(Ctx,
3733 SourceRange(Locs.front(), Locs.back()));
3734 }
3735 return clang_getNullRange();
3736 }
3737
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003738 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3739 C.kind == CXCursor_ConversionFunction) {
3740 if (pieceIndex > 0)
3741 return clang_getNullRange();
3742 if (const FunctionDecl *FD =
3743 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3744 DeclarationNameInfo FunctionName = FD->getNameInfo();
3745 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3746 }
3747 return clang_getNullRange();
3748 }
3749
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 // FIXME: A CXCursor_InclusionDirective should give the location of the
3751 // filename, but we don't keep track of this.
3752
3753 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3754 // but we don't keep track of this.
3755
3756 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3757 // but we don't keep track of this.
3758
3759 // Default handling, give the location of the cursor.
3760
3761 if (pieceIndex > 0)
3762 return clang_getNullRange();
3763
3764 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3765 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3766 return cxloc::translateSourceRange(Ctx, Loc);
3767}
3768
Eli Bendersky44a206f2014-07-31 18:04:56 +00003769CXString clang_Cursor_getMangling(CXCursor C) {
3770 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3771 return cxstring::createEmpty();
3772
Eli Bendersky44a206f2014-07-31 18:04:56 +00003773 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003774 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003775 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3776 return cxstring::createEmpty();
3777
Eli Bendersky79759592014-08-01 15:01:10 +00003778 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003779 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003780 ASTContext &Ctx = ND->getASTContext();
3781 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003782
Eli Bendersky79759592014-08-01 15:01:10 +00003783 std::string FrontendBuf;
3784 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3785 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003786
Eli Bendersky79759592014-08-01 15:01:10 +00003787 // Now apply backend mangling.
3788 std::unique_ptr<llvm::DataLayout> DL(
3789 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3790 llvm::Mangler BackendMangler(DL.get());
3791
3792 std::string FinalBuf;
3793 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3794 BackendMangler.getNameWithPrefix(FinalBufOS,
3795 llvm::Twine(FrontendBufOS.str()));
3796
3797 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003798}
3799
Guy Benyei11169dd2012-12-18 14:30:41 +00003800CXString clang_getCursorDisplayName(CXCursor C) {
3801 if (!clang_isDeclaration(C.kind))
3802 return clang_getCursorSpelling(C);
3803
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003804 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003806 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003807
3808 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003809 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 D = FunTmpl->getTemplatedDecl();
3811
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003812 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 SmallString<64> Str;
3814 llvm::raw_svector_ostream OS(Str);
3815 OS << *Function;
3816 if (Function->getPrimaryTemplate())
3817 OS << "<>";
3818 OS << "(";
3819 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3820 if (I)
3821 OS << ", ";
3822 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3823 }
3824
3825 if (Function->isVariadic()) {
3826 if (Function->getNumParams())
3827 OS << ", ";
3828 OS << "...";
3829 }
3830 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003831 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 }
3833
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003834 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 SmallString<64> Str;
3836 llvm::raw_svector_ostream OS(Str);
3837 OS << *ClassTemplate;
3838 OS << "<";
3839 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3840 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3841 if (I)
3842 OS << ", ";
3843
3844 NamedDecl *Param = Params->getParam(I);
3845 if (Param->getIdentifier()) {
3846 OS << Param->getIdentifier()->getName();
3847 continue;
3848 }
3849
3850 // There is no parameter name, which makes this tricky. Try to come up
3851 // with something useful that isn't too long.
3852 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3853 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3854 else if (NonTypeTemplateParmDecl *NTTP
3855 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3856 OS << NTTP->getType().getAsString(Policy);
3857 else
3858 OS << "template<...> class";
3859 }
3860
3861 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003862 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 }
3864
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003865 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3867 // If the type was explicitly written, use that.
3868 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003869 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003870
Benjamin Kramer9170e912013-02-22 15:46:01 +00003871 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 llvm::raw_svector_ostream OS(Str);
3873 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003874 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 ClassSpec->getTemplateArgs().data(),
3876 ClassSpec->getTemplateArgs().size(),
3877 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003878 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 }
3880
3881 return clang_getCursorSpelling(C);
3882}
3883
3884CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3885 switch (Kind) {
3886 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004014 case CXCursor_ObjCSelfExpr:
4015 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004104 case CXCursor_SEHLeaveStmt:
4105 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004134 case CXCursor_PackedAttr:
4135 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004136 case CXCursor_PureAttr:
4137 return cxstring::createRef("attribute(pure)");
4138 case CXCursor_ConstAttr:
4139 return cxstring::createRef("attribute(const)");
4140 case CXCursor_NoDuplicateAttr:
4141 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004142 case CXCursor_CUDAConstantAttr:
4143 return cxstring::createRef("attribute(constant)");
4144 case CXCursor_CUDADeviceAttr:
4145 return cxstring::createRef("attribute(device)");
4146 case CXCursor_CUDAGlobalAttr:
4147 return cxstring::createRef("attribute(global)");
4148 case CXCursor_CUDAHostAttr:
4149 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004150 case CXCursor_CUDASharedAttr:
4151 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004169 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004173 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004175 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004177 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004179 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004181 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004183 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004185 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004187 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004189 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004191 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004193 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004197 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004199 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004200 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004201 return cxstring::createRef("OMPParallelDirective");
4202 case CXCursor_OMPSimdDirective:
4203 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004204 case CXCursor_OMPForDirective:
4205 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004206 case CXCursor_OMPForSimdDirective:
4207 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004208 case CXCursor_OMPSectionsDirective:
4209 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004210 case CXCursor_OMPSectionDirective:
4211 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004212 case CXCursor_OMPSingleDirective:
4213 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004214 case CXCursor_OMPMasterDirective:
4215 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004216 case CXCursor_OMPCriticalDirective:
4217 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004218 case CXCursor_OMPParallelForDirective:
4219 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004220 case CXCursor_OMPParallelForSimdDirective:
4221 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004222 case CXCursor_OMPParallelSectionsDirective:
4223 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004224 case CXCursor_OMPTaskDirective:
4225 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004226 case CXCursor_OMPTaskyieldDirective:
4227 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004228 case CXCursor_OMPBarrierDirective:
4229 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004230 case CXCursor_OMPTaskwaitDirective:
4231 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004232 case CXCursor_OMPFlushDirective:
4233 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004234 case CXCursor_OMPOrderedDirective:
4235 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004236 case CXCursor_OMPAtomicDirective:
4237 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004238 case CXCursor_OMPTargetDirective:
4239 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004240 case CXCursor_OMPTeamsDirective:
4241 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004242 case CXCursor_OverloadCandidate:
4243 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 }
4245
4246 llvm_unreachable("Unhandled CXCursorKind");
4247}
4248
4249struct GetCursorData {
4250 SourceLocation TokenBeginLoc;
4251 bool PointsAtMacroArgExpansion;
4252 bool VisitedObjCPropertyImplDecl;
4253 SourceLocation VisitedDeclaratorDeclStartLoc;
4254 CXCursor &BestCursor;
4255
4256 GetCursorData(SourceManager &SM,
4257 SourceLocation tokenBegin, CXCursor &outputCursor)
4258 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4259 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4260 VisitedObjCPropertyImplDecl = false;
4261 }
4262};
4263
4264static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4265 CXCursor parent,
4266 CXClientData client_data) {
4267 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4268 CXCursor *BestCursor = &Data->BestCursor;
4269
4270 // If we point inside a macro argument we should provide info of what the
4271 // token is so use the actual cursor, don't replace it with a macro expansion
4272 // cursor.
4273 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4274 return CXChildVisit_Recurse;
4275
4276 if (clang_isDeclaration(cursor.kind)) {
4277 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004278 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4280 if (MD->isImplicit())
4281 return CXChildVisit_Break;
4282
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004283 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4285 // Check that when we have multiple @class references in the same line,
4286 // that later ones do not override the previous ones.
4287 // If we have:
4288 // @class Foo, Bar;
4289 // source ranges for both start at '@', so 'Bar' will end up overriding
4290 // 'Foo' even though the cursor location was at 'Foo'.
4291 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4292 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004293 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4295 if (PrevID != ID &&
4296 !PrevID->isThisDeclarationADefinition() &&
4297 !ID->isThisDeclarationADefinition())
4298 return CXChildVisit_Break;
4299 }
4300
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004301 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4303 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4304 // Check that when we have multiple declarators in the same line,
4305 // that later ones do not override the previous ones.
4306 // If we have:
4307 // int Foo, Bar;
4308 // source ranges for both start at 'int', so 'Bar' will end up overriding
4309 // 'Foo' even though the cursor location was at 'Foo'.
4310 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4311 return CXChildVisit_Break;
4312 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4313
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004314 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4316 (void)PropImp;
4317 // Check that when we have multiple @synthesize in the same line,
4318 // that later ones do not override the previous ones.
4319 // If we have:
4320 // @synthesize Foo, Bar;
4321 // source ranges for both start at '@', so 'Bar' will end up overriding
4322 // 'Foo' even though the cursor location was at 'Foo'.
4323 if (Data->VisitedObjCPropertyImplDecl)
4324 return CXChildVisit_Break;
4325 Data->VisitedObjCPropertyImplDecl = true;
4326 }
4327 }
4328
4329 if (clang_isExpression(cursor.kind) &&
4330 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004331 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 // Avoid having the cursor of an expression replace the declaration cursor
4333 // when the expression source range overlaps the declaration range.
4334 // This can happen for C++ constructor expressions whose range generally
4335 // include the variable declaration, e.g.:
4336 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4337 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4338 D->getLocation() == Data->TokenBeginLoc)
4339 return CXChildVisit_Break;
4340 }
4341 }
4342
4343 // If our current best cursor is the construction of a temporary object,
4344 // don't replace that cursor with a type reference, because we want
4345 // clang_getCursor() to point at the constructor.
4346 if (clang_isExpression(BestCursor->kind) &&
4347 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4348 cursor.kind == CXCursor_TypeRef) {
4349 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4350 // as having the actual point on the type reference.
4351 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4352 return CXChildVisit_Recurse;
4353 }
4354
4355 *BestCursor = cursor;
4356 return CXChildVisit_Recurse;
4357}
4358
4359CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004360 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004361 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004363 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004364
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004365 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004366 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4367
4368 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4369 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4370
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004371 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004372 CXFile SearchFile;
4373 unsigned SearchLine, SearchColumn;
4374 CXFile ResultFile;
4375 unsigned ResultLine, ResultColumn;
4376 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4377 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4378 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004379
4380 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4381 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004382 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004383 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 SearchFileName = clang_getFileName(SearchFile);
4385 ResultFileName = clang_getFileName(ResultFile);
4386 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4387 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004388 *Log << llvm::format("(%s:%d:%d) = %s",
4389 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4390 clang_getCString(KindSpelling))
4391 << llvm::format("(%s:%d:%d):%s%s",
4392 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4393 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 clang_disposeString(SearchFileName);
4395 clang_disposeString(ResultFileName);
4396 clang_disposeString(KindSpelling);
4397 clang_disposeString(USR);
4398
4399 CXCursor Definition = clang_getCursorDefinition(Result);
4400 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4401 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4402 CXString DefinitionKindSpelling
4403 = clang_getCursorKindSpelling(Definition.kind);
4404 CXFile DefinitionFile;
4405 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004406 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004407 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004409 *Log << llvm::format(" -> %s(%s:%d:%d)",
4410 clang_getCString(DefinitionKindSpelling),
4411 clang_getCString(DefinitionFileName),
4412 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 clang_disposeString(DefinitionFileName);
4414 clang_disposeString(DefinitionKindSpelling);
4415 }
4416 }
4417
4418 return Result;
4419}
4420
4421CXCursor clang_getNullCursor(void) {
4422 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4423}
4424
4425unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004426 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4427 // can't set consistently. For example, when visiting a DeclStmt we will set
4428 // it but we don't set it on the result of clang_getCursorDefinition for
4429 // a reference of the same declaration.
4430 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4431 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4432 // to provide that kind of info.
4433 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004434 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004435 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004436 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004437
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 return X == Y;
4439}
4440
4441unsigned clang_hashCursor(CXCursor C) {
4442 unsigned Index = 0;
4443 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4444 Index = 1;
4445
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004446 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004447 std::make_pair(C.kind, C.data[Index]));
4448}
4449
4450unsigned clang_isInvalid(enum CXCursorKind K) {
4451 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4452}
4453
4454unsigned clang_isDeclaration(enum CXCursorKind K) {
4455 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4456 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4457}
4458
4459unsigned clang_isReference(enum CXCursorKind K) {
4460 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4461}
4462
4463unsigned clang_isExpression(enum CXCursorKind K) {
4464 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4465}
4466
4467unsigned clang_isStatement(enum CXCursorKind K) {
4468 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4469}
4470
4471unsigned clang_isAttribute(enum CXCursorKind K) {
4472 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4473}
4474
4475unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4476 return K == CXCursor_TranslationUnit;
4477}
4478
4479unsigned clang_isPreprocessing(enum CXCursorKind K) {
4480 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4481}
4482
4483unsigned clang_isUnexposed(enum CXCursorKind K) {
4484 switch (K) {
4485 case CXCursor_UnexposedDecl:
4486 case CXCursor_UnexposedExpr:
4487 case CXCursor_UnexposedStmt:
4488 case CXCursor_UnexposedAttr:
4489 return true;
4490 default:
4491 return false;
4492 }
4493}
4494
4495CXCursorKind clang_getCursorKind(CXCursor C) {
4496 return C.kind;
4497}
4498
4499CXSourceLocation clang_getCursorLocation(CXCursor C) {
4500 if (clang_isReference(C.kind)) {
4501 switch (C.kind) {
4502 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004503 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 = getCursorObjCSuperClassRef(C);
4505 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4506 }
4507
4508 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004509 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 = getCursorObjCProtocolRef(C);
4511 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4512 }
4513
4514 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004515 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 = getCursorObjCClassRef(C);
4517 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4518 }
4519
4520 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004521 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4523 }
4524
4525 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004526 std::pair<const TemplateDecl *, SourceLocation> P =
4527 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4529 }
4530
4531 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004532 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4534 }
4535
4536 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004537 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4539 }
4540
4541 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004542 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4544 }
4545
4546 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004547 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 if (!BaseSpec)
4549 return clang_getNullLocation();
4550
4551 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4552 return cxloc::translateSourceLocation(getCursorContext(C),
4553 TSInfo->getTypeLoc().getBeginLoc());
4554
4555 return cxloc::translateSourceLocation(getCursorContext(C),
4556 BaseSpec->getLocStart());
4557 }
4558
4559 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004560 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4562 }
4563
4564 case CXCursor_OverloadedDeclRef:
4565 return cxloc::translateSourceLocation(getCursorContext(C),
4566 getCursorOverloadedDeclRef(C).second);
4567
4568 default:
4569 // FIXME: Need a way to enumerate all non-reference cases.
4570 llvm_unreachable("Missed a reference kind");
4571 }
4572 }
4573
4574 if (clang_isExpression(C.kind))
4575 return cxloc::translateSourceLocation(getCursorContext(C),
4576 getLocationFromExpr(getCursorExpr(C)));
4577
4578 if (clang_isStatement(C.kind))
4579 return cxloc::translateSourceLocation(getCursorContext(C),
4580 getCursorStmt(C)->getLocStart());
4581
4582 if (C.kind == CXCursor_PreprocessingDirective) {
4583 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4584 return cxloc::translateSourceLocation(getCursorContext(C), L);
4585 }
4586
4587 if (C.kind == CXCursor_MacroExpansion) {
4588 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004589 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 return cxloc::translateSourceLocation(getCursorContext(C), L);
4591 }
4592
4593 if (C.kind == CXCursor_MacroDefinition) {
4594 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4595 return cxloc::translateSourceLocation(getCursorContext(C), L);
4596 }
4597
4598 if (C.kind == CXCursor_InclusionDirective) {
4599 SourceLocation L
4600 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4601 return cxloc::translateSourceLocation(getCursorContext(C), L);
4602 }
4603
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004604 if (clang_isAttribute(C.kind)) {
4605 SourceLocation L
4606 = cxcursor::getCursorAttr(C)->getLocation();
4607 return cxloc::translateSourceLocation(getCursorContext(C), L);
4608 }
4609
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 if (!clang_isDeclaration(C.kind))
4611 return clang_getNullLocation();
4612
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004613 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 if (!D)
4615 return clang_getNullLocation();
4616
4617 SourceLocation Loc = D->getLocation();
4618 // FIXME: Multiple variables declared in a single declaration
4619 // currently lack the information needed to correctly determine their
4620 // ranges when accounting for the type-specifier. We use context
4621 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4622 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004623 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 if (!cxcursor::isFirstInDeclGroup(C))
4625 Loc = VD->getLocation();
4626 }
4627
4628 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004629 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 Loc = MD->getSelectorStartLoc();
4631
4632 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4633}
4634
4635} // end extern "C"
4636
4637CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4638 assert(TU);
4639
4640 // Guard against an invalid SourceLocation, or we may assert in one
4641 // of the following calls.
4642 if (SLoc.isInvalid())
4643 return clang_getNullCursor();
4644
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004645 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004646
4647 // Translate the given source location to make it point at the beginning of
4648 // the token under the cursor.
4649 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4650 CXXUnit->getASTContext().getLangOpts());
4651
4652 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4653 if (SLoc.isValid()) {
4654 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4655 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4656 /*VisitPreprocessorLast=*/true,
4657 /*VisitIncludedEntities=*/false,
4658 SourceLocation(SLoc));
4659 CursorVis.visitFileRegion();
4660 }
4661
4662 return Result;
4663}
4664
4665static SourceRange getRawCursorExtent(CXCursor C) {
4666 if (clang_isReference(C.kind)) {
4667 switch (C.kind) {
4668 case CXCursor_ObjCSuperClassRef:
4669 return getCursorObjCSuperClassRef(C).second;
4670
4671 case CXCursor_ObjCProtocolRef:
4672 return getCursorObjCProtocolRef(C).second;
4673
4674 case CXCursor_ObjCClassRef:
4675 return getCursorObjCClassRef(C).second;
4676
4677 case CXCursor_TypeRef:
4678 return getCursorTypeRef(C).second;
4679
4680 case CXCursor_TemplateRef:
4681 return getCursorTemplateRef(C).second;
4682
4683 case CXCursor_NamespaceRef:
4684 return getCursorNamespaceRef(C).second;
4685
4686 case CXCursor_MemberRef:
4687 return getCursorMemberRef(C).second;
4688
4689 case CXCursor_CXXBaseSpecifier:
4690 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4691
4692 case CXCursor_LabelRef:
4693 return getCursorLabelRef(C).second;
4694
4695 case CXCursor_OverloadedDeclRef:
4696 return getCursorOverloadedDeclRef(C).second;
4697
4698 case CXCursor_VariableRef:
4699 return getCursorVariableRef(C).second;
4700
4701 default:
4702 // FIXME: Need a way to enumerate all non-reference cases.
4703 llvm_unreachable("Missed a reference kind");
4704 }
4705 }
4706
4707 if (clang_isExpression(C.kind))
4708 return getCursorExpr(C)->getSourceRange();
4709
4710 if (clang_isStatement(C.kind))
4711 return getCursorStmt(C)->getSourceRange();
4712
4713 if (clang_isAttribute(C.kind))
4714 return getCursorAttr(C)->getRange();
4715
4716 if (C.kind == CXCursor_PreprocessingDirective)
4717 return cxcursor::getCursorPreprocessingDirective(C);
4718
4719 if (C.kind == CXCursor_MacroExpansion) {
4720 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004721 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 return TU->mapRangeFromPreamble(Range);
4723 }
4724
4725 if (C.kind == CXCursor_MacroDefinition) {
4726 ASTUnit *TU = getCursorASTUnit(C);
4727 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4728 return TU->mapRangeFromPreamble(Range);
4729 }
4730
4731 if (C.kind == CXCursor_InclusionDirective) {
4732 ASTUnit *TU = getCursorASTUnit(C);
4733 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4734 return TU->mapRangeFromPreamble(Range);
4735 }
4736
4737 if (C.kind == CXCursor_TranslationUnit) {
4738 ASTUnit *TU = getCursorASTUnit(C);
4739 FileID MainID = TU->getSourceManager().getMainFileID();
4740 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4741 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4742 return SourceRange(Start, End);
4743 }
4744
4745 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004746 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 if (!D)
4748 return SourceRange();
4749
4750 SourceRange R = D->getSourceRange();
4751 // FIXME: Multiple variables declared in a single declaration
4752 // currently lack the information needed to correctly determine their
4753 // ranges when accounting for the type-specifier. We use context
4754 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4755 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004756 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 if (!cxcursor::isFirstInDeclGroup(C))
4758 R.setBegin(VD->getLocation());
4759 }
4760 return R;
4761 }
4762 return SourceRange();
4763}
4764
4765/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4766/// the decl-specifier-seq for declarations.
4767static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4768 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004769 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 if (!D)
4771 return SourceRange();
4772
4773 SourceRange R = D->getSourceRange();
4774
4775 // Adjust the start of the location for declarations preceded by
4776 // declaration specifiers.
4777 SourceLocation StartLoc;
4778 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4779 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4780 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004781 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004782 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4783 StartLoc = TI->getTypeLoc().getLocStart();
4784 }
4785
4786 if (StartLoc.isValid() && R.getBegin().isValid() &&
4787 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4788 R.setBegin(StartLoc);
4789
4790 // FIXME: Multiple variables declared in a single declaration
4791 // currently lack the information needed to correctly determine their
4792 // ranges when accounting for the type-specifier. We use context
4793 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4794 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004795 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004796 if (!cxcursor::isFirstInDeclGroup(C))
4797 R.setBegin(VD->getLocation());
4798 }
4799
4800 return R;
4801 }
4802
4803 return getRawCursorExtent(C);
4804}
4805
4806extern "C" {
4807
4808CXSourceRange clang_getCursorExtent(CXCursor C) {
4809 SourceRange R = getRawCursorExtent(C);
4810 if (R.isInvalid())
4811 return clang_getNullRange();
4812
4813 return cxloc::translateSourceRange(getCursorContext(C), R);
4814}
4815
4816CXCursor clang_getCursorReferenced(CXCursor C) {
4817 if (clang_isInvalid(C.kind))
4818 return clang_getNullCursor();
4819
4820 CXTranslationUnit tu = getCursorTU(C);
4821 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004822 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 if (!D)
4824 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004825 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004826 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004827 if (const ObjCPropertyImplDecl *PropImpl =
4828 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004829 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4830 return MakeCXCursor(Property, tu);
4831
4832 return C;
4833 }
4834
4835 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004836 const Expr *E = getCursorExpr(C);
4837 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 if (D) {
4839 CXCursor declCursor = MakeCXCursor(D, tu);
4840 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4841 declCursor);
4842 return declCursor;
4843 }
4844
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004845 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004846 return MakeCursorOverloadedDeclRef(Ovl, tu);
4847
4848 return clang_getNullCursor();
4849 }
4850
4851 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004852 const Stmt *S = getCursorStmt(C);
4853 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004854 if (LabelDecl *label = Goto->getLabel())
4855 if (LabelStmt *labelS = label->getStmt())
4856 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4857
4858 return clang_getNullCursor();
4859 }
4860
4861 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004862 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004863 return MakeMacroDefinitionCursor(Def, tu);
4864 }
4865
4866 if (!clang_isReference(C.kind))
4867 return clang_getNullCursor();
4868
4869 switch (C.kind) {
4870 case CXCursor_ObjCSuperClassRef:
4871 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4872
4873 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004874 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4875 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 return MakeCXCursor(Def, tu);
4877
4878 return MakeCXCursor(Prot, tu);
4879 }
4880
4881 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004882 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4883 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 return MakeCXCursor(Def, tu);
4885
4886 return MakeCXCursor(Class, tu);
4887 }
4888
4889 case CXCursor_TypeRef:
4890 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4891
4892 case CXCursor_TemplateRef:
4893 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4894
4895 case CXCursor_NamespaceRef:
4896 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4897
4898 case CXCursor_MemberRef:
4899 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4900
4901 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004902 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004903 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4904 tu ));
4905 }
4906
4907 case CXCursor_LabelRef:
4908 // FIXME: We end up faking the "parent" declaration here because we
4909 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004910 return MakeCXCursor(getCursorLabelRef(C).first,
4911 cxtu::getASTUnit(tu)->getASTContext()
4912 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 tu);
4914
4915 case CXCursor_OverloadedDeclRef:
4916 return C;
4917
4918 case CXCursor_VariableRef:
4919 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4920
4921 default:
4922 // We would prefer to enumerate all non-reference cursor kinds here.
4923 llvm_unreachable("Unhandled reference cursor kind");
4924 }
4925}
4926
4927CXCursor clang_getCursorDefinition(CXCursor C) {
4928 if (clang_isInvalid(C.kind))
4929 return clang_getNullCursor();
4930
4931 CXTranslationUnit TU = getCursorTU(C);
4932
4933 bool WasReference = false;
4934 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4935 C = clang_getCursorReferenced(C);
4936 WasReference = true;
4937 }
4938
4939 if (C.kind == CXCursor_MacroExpansion)
4940 return clang_getCursorReferenced(C);
4941
4942 if (!clang_isDeclaration(C.kind))
4943 return clang_getNullCursor();
4944
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004945 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004946 if (!D)
4947 return clang_getNullCursor();
4948
4949 switch (D->getKind()) {
4950 // Declaration kinds that don't really separate the notions of
4951 // declaration and definition.
4952 case Decl::Namespace:
4953 case Decl::Typedef:
4954 case Decl::TypeAlias:
4955 case Decl::TypeAliasTemplate:
4956 case Decl::TemplateTypeParm:
4957 case Decl::EnumConstant:
4958 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004959 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004960 case Decl::IndirectField:
4961 case Decl::ObjCIvar:
4962 case Decl::ObjCAtDefsField:
4963 case Decl::ImplicitParam:
4964 case Decl::ParmVar:
4965 case Decl::NonTypeTemplateParm:
4966 case Decl::TemplateTemplateParm:
4967 case Decl::ObjCCategoryImpl:
4968 case Decl::ObjCImplementation:
4969 case Decl::AccessSpec:
4970 case Decl::LinkageSpec:
4971 case Decl::ObjCPropertyImpl:
4972 case Decl::FileScopeAsm:
4973 case Decl::StaticAssert:
4974 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004975 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004976 case Decl::Label: // FIXME: Is this right??
4977 case Decl::ClassScopeFunctionSpecialization:
4978 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004979 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004980 return C;
4981
4982 // Declaration kinds that don't make any sense here, but are
4983 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004984 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00004986 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00004987 break;
4988
4989 // Declaration kinds for which the definition is not resolvable.
4990 case Decl::UnresolvedUsingTypename:
4991 case Decl::UnresolvedUsingValue:
4992 break;
4993
4994 case Decl::UsingDirective:
4995 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4996 TU);
4997
4998 case Decl::NamespaceAlias:
4999 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5000
5001 case Decl::Enum:
5002 case Decl::Record:
5003 case Decl::CXXRecord:
5004 case Decl::ClassTemplateSpecialization:
5005 case Decl::ClassTemplatePartialSpecialization:
5006 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5007 return MakeCXCursor(Def, TU);
5008 return clang_getNullCursor();
5009
5010 case Decl::Function:
5011 case Decl::CXXMethod:
5012 case Decl::CXXConstructor:
5013 case Decl::CXXDestructor:
5014 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005015 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005016 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005017 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 return clang_getNullCursor();
5019 }
5020
Larisse Voufo39a1e502013-08-06 01:03:05 +00005021 case Decl::Var:
5022 case Decl::VarTemplateSpecialization:
5023 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005024 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005025 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005026 return MakeCXCursor(Def, TU);
5027 return clang_getNullCursor();
5028 }
5029
5030 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005031 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005032 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5033 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5034 return clang_getNullCursor();
5035 }
5036
5037 case Decl::ClassTemplate: {
5038 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5039 ->getDefinition())
5040 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5041 TU);
5042 return clang_getNullCursor();
5043 }
5044
Larisse Voufo39a1e502013-08-06 01:03:05 +00005045 case Decl::VarTemplate: {
5046 if (VarDecl *Def =
5047 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5048 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5049 return clang_getNullCursor();
5050 }
5051
Guy Benyei11169dd2012-12-18 14:30:41 +00005052 case Decl::Using:
5053 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5054 D->getLocation(), TU);
5055
5056 case Decl::UsingShadow:
5057 return clang_getCursorDefinition(
5058 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5059 TU));
5060
5061 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005062 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005063 if (Method->isThisDeclarationADefinition())
5064 return C;
5065
5066 // Dig out the method definition in the associated
5067 // @implementation, if we have it.
5068 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005069 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005070 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5071 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5072 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5073 Method->isInstanceMethod()))
5074 if (Def->isThisDeclarationADefinition())
5075 return MakeCXCursor(Def, TU);
5076
5077 return clang_getNullCursor();
5078 }
5079
5080 case Decl::ObjCCategory:
5081 if (ObjCCategoryImplDecl *Impl
5082 = cast<ObjCCategoryDecl>(D)->getImplementation())
5083 return MakeCXCursor(Impl, TU);
5084 return clang_getNullCursor();
5085
5086 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005087 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005088 return MakeCXCursor(Def, TU);
5089 return clang_getNullCursor();
5090
5091 case Decl::ObjCInterface: {
5092 // There are two notions of a "definition" for an Objective-C
5093 // class: the interface and its implementation. When we resolved a
5094 // reference to an Objective-C class, produce the @interface as
5095 // the definition; when we were provided with the interface,
5096 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005097 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005098 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005099 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 return MakeCXCursor(Def, TU);
5101 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5102 return MakeCXCursor(Impl, TU);
5103 return clang_getNullCursor();
5104 }
5105
5106 case Decl::ObjCProperty:
5107 // FIXME: We don't really know where to find the
5108 // ObjCPropertyImplDecls that implement this property.
5109 return clang_getNullCursor();
5110
5111 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005112 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005113 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005114 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005115 return MakeCXCursor(Def, TU);
5116
5117 return clang_getNullCursor();
5118
5119 case Decl::Friend:
5120 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5121 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5122 return clang_getNullCursor();
5123
5124 case Decl::FriendTemplate:
5125 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5126 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5127 return clang_getNullCursor();
5128 }
5129
5130 return clang_getNullCursor();
5131}
5132
5133unsigned clang_isCursorDefinition(CXCursor C) {
5134 if (!clang_isDeclaration(C.kind))
5135 return 0;
5136
5137 return clang_getCursorDefinition(C) == C;
5138}
5139
5140CXCursor clang_getCanonicalCursor(CXCursor C) {
5141 if (!clang_isDeclaration(C.kind))
5142 return C;
5143
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005144 if (const Decl *D = getCursorDecl(C)) {
5145 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5147 return MakeCXCursor(CatD, getCursorTU(C));
5148
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005149 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5150 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005151 return MakeCXCursor(IFD, getCursorTU(C));
5152
5153 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5154 }
5155
5156 return C;
5157}
5158
5159int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5160 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5161}
5162
5163unsigned clang_getNumOverloadedDecls(CXCursor C) {
5164 if (C.kind != CXCursor_OverloadedDeclRef)
5165 return 0;
5166
5167 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005168 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005169 return E->getNumDecls();
5170
5171 if (OverloadedTemplateStorage *S
5172 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5173 return S->size();
5174
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005175 const Decl *D = Storage.get<const Decl *>();
5176 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 return Using->shadow_size();
5178
5179 return 0;
5180}
5181
5182CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5183 if (cursor.kind != CXCursor_OverloadedDeclRef)
5184 return clang_getNullCursor();
5185
5186 if (index >= clang_getNumOverloadedDecls(cursor))
5187 return clang_getNullCursor();
5188
5189 CXTranslationUnit TU = getCursorTU(cursor);
5190 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005191 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 return MakeCXCursor(E->decls_begin()[index], TU);
5193
5194 if (OverloadedTemplateStorage *S
5195 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5196 return MakeCXCursor(S->begin()[index], TU);
5197
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005198 const Decl *D = Storage.get<const Decl *>();
5199 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 // FIXME: This is, unfortunately, linear time.
5201 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5202 std::advance(Pos, index);
5203 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5204 }
5205
5206 return clang_getNullCursor();
5207}
5208
5209void clang_getDefinitionSpellingAndExtent(CXCursor C,
5210 const char **startBuf,
5211 const char **endBuf,
5212 unsigned *startLine,
5213 unsigned *startColumn,
5214 unsigned *endLine,
5215 unsigned *endColumn) {
5216 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005217 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5219
5220 SourceManager &SM = FD->getASTContext().getSourceManager();
5221 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5222 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5223 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5224 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5225 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5226 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5227}
5228
5229
5230CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5231 unsigned PieceIndex) {
5232 RefNamePieces Pieces;
5233
5234 switch (C.kind) {
5235 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005236 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005237 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5238 E->getQualifierLoc().getSourceRange());
5239 break;
5240
5241 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005242 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005243 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5244 E->getQualifierLoc().getSourceRange(),
5245 E->getOptionalExplicitTemplateArgs());
5246 break;
5247
5248 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005249 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005251 const Expr *Callee = OCE->getCallee();
5252 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005253 Callee = ICE->getSubExpr();
5254
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005255 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5257 DRE->getQualifierLoc().getSourceRange());
5258 }
5259 break;
5260
5261 default:
5262 break;
5263 }
5264
5265 if (Pieces.empty()) {
5266 if (PieceIndex == 0)
5267 return clang_getCursorExtent(C);
5268 } else if (PieceIndex < Pieces.size()) {
5269 SourceRange R = Pieces[PieceIndex];
5270 if (R.isValid())
5271 return cxloc::translateSourceRange(getCursorContext(C), R);
5272 }
5273
5274 return clang_getNullRange();
5275}
5276
5277void clang_enableStackTraces(void) {
5278 llvm::sys::PrintStackTraceOnErrorSignal();
5279}
5280
5281void clang_executeOnThread(void (*fn)(void*), void *user_data,
5282 unsigned stack_size) {
5283 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5284}
5285
5286} // end: extern "C"
5287
5288//===----------------------------------------------------------------------===//
5289// Token-based Operations.
5290//===----------------------------------------------------------------------===//
5291
5292/* CXToken layout:
5293 * int_data[0]: a CXTokenKind
5294 * int_data[1]: starting token location
5295 * int_data[2]: token length
5296 * int_data[3]: reserved
5297 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5298 * otherwise unused.
5299 */
5300extern "C" {
5301
5302CXTokenKind clang_getTokenKind(CXToken CXTok) {
5303 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5304}
5305
5306CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5307 switch (clang_getTokenKind(CXTok)) {
5308 case CXToken_Identifier:
5309 case CXToken_Keyword:
5310 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005311 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 ->getNameStart());
5313
5314 case CXToken_Literal: {
5315 // We have stashed the starting pointer in the ptr_data field. Use it.
5316 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005317 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 }
5319
5320 case CXToken_Punctuation:
5321 case CXToken_Comment:
5322 break;
5323 }
5324
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005325 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005326 LOG_BAD_TU(TU);
5327 return cxstring::createEmpty();
5328 }
5329
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 // We have to find the starting buffer pointer the hard way, by
5331 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005332 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005334 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005335
5336 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5337 std::pair<FileID, unsigned> LocInfo
5338 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5339 bool Invalid = false;
5340 StringRef Buffer
5341 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5342 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005343 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005344
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005345 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005346}
5347
5348CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005349 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005350 LOG_BAD_TU(TU);
5351 return clang_getNullLocation();
5352 }
5353
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005354 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005355 if (!CXXUnit)
5356 return clang_getNullLocation();
5357
5358 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5359 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5360}
5361
5362CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005363 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005364 LOG_BAD_TU(TU);
5365 return clang_getNullRange();
5366 }
5367
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005368 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005369 if (!CXXUnit)
5370 return clang_getNullRange();
5371
5372 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5373 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5374}
5375
5376static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5377 SmallVectorImpl<CXToken> &CXTokens) {
5378 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5379 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005380 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005381 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005382 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005383
5384 // Cannot tokenize across files.
5385 if (BeginLocInfo.first != EndLocInfo.first)
5386 return;
5387
5388 // Create a lexer
5389 bool Invalid = false;
5390 StringRef Buffer
5391 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5392 if (Invalid)
5393 return;
5394
5395 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5396 CXXUnit->getASTContext().getLangOpts(),
5397 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5398 Lex.SetCommentRetentionState(true);
5399
5400 // Lex tokens until we hit the end of the range.
5401 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5402 Token Tok;
5403 bool previousWasAt = false;
5404 do {
5405 // Lex the next token
5406 Lex.LexFromRawLexer(Tok);
5407 if (Tok.is(tok::eof))
5408 break;
5409
5410 // Initialize the CXToken.
5411 CXToken CXTok;
5412
5413 // - Common fields
5414 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5415 CXTok.int_data[2] = Tok.getLength();
5416 CXTok.int_data[3] = 0;
5417
5418 // - Kind-specific fields
5419 if (Tok.isLiteral()) {
5420 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005421 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 } else if (Tok.is(tok::raw_identifier)) {
5423 // Lookup the identifier to determine whether we have a keyword.
5424 IdentifierInfo *II
5425 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5426
5427 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5428 CXTok.int_data[0] = CXToken_Keyword;
5429 }
5430 else {
5431 CXTok.int_data[0] = Tok.is(tok::identifier)
5432 ? CXToken_Identifier
5433 : CXToken_Keyword;
5434 }
5435 CXTok.ptr_data = II;
5436 } else if (Tok.is(tok::comment)) {
5437 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005438 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 } else {
5440 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005441 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 }
5443 CXTokens.push_back(CXTok);
5444 previousWasAt = Tok.is(tok::at);
5445 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5446}
5447
5448void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5449 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005450 LOG_FUNC_SECTION {
5451 *Log << TU << ' ' << Range;
5452 }
5453
Guy Benyei11169dd2012-12-18 14:30:41 +00005454 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005455 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 if (NumTokens)
5457 *NumTokens = 0;
5458
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005459 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005460 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005461 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005462 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005463
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005464 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 if (!CXXUnit || !Tokens || !NumTokens)
5466 return;
5467
5468 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5469
5470 SourceRange R = cxloc::translateCXSourceRange(Range);
5471 if (R.isInvalid())
5472 return;
5473
5474 SmallVector<CXToken, 32> CXTokens;
5475 getTokens(CXXUnit, R, CXTokens);
5476
5477 if (CXTokens.empty())
5478 return;
5479
5480 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5481 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5482 *NumTokens = CXTokens.size();
5483}
5484
5485void clang_disposeTokens(CXTranslationUnit TU,
5486 CXToken *Tokens, unsigned NumTokens) {
5487 free(Tokens);
5488}
5489
5490} // end: extern "C"
5491
5492//===----------------------------------------------------------------------===//
5493// Token annotation APIs.
5494//===----------------------------------------------------------------------===//
5495
Guy Benyei11169dd2012-12-18 14:30:41 +00005496static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5497 CXCursor parent,
5498 CXClientData client_data);
5499static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5500 CXClientData client_data);
5501
5502namespace {
5503class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005504 CXToken *Tokens;
5505 CXCursor *Cursors;
5506 unsigned NumTokens;
5507 unsigned TokIdx;
5508 unsigned PreprocessingTokIdx;
5509 CursorVisitor AnnotateVis;
5510 SourceManager &SrcMgr;
5511 bool HasContextSensitiveKeywords;
5512
5513 struct PostChildrenInfo {
5514 CXCursor Cursor;
5515 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005516 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 unsigned BeforeChildrenTokenIdx;
5518 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005519 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005520
5521 CXToken &getTok(unsigned Idx) {
5522 assert(Idx < NumTokens);
5523 return Tokens[Idx];
5524 }
5525 const CXToken &getTok(unsigned Idx) const {
5526 assert(Idx < NumTokens);
5527 return Tokens[Idx];
5528 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005529 bool MoreTokens() const { return TokIdx < NumTokens; }
5530 unsigned NextToken() const { return TokIdx; }
5531 void AdvanceToken() { ++TokIdx; }
5532 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005533 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005534 }
5535 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005536 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005537 }
5538 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005539 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005540 }
5541
5542 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005543 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005544 SourceRange);
5545
5546public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005547 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005548 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005549 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005550 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005551 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005552 AnnotateTokensVisitor, this,
5553 /*VisitPreprocessorLast=*/true,
5554 /*VisitIncludedEntities=*/false,
5555 RegionOfInterest,
5556 /*VisitDeclsOnly=*/false,
5557 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005558 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005559 HasContextSensitiveKeywords(false) { }
5560
5561 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5562 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5563 bool postVisitChildren(CXCursor cursor);
5564 void AnnotateTokens();
5565
5566 /// \brief Determine whether the annotator saw any cursors that have
5567 /// context-sensitive keywords.
5568 bool hasContextSensitiveKeywords() const {
5569 return HasContextSensitiveKeywords;
5570 }
5571
5572 ~AnnotateTokensWorker() {
5573 assert(PostChildrenInfos.empty());
5574 }
5575};
5576}
5577
5578void AnnotateTokensWorker::AnnotateTokens() {
5579 // Walk the AST within the region of interest, annotating tokens
5580 // along the way.
5581 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005582}
Guy Benyei11169dd2012-12-18 14:30:41 +00005583
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005584static inline void updateCursorAnnotation(CXCursor &Cursor,
5585 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005586 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005587 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005588 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005589}
5590
5591/// \brief It annotates and advances tokens with a cursor until the comparison
5592//// between the cursor location and the source range is the same as
5593/// \arg compResult.
5594///
5595/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5596/// Pass RangeOverlap to annotate tokens inside a range.
5597void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5598 RangeComparisonResult compResult,
5599 SourceRange range) {
5600 while (MoreTokens()) {
5601 const unsigned I = NextToken();
5602 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005603 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5604 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005605
5606 SourceLocation TokLoc = GetTokenLoc(I);
5607 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005608 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005609 AdvanceToken();
5610 continue;
5611 }
5612 break;
5613 }
5614}
5615
5616/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005617/// \returns true if it advanced beyond all macro tokens, false otherwise.
5618bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005619 CXCursor updateC,
5620 RangeComparisonResult compResult,
5621 SourceRange range) {
5622 assert(MoreTokens());
5623 assert(isFunctionMacroToken(NextToken()) &&
5624 "Should be called only for macro arg tokens");
5625
5626 // This works differently than annotateAndAdvanceTokens; because expanded
5627 // macro arguments can have arbitrary translation-unit source order, we do not
5628 // advance the token index one by one until a token fails the range test.
5629 // We only advance once past all of the macro arg tokens if all of them
5630 // pass the range test. If one of them fails we keep the token index pointing
5631 // at the start of the macro arg tokens so that the failing token will be
5632 // annotated by a subsequent annotation try.
5633
5634 bool atLeastOneCompFail = false;
5635
5636 unsigned I = NextToken();
5637 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5638 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5639 if (TokLoc.isFileID())
5640 continue; // not macro arg token, it's parens or comma.
5641 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5642 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5643 Cursors[I] = updateC;
5644 } else
5645 atLeastOneCompFail = true;
5646 }
5647
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005648 if (atLeastOneCompFail)
5649 return false;
5650
5651 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5652 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005653}
5654
5655enum CXChildVisitResult
5656AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 SourceRange cursorRange = getRawCursorExtent(cursor);
5658 if (cursorRange.isInvalid())
5659 return CXChildVisit_Recurse;
5660
5661 if (!HasContextSensitiveKeywords) {
5662 // Objective-C properties can have context-sensitive keywords.
5663 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005664 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005665 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5666 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5667 }
5668 // Objective-C methods can have context-sensitive keywords.
5669 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5670 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005671 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005672 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5673 if (Method->getObjCDeclQualifier())
5674 HasContextSensitiveKeywords = true;
5675 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005676 for (const auto *P : Method->params()) {
5677 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005678 HasContextSensitiveKeywords = true;
5679 break;
5680 }
5681 }
5682 }
5683 }
5684 }
5685 // C++ methods can have context-sensitive keywords.
5686 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005687 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5689 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5690 HasContextSensitiveKeywords = true;
5691 }
5692 }
5693 // C++ classes can have context-sensitive keywords.
5694 else if (cursor.kind == CXCursor_StructDecl ||
5695 cursor.kind == CXCursor_ClassDecl ||
5696 cursor.kind == CXCursor_ClassTemplate ||
5697 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005698 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 if (D->hasAttr<FinalAttr>())
5700 HasContextSensitiveKeywords = true;
5701 }
5702 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005703
5704 // Don't override a property annotation with its getter/setter method.
5705 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5706 parent.kind == CXCursor_ObjCPropertyDecl)
5707 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005708
5709 if (clang_isPreprocessing(cursor.kind)) {
5710 // Items in the preprocessing record are kept separate from items in
5711 // declarations, so we keep a separate token index.
5712 unsigned SavedTokIdx = TokIdx;
5713 TokIdx = PreprocessingTokIdx;
5714
5715 // Skip tokens up until we catch up to the beginning of the preprocessing
5716 // entry.
5717 while (MoreTokens()) {
5718 const unsigned I = NextToken();
5719 SourceLocation TokLoc = GetTokenLoc(I);
5720 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5721 case RangeBefore:
5722 AdvanceToken();
5723 continue;
5724 case RangeAfter:
5725 case RangeOverlap:
5726 break;
5727 }
5728 break;
5729 }
5730
5731 // Look at all of the tokens within this range.
5732 while (MoreTokens()) {
5733 const unsigned I = NextToken();
5734 SourceLocation TokLoc = GetTokenLoc(I);
5735 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5736 case RangeBefore:
5737 llvm_unreachable("Infeasible");
5738 case RangeAfter:
5739 break;
5740 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005741 // For macro expansions, just note where the beginning of the macro
5742 // expansion occurs.
5743 if (cursor.kind == CXCursor_MacroExpansion) {
5744 if (TokLoc == cursorRange.getBegin())
5745 Cursors[I] = cursor;
5746 AdvanceToken();
5747 break;
5748 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005749 // We may have already annotated macro names inside macro definitions.
5750 if (Cursors[I].kind != CXCursor_MacroExpansion)
5751 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005753 continue;
5754 }
5755 break;
5756 }
5757
5758 // Save the preprocessing token index; restore the non-preprocessing
5759 // token index.
5760 PreprocessingTokIdx = TokIdx;
5761 TokIdx = SavedTokIdx;
5762 return CXChildVisit_Recurse;
5763 }
5764
5765 if (cursorRange.isInvalid())
5766 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005767
5768 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005769 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 const enum CXCursorKind K = clang_getCursorKind(parent);
5771 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005772 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5773 // Attributes are annotated out-of-order, skip tokens until we reach it.
5774 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005775 ? clang_getNullCursor() : parent;
5776
5777 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5778
5779 // Avoid having the cursor of an expression "overwrite" the annotation of the
5780 // variable declaration that it belongs to.
5781 // This can happen for C++ constructor expressions whose range generally
5782 // include the variable declaration, e.g.:
5783 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005784 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005785 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005786 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005787 const unsigned I = NextToken();
5788 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5789 E->getLocStart() == D->getLocation() &&
5790 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005791 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005792 AdvanceToken();
5793 }
5794 }
5795 }
5796
5797 // Before recursing into the children keep some state that we are going
5798 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5799 // extra work after the child nodes are visited.
5800 // Note that we don't call VisitChildren here to avoid traversing statements
5801 // code-recursively which can blow the stack.
5802
5803 PostChildrenInfo Info;
5804 Info.Cursor = cursor;
5805 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005806 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005807 Info.BeforeChildrenTokenIdx = NextToken();
5808 PostChildrenInfos.push_back(Info);
5809
5810 return CXChildVisit_Recurse;
5811}
5812
5813bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5814 if (PostChildrenInfos.empty())
5815 return false;
5816 const PostChildrenInfo &Info = PostChildrenInfos.back();
5817 if (!clang_equalCursors(Info.Cursor, cursor))
5818 return false;
5819
5820 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5821 const unsigned AfterChildren = NextToken();
5822 SourceRange cursorRange = Info.CursorRange;
5823
5824 // Scan the tokens that are at the end of the cursor, but are not captured
5825 // but the child cursors.
5826 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5827
5828 // Scan the tokens that are at the beginning of the cursor, but are not
5829 // capture by the child cursors.
5830 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5831 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5832 break;
5833
5834 Cursors[I] = cursor;
5835 }
5836
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005837 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5838 // encountered the attribute cursor.
5839 if (clang_isAttribute(cursor.kind))
5840 TokIdx = Info.BeforeReachingCursorIdx;
5841
Guy Benyei11169dd2012-12-18 14:30:41 +00005842 PostChildrenInfos.pop_back();
5843 return false;
5844}
5845
5846static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5847 CXCursor parent,
5848 CXClientData client_data) {
5849 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5850}
5851
5852static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5853 CXClientData client_data) {
5854 return static_cast<AnnotateTokensWorker*>(client_data)->
5855 postVisitChildren(cursor);
5856}
5857
5858namespace {
5859
5860/// \brief Uses the macro expansions in the preprocessing record to find
5861/// and mark tokens that are macro arguments. This info is used by the
5862/// AnnotateTokensWorker.
5863class MarkMacroArgTokensVisitor {
5864 SourceManager &SM;
5865 CXToken *Tokens;
5866 unsigned NumTokens;
5867 unsigned CurIdx;
5868
5869public:
5870 MarkMacroArgTokensVisitor(SourceManager &SM,
5871 CXToken *tokens, unsigned numTokens)
5872 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5873
5874 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5875 if (cursor.kind != CXCursor_MacroExpansion)
5876 return CXChildVisit_Continue;
5877
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005878 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005879 if (macroRange.getBegin() == macroRange.getEnd())
5880 return CXChildVisit_Continue; // it's not a function macro.
5881
5882 for (; CurIdx < NumTokens; ++CurIdx) {
5883 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5884 macroRange.getBegin()))
5885 break;
5886 }
5887
5888 if (CurIdx == NumTokens)
5889 return CXChildVisit_Break;
5890
5891 for (; CurIdx < NumTokens; ++CurIdx) {
5892 SourceLocation tokLoc = getTokenLoc(CurIdx);
5893 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5894 break;
5895
5896 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5897 }
5898
5899 if (CurIdx == NumTokens)
5900 return CXChildVisit_Break;
5901
5902 return CXChildVisit_Continue;
5903 }
5904
5905private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005906 CXToken &getTok(unsigned Idx) {
5907 assert(Idx < NumTokens);
5908 return Tokens[Idx];
5909 }
5910 const CXToken &getTok(unsigned Idx) const {
5911 assert(Idx < NumTokens);
5912 return Tokens[Idx];
5913 }
5914
Guy Benyei11169dd2012-12-18 14:30:41 +00005915 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005916 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005917 }
5918
5919 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5920 // The third field is reserved and currently not used. Use it here
5921 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005922 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005923 }
5924};
5925
5926} // end anonymous namespace
5927
5928static CXChildVisitResult
5929MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5930 CXClientData client_data) {
5931 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5932 parent);
5933}
5934
5935namespace {
5936 struct clang_annotateTokens_Data {
5937 CXTranslationUnit TU;
5938 ASTUnit *CXXUnit;
5939 CXToken *Tokens;
5940 unsigned NumTokens;
5941 CXCursor *Cursors;
5942 };
5943}
5944
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005945/// \brief Used by \c annotatePreprocessorTokens.
5946/// \returns true if lexing was finished, false otherwise.
5947static bool lexNext(Lexer &Lex, Token &Tok,
5948 unsigned &NextIdx, unsigned NumTokens) {
5949 if (NextIdx >= NumTokens)
5950 return true;
5951
5952 ++NextIdx;
5953 Lex.LexFromRawLexer(Tok);
5954 if (Tok.is(tok::eof))
5955 return true;
5956
5957 return false;
5958}
5959
Guy Benyei11169dd2012-12-18 14:30:41 +00005960static void annotatePreprocessorTokens(CXTranslationUnit TU,
5961 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005962 CXCursor *Cursors,
5963 CXToken *Tokens,
5964 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005965 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005966
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005967 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005968 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5969 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005970 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005971 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005972 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005973
5974 if (BeginLocInfo.first != EndLocInfo.first)
5975 return;
5976
5977 StringRef Buffer;
5978 bool Invalid = false;
5979 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5980 if (Buffer.empty() || Invalid)
5981 return;
5982
5983 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5984 CXXUnit->getASTContext().getLangOpts(),
5985 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5986 Buffer.end());
5987 Lex.SetCommentRetentionState(true);
5988
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005989 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005990 // Lex tokens in raw mode until we hit the end of the range, to avoid
5991 // entering #includes or expanding macros.
5992 while (true) {
5993 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005994 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5995 break;
5996 unsigned TokIdx = NextIdx-1;
5997 assert(Tok.getLocation() ==
5998 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005999
6000 reprocess:
6001 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006002 // We have found a preprocessing directive. Annotate the tokens
6003 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006004 //
6005 // FIXME: Some simple tests here could identify macro definitions and
6006 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006007
6008 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006009 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6010 break;
6011
Craig Topper69186e72014-06-08 08:38:04 +00006012 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006013 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006014 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6015 break;
6016
6017 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006018 IdentifierInfo &II =
6019 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006020 SourceLocation MappedTokLoc =
6021 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6022 MI = getMacroInfo(II, MappedTokLoc, TU);
6023 }
6024 }
6025
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006026 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006027 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006028 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6029 finished = true;
6030 break;
6031 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006032 // If we are in a macro definition, check if the token was ever a
6033 // macro name and annotate it if that's the case.
6034 if (MI) {
6035 SourceLocation SaveLoc = Tok.getLocation();
6036 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6037 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
6038 Tok.setLocation(SaveLoc);
6039 if (MacroDef)
6040 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6041 Tok.getLocation(), TU);
6042 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006043 } while (!Tok.isAtStartOfLine());
6044
6045 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6046 assert(TokIdx <= LastIdx);
6047 SourceLocation EndLoc =
6048 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6049 CXCursor Cursor =
6050 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6051
6052 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006053 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006054
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006055 if (finished)
6056 break;
6057 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006058 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006059 }
6060}
6061
6062// This gets run a separate thread to avoid stack blowout.
6063static void clang_annotateTokensImpl(void *UserData) {
6064 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6065 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6066 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6067 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6068 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6069
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006070 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006071 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6072 setThreadBackgroundPriority();
6073
6074 // Determine the region of interest, which contains all of the tokens.
6075 SourceRange RegionOfInterest;
6076 RegionOfInterest.setBegin(
6077 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6078 RegionOfInterest.setEnd(
6079 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6080 Tokens[NumTokens-1])));
6081
Guy Benyei11169dd2012-12-18 14:30:41 +00006082 // Relex the tokens within the source range to look for preprocessing
6083 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006084 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006085
6086 // If begin location points inside a macro argument, set it to the expansion
6087 // location so we can have the full context when annotating semantically.
6088 {
6089 SourceManager &SM = CXXUnit->getSourceManager();
6090 SourceLocation Loc =
6091 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6092 if (Loc.isMacroID())
6093 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6094 }
6095
Guy Benyei11169dd2012-12-18 14:30:41 +00006096 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6097 // Search and mark tokens that are macro argument expansions.
6098 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6099 Tokens, NumTokens);
6100 CursorVisitor MacroArgMarker(TU,
6101 MarkMacroArgTokensVisitorDelegate, &Visitor,
6102 /*VisitPreprocessorLast=*/true,
6103 /*VisitIncludedEntities=*/false,
6104 RegionOfInterest);
6105 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6106 }
6107
6108 // Annotate all of the source locations in the region of interest that map to
6109 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006110 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006111
6112 // FIXME: We use a ridiculous stack size here because the data-recursion
6113 // algorithm uses a large stack frame than the non-data recursive version,
6114 // and AnnotationTokensWorker currently transforms the data-recursion
6115 // algorithm back into a traditional recursion by explicitly calling
6116 // VisitChildren(). We will need to remove this explicit recursive call.
6117 W.AnnotateTokens();
6118
6119 // If we ran into any entities that involve context-sensitive keywords,
6120 // take another pass through the tokens to mark them as such.
6121 if (W.hasContextSensitiveKeywords()) {
6122 for (unsigned I = 0; I != NumTokens; ++I) {
6123 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6124 continue;
6125
6126 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6127 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006128 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006129 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6130 if (Property->getPropertyAttributesAsWritten() != 0 &&
6131 llvm::StringSwitch<bool>(II->getName())
6132 .Case("readonly", true)
6133 .Case("assign", true)
6134 .Case("unsafe_unretained", true)
6135 .Case("readwrite", true)
6136 .Case("retain", true)
6137 .Case("copy", true)
6138 .Case("nonatomic", true)
6139 .Case("atomic", true)
6140 .Case("getter", true)
6141 .Case("setter", true)
6142 .Case("strong", true)
6143 .Case("weak", true)
6144 .Default(false))
6145 Tokens[I].int_data[0] = CXToken_Keyword;
6146 }
6147 continue;
6148 }
6149
6150 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6151 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6152 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6153 if (llvm::StringSwitch<bool>(II->getName())
6154 .Case("in", true)
6155 .Case("out", true)
6156 .Case("inout", true)
6157 .Case("oneway", true)
6158 .Case("bycopy", true)
6159 .Case("byref", true)
6160 .Default(false))
6161 Tokens[I].int_data[0] = CXToken_Keyword;
6162 continue;
6163 }
6164
6165 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6166 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6167 Tokens[I].int_data[0] = CXToken_Keyword;
6168 continue;
6169 }
6170 }
6171 }
6172}
6173
6174extern "C" {
6175
6176void clang_annotateTokens(CXTranslationUnit TU,
6177 CXToken *Tokens, unsigned NumTokens,
6178 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006179 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006180 LOG_BAD_TU(TU);
6181 return;
6182 }
6183 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006184 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006185 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006186 }
6187
6188 LOG_FUNC_SECTION {
6189 *Log << TU << ' ';
6190 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6191 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6192 *Log << clang_getRange(bloc, eloc);
6193 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006194
6195 // Any token we don't specifically annotate will have a NULL cursor.
6196 CXCursor C = clang_getNullCursor();
6197 for (unsigned I = 0; I != NumTokens; ++I)
6198 Cursors[I] = C;
6199
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006200 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006201 if (!CXXUnit)
6202 return;
6203
6204 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6205
6206 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6207 llvm::CrashRecoveryContext CRC;
6208 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6209 GetSafetyThreadStackSize() * 2)) {
6210 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6211 }
6212}
6213
6214} // end: extern "C"
6215
6216//===----------------------------------------------------------------------===//
6217// Operations for querying linkage of a cursor.
6218//===----------------------------------------------------------------------===//
6219
6220extern "C" {
6221CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6222 if (!clang_isDeclaration(cursor.kind))
6223 return CXLinkage_Invalid;
6224
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006225 const Decl *D = cxcursor::getCursorDecl(cursor);
6226 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006227 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006228 case NoLinkage:
6229 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006230 case InternalLinkage: return CXLinkage_Internal;
6231 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6232 case ExternalLinkage: return CXLinkage_External;
6233 };
6234
6235 return CXLinkage_Invalid;
6236}
6237} // end: extern "C"
6238
6239//===----------------------------------------------------------------------===//
6240// Operations for querying language of a cursor.
6241//===----------------------------------------------------------------------===//
6242
6243static CXLanguageKind getDeclLanguage(const Decl *D) {
6244 if (!D)
6245 return CXLanguage_C;
6246
6247 switch (D->getKind()) {
6248 default:
6249 break;
6250 case Decl::ImplicitParam:
6251 case Decl::ObjCAtDefsField:
6252 case Decl::ObjCCategory:
6253 case Decl::ObjCCategoryImpl:
6254 case Decl::ObjCCompatibleAlias:
6255 case Decl::ObjCImplementation:
6256 case Decl::ObjCInterface:
6257 case Decl::ObjCIvar:
6258 case Decl::ObjCMethod:
6259 case Decl::ObjCProperty:
6260 case Decl::ObjCPropertyImpl:
6261 case Decl::ObjCProtocol:
6262 return CXLanguage_ObjC;
6263 case Decl::CXXConstructor:
6264 case Decl::CXXConversion:
6265 case Decl::CXXDestructor:
6266 case Decl::CXXMethod:
6267 case Decl::CXXRecord:
6268 case Decl::ClassTemplate:
6269 case Decl::ClassTemplatePartialSpecialization:
6270 case Decl::ClassTemplateSpecialization:
6271 case Decl::Friend:
6272 case Decl::FriendTemplate:
6273 case Decl::FunctionTemplate:
6274 case Decl::LinkageSpec:
6275 case Decl::Namespace:
6276 case Decl::NamespaceAlias:
6277 case Decl::NonTypeTemplateParm:
6278 case Decl::StaticAssert:
6279 case Decl::TemplateTemplateParm:
6280 case Decl::TemplateTypeParm:
6281 case Decl::UnresolvedUsingTypename:
6282 case Decl::UnresolvedUsingValue:
6283 case Decl::Using:
6284 case Decl::UsingDirective:
6285 case Decl::UsingShadow:
6286 return CXLanguage_CPlusPlus;
6287 }
6288
6289 return CXLanguage_C;
6290}
6291
6292extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006293
6294static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6295 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6296 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006297
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006298 switch (D->getAvailability()) {
6299 case AR_Available:
6300 case AR_NotYetIntroduced:
6301 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006302 return getCursorAvailabilityForDecl(
6303 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006304 return CXAvailability_Available;
6305
6306 case AR_Deprecated:
6307 return CXAvailability_Deprecated;
6308
6309 case AR_Unavailable:
6310 return CXAvailability_NotAvailable;
6311 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006312
6313 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006314}
6315
Guy Benyei11169dd2012-12-18 14:30:41 +00006316enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6317 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006318 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6319 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006320
6321 return CXAvailability_Available;
6322}
6323
6324static CXVersion convertVersion(VersionTuple In) {
6325 CXVersion Out = { -1, -1, -1 };
6326 if (In.empty())
6327 return Out;
6328
6329 Out.Major = In.getMajor();
6330
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006331 Optional<unsigned> Minor = In.getMinor();
6332 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006333 Out.Minor = *Minor;
6334 else
6335 return Out;
6336
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006337 Optional<unsigned> Subminor = In.getSubminor();
6338 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006339 Out.Subminor = *Subminor;
6340
6341 return Out;
6342}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006343
6344static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6345 int *always_deprecated,
6346 CXString *deprecated_message,
6347 int *always_unavailable,
6348 CXString *unavailable_message,
6349 CXPlatformAvailability *availability,
6350 int availability_size) {
6351 bool HadAvailAttr = false;
6352 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006353 for (auto A : D->attrs()) {
6354 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006355 HadAvailAttr = true;
6356 if (always_deprecated)
6357 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006358 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006359 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006360 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006361 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006362 continue;
6363 }
6364
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006365 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006366 HadAvailAttr = true;
6367 if (always_unavailable)
6368 *always_unavailable = 1;
6369 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006370 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006371 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6372 }
6373 continue;
6374 }
6375
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006376 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006377 HadAvailAttr = true;
6378 if (N < availability_size) {
6379 availability[N].Platform
6380 = cxstring::createDup(Avail->getPlatform()->getName());
6381 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6382 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6383 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6384 availability[N].Unavailable = Avail->getUnavailable();
6385 availability[N].Message = cxstring::createDup(Avail->getMessage());
6386 }
6387 ++N;
6388 }
6389 }
6390
6391 if (!HadAvailAttr)
6392 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6393 return getCursorPlatformAvailabilityForDecl(
6394 cast<Decl>(EnumConst->getDeclContext()),
6395 always_deprecated,
6396 deprecated_message,
6397 always_unavailable,
6398 unavailable_message,
6399 availability,
6400 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006401
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006402 return N;
6403}
6404
Guy Benyei11169dd2012-12-18 14:30:41 +00006405int clang_getCursorPlatformAvailability(CXCursor cursor,
6406 int *always_deprecated,
6407 CXString *deprecated_message,
6408 int *always_unavailable,
6409 CXString *unavailable_message,
6410 CXPlatformAvailability *availability,
6411 int availability_size) {
6412 if (always_deprecated)
6413 *always_deprecated = 0;
6414 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006415 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006416 if (always_unavailable)
6417 *always_unavailable = 0;
6418 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006419 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006420
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 if (!clang_isDeclaration(cursor.kind))
6422 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006423
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006424 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006425 if (!D)
6426 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006427
6428 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6429 deprecated_message,
6430 always_unavailable,
6431 unavailable_message,
6432 availability,
6433 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006434}
6435
6436void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6437 clang_disposeString(availability->Platform);
6438 clang_disposeString(availability->Message);
6439}
6440
6441CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6442 if (clang_isDeclaration(cursor.kind))
6443 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6444
6445 return CXLanguage_Invalid;
6446}
6447
6448 /// \brief If the given cursor is the "templated" declaration
6449 /// descibing a class or function template, return the class or
6450 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006451static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006452 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006453 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006454
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006455 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006456 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6457 return FunTmpl;
6458
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006459 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006460 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6461 return ClassTmpl;
6462
6463 return D;
6464}
6465
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006466
6467enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6468 StorageClass sc = SC_None;
6469 const Decl *D = getCursorDecl(C);
6470 if (D) {
6471 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6472 sc = FD->getStorageClass();
6473 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6474 sc = VD->getStorageClass();
6475 } else {
6476 return CX_SC_Invalid;
6477 }
6478 } else {
6479 return CX_SC_Invalid;
6480 }
6481 switch (sc) {
6482 case SC_None:
6483 return CX_SC_None;
6484 case SC_Extern:
6485 return CX_SC_Extern;
6486 case SC_Static:
6487 return CX_SC_Static;
6488 case SC_PrivateExtern:
6489 return CX_SC_PrivateExtern;
6490 case SC_OpenCLWorkGroupLocal:
6491 return CX_SC_OpenCLWorkGroupLocal;
6492 case SC_Auto:
6493 return CX_SC_Auto;
6494 case SC_Register:
6495 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006496 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006497 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006498}
6499
Guy Benyei11169dd2012-12-18 14:30:41 +00006500CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6501 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006502 if (const Decl *D = getCursorDecl(cursor)) {
6503 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006504 if (!DC)
6505 return clang_getNullCursor();
6506
6507 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6508 getCursorTU(cursor));
6509 }
6510 }
6511
6512 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006513 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006514 return MakeCXCursor(D, getCursorTU(cursor));
6515 }
6516
6517 return clang_getNullCursor();
6518}
6519
6520CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6521 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006522 if (const Decl *D = getCursorDecl(cursor)) {
6523 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006524 if (!DC)
6525 return clang_getNullCursor();
6526
6527 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6528 getCursorTU(cursor));
6529 }
6530 }
6531
6532 // FIXME: Note that we can't easily compute the lexical context of a
6533 // statement or expression, so we return nothing.
6534 return clang_getNullCursor();
6535}
6536
6537CXFile clang_getIncludedFile(CXCursor cursor) {
6538 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006539 return nullptr;
6540
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006541 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006542 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006543}
6544
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006545unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6546 if (C.kind != CXCursor_ObjCPropertyDecl)
6547 return CXObjCPropertyAttr_noattr;
6548
6549 unsigned Result = CXObjCPropertyAttr_noattr;
6550 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6551 ObjCPropertyDecl::PropertyAttributeKind Attr =
6552 PD->getPropertyAttributesAsWritten();
6553
6554#define SET_CXOBJCPROP_ATTR(A) \
6555 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6556 Result |= CXObjCPropertyAttr_##A
6557 SET_CXOBJCPROP_ATTR(readonly);
6558 SET_CXOBJCPROP_ATTR(getter);
6559 SET_CXOBJCPROP_ATTR(assign);
6560 SET_CXOBJCPROP_ATTR(readwrite);
6561 SET_CXOBJCPROP_ATTR(retain);
6562 SET_CXOBJCPROP_ATTR(copy);
6563 SET_CXOBJCPROP_ATTR(nonatomic);
6564 SET_CXOBJCPROP_ATTR(setter);
6565 SET_CXOBJCPROP_ATTR(atomic);
6566 SET_CXOBJCPROP_ATTR(weak);
6567 SET_CXOBJCPROP_ATTR(strong);
6568 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6569#undef SET_CXOBJCPROP_ATTR
6570
6571 return Result;
6572}
6573
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006574unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6575 if (!clang_isDeclaration(C.kind))
6576 return CXObjCDeclQualifier_None;
6577
6578 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6579 const Decl *D = getCursorDecl(C);
6580 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6581 QT = MD->getObjCDeclQualifier();
6582 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6583 QT = PD->getObjCDeclQualifier();
6584 if (QT == Decl::OBJC_TQ_None)
6585 return CXObjCDeclQualifier_None;
6586
6587 unsigned Result = CXObjCDeclQualifier_None;
6588 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6589 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6590 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6591 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6592 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6593 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6594
6595 return Result;
6596}
6597
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006598unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6599 if (!clang_isDeclaration(C.kind))
6600 return 0;
6601
6602 const Decl *D = getCursorDecl(C);
6603 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6604 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6605 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6606 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6607
6608 return 0;
6609}
6610
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006611unsigned clang_Cursor_isVariadic(CXCursor C) {
6612 if (!clang_isDeclaration(C.kind))
6613 return 0;
6614
6615 const Decl *D = getCursorDecl(C);
6616 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6617 return FD->isVariadic();
6618 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6619 return MD->isVariadic();
6620
6621 return 0;
6622}
6623
Guy Benyei11169dd2012-12-18 14:30:41 +00006624CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6625 if (!clang_isDeclaration(C.kind))
6626 return clang_getNullRange();
6627
6628 const Decl *D = getCursorDecl(C);
6629 ASTContext &Context = getCursorContext(C);
6630 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6631 if (!RC)
6632 return clang_getNullRange();
6633
6634 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6635}
6636
6637CXString clang_Cursor_getRawCommentText(CXCursor C) {
6638 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006639 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006640
6641 const Decl *D = getCursorDecl(C);
6642 ASTContext &Context = getCursorContext(C);
6643 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6644 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6645 StringRef();
6646
6647 // Don't duplicate the string because RawText points directly into source
6648 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006649 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006650}
6651
6652CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6653 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006654 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006655
6656 const Decl *D = getCursorDecl(C);
6657 const ASTContext &Context = getCursorContext(C);
6658 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6659
6660 if (RC) {
6661 StringRef BriefText = RC->getBriefText(Context);
6662
6663 // Don't duplicate the string because RawComment ensures that this memory
6664 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006665 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006666 }
6667
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006668 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006669}
6670
Guy Benyei11169dd2012-12-18 14:30:41 +00006671CXModule clang_Cursor_getModule(CXCursor C) {
6672 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006673 if (const ImportDecl *ImportD =
6674 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006675 return ImportD->getImportedModule();
6676 }
6677
Craig Topper69186e72014-06-08 08:38:04 +00006678 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006679}
6680
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006681CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6682 if (isNotUsableTU(TU)) {
6683 LOG_BAD_TU(TU);
6684 return nullptr;
6685 }
6686 if (!File)
6687 return nullptr;
6688 FileEntry *FE = static_cast<FileEntry *>(File);
6689
6690 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6691 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6692 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6693
Richard Smithfeb54b62014-10-23 02:01:19 +00006694 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006695}
6696
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006697CXFile clang_Module_getASTFile(CXModule CXMod) {
6698 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006699 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006700 Module *Mod = static_cast<Module*>(CXMod);
6701 return const_cast<FileEntry *>(Mod->getASTFile());
6702}
6703
Guy Benyei11169dd2012-12-18 14:30:41 +00006704CXModule clang_Module_getParent(CXModule CXMod) {
6705 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006706 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006707 Module *Mod = static_cast<Module*>(CXMod);
6708 return Mod->Parent;
6709}
6710
6711CXString clang_Module_getName(CXModule CXMod) {
6712 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006713 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006714 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006715 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006716}
6717
6718CXString clang_Module_getFullName(CXModule CXMod) {
6719 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006720 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006721 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006722 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006723}
6724
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006725int clang_Module_isSystem(CXModule CXMod) {
6726 if (!CXMod)
6727 return 0;
6728 Module *Mod = static_cast<Module*>(CXMod);
6729 return Mod->IsSystem;
6730}
6731
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006732unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6733 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006734 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006735 LOG_BAD_TU(TU);
6736 return 0;
6737 }
6738 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006739 return 0;
6740 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006741 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6742 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6743 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006744}
6745
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006746CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6747 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006748 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006749 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006750 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006751 }
6752 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006753 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006754 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006755 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006756
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006757 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6758 if (Index < TopHeaders.size())
6759 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006760
Craig Topper69186e72014-06-08 08:38:04 +00006761 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006762}
6763
6764} // end: extern "C"
6765
6766//===----------------------------------------------------------------------===//
6767// C++ AST instrospection.
6768//===----------------------------------------------------------------------===//
6769
6770extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006771unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6772 if (!clang_isDeclaration(C.kind))
6773 return 0;
6774
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006775 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006776 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006777 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006778 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6779}
6780
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006781unsigned clang_CXXMethod_isConst(CXCursor C) {
6782 if (!clang_isDeclaration(C.kind))
6783 return 0;
6784
6785 const Decl *D = cxcursor::getCursorDecl(C);
6786 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006787 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006788 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6789}
6790
Guy Benyei11169dd2012-12-18 14:30:41 +00006791unsigned clang_CXXMethod_isStatic(CXCursor C) {
6792 if (!clang_isDeclaration(C.kind))
6793 return 0;
6794
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006795 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006796 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006797 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006798 return (Method && Method->isStatic()) ? 1 : 0;
6799}
6800
6801unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6802 if (!clang_isDeclaration(C.kind))
6803 return 0;
6804
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006805 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006806 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006807 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006808 return (Method && Method->isVirtual()) ? 1 : 0;
6809}
6810} // end: extern "C"
6811
6812//===----------------------------------------------------------------------===//
6813// Attribute introspection.
6814//===----------------------------------------------------------------------===//
6815
6816extern "C" {
6817CXType clang_getIBOutletCollectionType(CXCursor C) {
6818 if (C.kind != CXCursor_IBOutletCollectionAttr)
6819 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6820
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006821 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006822 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6823
6824 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6825}
6826} // end: extern "C"
6827
6828//===----------------------------------------------------------------------===//
6829// Inspecting memory usage.
6830//===----------------------------------------------------------------------===//
6831
6832typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6833
6834static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6835 enum CXTUResourceUsageKind k,
6836 unsigned long amount) {
6837 CXTUResourceUsageEntry entry = { k, amount };
6838 entries.push_back(entry);
6839}
6840
6841extern "C" {
6842
6843const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6844 const char *str = "";
6845 switch (kind) {
6846 case CXTUResourceUsage_AST:
6847 str = "ASTContext: expressions, declarations, and types";
6848 break;
6849 case CXTUResourceUsage_Identifiers:
6850 str = "ASTContext: identifiers";
6851 break;
6852 case CXTUResourceUsage_Selectors:
6853 str = "ASTContext: selectors";
6854 break;
6855 case CXTUResourceUsage_GlobalCompletionResults:
6856 str = "Code completion: cached global results";
6857 break;
6858 case CXTUResourceUsage_SourceManagerContentCache:
6859 str = "SourceManager: content cache allocator";
6860 break;
6861 case CXTUResourceUsage_AST_SideTables:
6862 str = "ASTContext: side tables";
6863 break;
6864 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6865 str = "SourceManager: malloc'ed memory buffers";
6866 break;
6867 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6868 str = "SourceManager: mmap'ed memory buffers";
6869 break;
6870 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6871 str = "ExternalASTSource: malloc'ed memory buffers";
6872 break;
6873 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6874 str = "ExternalASTSource: mmap'ed memory buffers";
6875 break;
6876 case CXTUResourceUsage_Preprocessor:
6877 str = "Preprocessor: malloc'ed memory";
6878 break;
6879 case CXTUResourceUsage_PreprocessingRecord:
6880 str = "Preprocessor: PreprocessingRecord";
6881 break;
6882 case CXTUResourceUsage_SourceManager_DataStructures:
6883 str = "SourceManager: data structures and tables";
6884 break;
6885 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6886 str = "Preprocessor: header search tables";
6887 break;
6888 }
6889 return str;
6890}
6891
6892CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006893 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006894 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006895 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006896 return usage;
6897 }
6898
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006899 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006900 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006901 ASTContext &astContext = astUnit->getASTContext();
6902
6903 // How much memory is used by AST nodes and types?
6904 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6905 (unsigned long) astContext.getASTAllocatedMemory());
6906
6907 // How much memory is used by identifiers?
6908 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6909 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6910
6911 // How much memory is used for selectors?
6912 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6913 (unsigned long) astContext.Selectors.getTotalMemory());
6914
6915 // How much memory is used by ASTContext's side tables?
6916 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6917 (unsigned long) astContext.getSideTableAllocatedMemory());
6918
6919 // How much memory is used for caching global code completion results?
6920 unsigned long completionBytes = 0;
6921 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006922 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006923 completionBytes = completionAllocator->getTotalMemory();
6924 }
6925 createCXTUResourceUsageEntry(*entries,
6926 CXTUResourceUsage_GlobalCompletionResults,
6927 completionBytes);
6928
6929 // How much memory is being used by SourceManager's content cache?
6930 createCXTUResourceUsageEntry(*entries,
6931 CXTUResourceUsage_SourceManagerContentCache,
6932 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6933
6934 // How much memory is being used by the MemoryBuffer's in SourceManager?
6935 const SourceManager::MemoryBufferSizes &srcBufs =
6936 astUnit->getSourceManager().getMemoryBufferSizes();
6937
6938 createCXTUResourceUsageEntry(*entries,
6939 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6940 (unsigned long) srcBufs.malloc_bytes);
6941 createCXTUResourceUsageEntry(*entries,
6942 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6943 (unsigned long) srcBufs.mmap_bytes);
6944 createCXTUResourceUsageEntry(*entries,
6945 CXTUResourceUsage_SourceManager_DataStructures,
6946 (unsigned long) astContext.getSourceManager()
6947 .getDataStructureSizes());
6948
6949 // How much memory is being used by the ExternalASTSource?
6950 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6951 const ExternalASTSource::MemoryBufferSizes &sizes =
6952 esrc->getMemoryBufferSizes();
6953
6954 createCXTUResourceUsageEntry(*entries,
6955 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6956 (unsigned long) sizes.malloc_bytes);
6957 createCXTUResourceUsageEntry(*entries,
6958 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6959 (unsigned long) sizes.mmap_bytes);
6960 }
6961
6962 // How much memory is being used by the Preprocessor?
6963 Preprocessor &pp = astUnit->getPreprocessor();
6964 createCXTUResourceUsageEntry(*entries,
6965 CXTUResourceUsage_Preprocessor,
6966 pp.getTotalMemory());
6967
6968 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6969 createCXTUResourceUsageEntry(*entries,
6970 CXTUResourceUsage_PreprocessingRecord,
6971 pRec->getTotalMemory());
6972 }
6973
6974 createCXTUResourceUsageEntry(*entries,
6975 CXTUResourceUsage_Preprocessor_HeaderSearch,
6976 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006977
Guy Benyei11169dd2012-12-18 14:30:41 +00006978 CXTUResourceUsage usage = { (void*) entries.get(),
6979 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00006980 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006981 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006982 return usage;
6983}
6984
6985void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6986 if (usage.data)
6987 delete (MemUsageEntries*) usage.data;
6988}
6989
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006990CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6991 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006992 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006993 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006994
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006995 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006996 LOG_BAD_TU(TU);
6997 return skipped;
6998 }
6999
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007000 if (!file)
7001 return skipped;
7002
7003 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7004 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7005 if (!ppRec)
7006 return skipped;
7007
7008 ASTContext &Ctx = astUnit->getASTContext();
7009 SourceManager &sm = Ctx.getSourceManager();
7010 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7011 FileID wantedFileID = sm.translateFile(fileEntry);
7012
7013 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7014 std::vector<SourceRange> wantedRanges;
7015 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7016 i != ei; ++i) {
7017 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7018 wantedRanges.push_back(*i);
7019 }
7020
7021 skipped->count = wantedRanges.size();
7022 skipped->ranges = new CXSourceRange[skipped->count];
7023 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7024 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7025
7026 return skipped;
7027}
7028
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007029void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7030 if (ranges) {
7031 delete[] ranges->ranges;
7032 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007033 }
7034}
7035
Guy Benyei11169dd2012-12-18 14:30:41 +00007036} // end extern "C"
7037
7038void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7039 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7040 for (unsigned I = 0; I != Usage.numEntries; ++I)
7041 fprintf(stderr, " %s: %lu\n",
7042 clang_getTUResourceUsageName(Usage.entries[I].kind),
7043 Usage.entries[I].amount);
7044
7045 clang_disposeCXTUResourceUsage(Usage);
7046}
7047
7048//===----------------------------------------------------------------------===//
7049// Misc. utility functions.
7050//===----------------------------------------------------------------------===//
7051
7052/// Default to using an 8 MB stack size on "safety" threads.
7053static unsigned SafetyStackThreadSize = 8 << 20;
7054
7055namespace clang {
7056
7057bool RunSafely(llvm::CrashRecoveryContext &CRC,
7058 void (*Fn)(void*), void *UserData,
7059 unsigned Size) {
7060 if (!Size)
7061 Size = GetSafetyThreadStackSize();
7062 if (Size)
7063 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7064 return CRC.RunSafely(Fn, UserData);
7065}
7066
7067unsigned GetSafetyThreadStackSize() {
7068 return SafetyStackThreadSize;
7069}
7070
7071void SetSafetyThreadStackSize(unsigned Value) {
7072 SafetyStackThreadSize = Value;
7073}
7074
7075}
7076
7077void clang::setThreadBackgroundPriority() {
7078 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7079 return;
7080
Alp Toker1a86ad22014-07-06 06:24:00 +00007081#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007082 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7083#endif
7084}
7085
7086void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7087 if (!Unit)
7088 return;
7089
7090 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7091 DEnd = Unit->stored_diag_end();
7092 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007093 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007094 CXString Msg = clang_formatDiagnostic(&Diag,
7095 clang_defaultDiagnosticDisplayOptions());
7096 fprintf(stderr, "%s\n", clang_getCString(Msg));
7097 clang_disposeString(Msg);
7098 }
7099#ifdef LLVM_ON_WIN32
7100 // On Windows, force a flush, since there may be multiple copies of
7101 // stderr and stdout in the file system, all with different buffers
7102 // but writing to the same device.
7103 fflush(stderr);
7104#endif
7105}
7106
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007107MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7108 SourceLocation MacroDefLoc,
7109 CXTranslationUnit TU){
7110 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007111 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007112 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007113 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007114
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007115 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007116 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007117 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007118 if (MD) {
7119 for (MacroDirective::DefInfo
7120 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7121 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7122 return Def.getMacroInfo();
7123 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007124 }
7125
Craig Topper69186e72014-06-08 08:38:04 +00007126 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007127}
7128
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007129const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7130 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007131 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007132 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007133 const IdentifierInfo *II = MacroDef->getName();
7134 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007135 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007136
7137 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7138}
7139
7140MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7141 const Token &Tok,
7142 CXTranslationUnit TU) {
7143 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007144 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007145 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007146 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007147
7148 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007149 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007150 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7151 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007152 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007153
7154 // Check that the token is inside the definition and not its argument list.
7155 SourceManager &SM = Unit->getSourceManager();
7156 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007157 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007158 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007159 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007160
7161 Preprocessor &PP = Unit->getPreprocessor();
7162 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7163 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007164 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007165
Alp Toker2d57cea2014-05-17 04:53:25 +00007166 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007167 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007168 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007169
7170 // Check that the identifier is not one of the macro arguments.
7171 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007172 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007173
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007174 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7175 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007176 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007177
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007178 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007179}
7180
7181MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7182 SourceLocation Loc,
7183 CXTranslationUnit TU) {
7184 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007185 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007186
7187 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007188 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007189 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007190 Preprocessor &PP = Unit->getPreprocessor();
7191 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007192 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007193 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7194 Token Tok;
7195 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007196 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007197
7198 return checkForMacroInMacroDefinition(MI, Tok, TU);
7199}
7200
Guy Benyei11169dd2012-12-18 14:30:41 +00007201extern "C" {
7202
7203CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007204 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007205}
7206
7207} // end: extern "C"
7208
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007209Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7210 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007211 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007212 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007213 if (Unit->isMainFileAST())
7214 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007215 return *this;
7216 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007217 } else {
7218 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007219 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007220 return *this;
7221}
7222
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007223Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7224 *this << FE->getName();
7225 return *this;
7226}
7227
7228Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7229 CXString cursorName = clang_getCursorDisplayName(cursor);
7230 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7231 clang_disposeString(cursorName);
7232 return *this;
7233}
7234
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007235Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7236 CXFile File;
7237 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007238 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007239 CXString FileName = clang_getFileName(File);
7240 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7241 clang_disposeString(FileName);
7242 return *this;
7243}
7244
7245Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7246 CXSourceLocation BLoc = clang_getRangeStart(range);
7247 CXSourceLocation ELoc = clang_getRangeEnd(range);
7248
7249 CXFile BFile;
7250 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007251 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007252
7253 CXFile EFile;
7254 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007255 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007256
7257 CXString BFileName = clang_getFileName(BFile);
7258 if (BFile == EFile) {
7259 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7260 BLine, BColumn, ELine, EColumn);
7261 } else {
7262 CXString EFileName = clang_getFileName(EFile);
7263 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7264 BLine, BColumn)
7265 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7266 ELine, EColumn);
7267 clang_disposeString(EFileName);
7268 }
7269 clang_disposeString(BFileName);
7270 return *this;
7271}
7272
7273Logger &cxindex::Logger::operator<<(CXString Str) {
7274 *this << clang_getCString(Str);
7275 return *this;
7276}
7277
7278Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7279 LogOS << Fmt;
7280 return *this;
7281}
7282
Chandler Carruth37ad2582014-06-27 15:14:39 +00007283static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7284
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007285cxindex::Logger::~Logger() {
7286 LogOS.flush();
7287
Chandler Carruth37ad2582014-06-27 15:14:39 +00007288 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007289
7290 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7291
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007292 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007293 OS << "[libclang:" << Name << ':';
7294
Alp Toker1a86ad22014-07-06 06:24:00 +00007295#ifdef USE_DARWIN_THREADS
7296 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007297 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7298 OS << tid << ':';
7299#endif
7300
7301 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7302 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007303 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007304
7305 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007306 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007307 OS << "--------------------------------------------------\n";
7308 }
7309}