blob: 8748dde99832a13ee8f354657e25af01a0f7a124 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000243 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
244 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000245 PPRec, FID);
246}
247
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000248bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000249 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000250 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000251
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000252 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000253 SourceManager &SM = Unit->getSourceManager();
254
255 std::pair<FileID, unsigned>
256 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
257 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
258
259 if (End.first != Begin.first) {
260 // If the end does not reside in the same file, try to recover by
261 // picking the end of the file of begin location.
262 End.first = Begin.first;
263 End.second = SM.getFileIDSize(Begin.first);
264 }
265
266 assert(Begin.first == End.first);
267 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000268 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
270 FileID File = Begin.first;
271 unsigned Offset = Begin.second;
272 unsigned Length = End.second - Begin.second;
273
274 if (!VisitDeclsOnly && !VisitPreprocessorLast)
275 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000278 if (visitDeclsFromFileRegion(File, Offset, Length))
279 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000280
281 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000282 return visitPreprocessedEntitiesInRegion();
283
284 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000285}
286
287static bool isInLexicalContext(Decl *D, DeclContext *DC) {
288 if (!DC)
289 return false;
290
291 for (DeclContext *DeclDC = D->getLexicalDeclContext();
292 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
293 if (DeclDC == DC)
294 return true;
295 }
296 return false;
297}
298
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000299bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000300 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000301 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000302 SourceManager &SM = Unit->getSourceManager();
303 SourceRange Range = RegionOfInterest;
304
305 SmallVector<Decl *, 16> Decls;
306 Unit->findFileRegionDecls(File, Offset, Length, Decls);
307
308 // If we didn't find any file level decls for the file, try looking at the
309 // file that it was included from.
310 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
311 bool Invalid = false;
312 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
313 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000314 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315
316 SourceLocation Outer;
317 if (SLEntry.isFile())
318 Outer = SLEntry.getFile().getIncludeLoc();
319 else
320 Outer = SLEntry.getExpansion().getExpansionLocStart();
321 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000322 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000323
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000324 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000325 Length = 0;
326 Unit->findFileRegionDecls(File, Offset, Length, Decls);
327 }
328
329 assert(!Decls.empty());
330
331 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000332 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000333 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
334 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000335 Decl *D = *DIt;
336 if (D->getSourceRange().isInvalid())
337 continue;
338
339 if (isInLexicalContext(D, CurDC))
340 continue;
341
342 CurDC = dyn_cast<DeclContext>(D);
343
344 if (TagDecl *TD = dyn_cast<TagDecl>(D))
345 if (!TD->isFreeStanding())
346 continue;
347
348 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
349 if (CompRes == RangeBefore)
350 continue;
351 if (CompRes == RangeAfter)
352 break;
353
354 assert(CompRes == RangeOverlap);
355 VisitedAtLeastOnce = true;
356
357 if (isa<ObjCContainerDecl>(D)) {
358 FileDI_current = &DIt;
359 FileDE_current = DE;
360 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000361 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000362 }
363
364 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000365 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000366 }
367
368 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000369 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000370
371 // No Decls overlapped with the range. Move up the lexical context until there
372 // is a context that contains the range or we reach the translation unit
373 // level.
374 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
375 : (*(DIt-1))->getLexicalDeclContext();
376
377 while (DC && !DC->isTranslationUnit()) {
378 Decl *D = cast<Decl>(DC);
379 SourceRange CurDeclRange = D->getSourceRange();
380 if (CurDeclRange.isInvalid())
381 break;
382
383 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000384 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
385 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000386 }
387
388 DC = D->getLexicalDeclContext();
389 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000390
391 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000392}
393
394bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
395 if (!AU->getPreprocessor().getPreprocessingRecord())
396 return false;
397
398 PreprocessingRecord &PPRec
399 = *AU->getPreprocessor().getPreprocessingRecord();
400 SourceManager &SM = AU->getSourceManager();
401
402 if (RegionOfInterest.isValid()) {
403 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
404 SourceLocation B = MappedRange.getBegin();
405 SourceLocation E = MappedRange.getEnd();
406
407 if (AU->isInPreambleFileID(B)) {
408 if (SM.isLoadedSourceLocation(E))
409 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
410 PPRec, *this);
411
412 // Beginning of range lies in the preamble but it also extends beyond
413 // it into the main file. Split the range into 2 parts, one covering
414 // the preamble and another covering the main file. This allows subsequent
415 // calls to visitPreprocessedEntitiesInRange to accept a source range that
416 // lies in the same FileID, allowing it to skip preprocessed entities that
417 // do not come from the same FileID.
418 bool breaked =
419 visitPreprocessedEntitiesInRange(
420 SourceRange(B, AU->getEndOfPreambleFileID()),
421 PPRec, *this);
422 if (breaked) return true;
423 return visitPreprocessedEntitiesInRange(
424 SourceRange(AU->getStartOfMainFileID(), E),
425 PPRec, *this);
426 }
427
428 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
429 }
430
431 bool OnlyLocalDecls
432 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
433
434 if (OnlyLocalDecls)
435 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
436 PPRec);
437
438 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
439}
440
441template<typename InputIterator>
442bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
443 InputIterator Last,
444 PreprocessingRecord &PPRec,
445 FileID FID) {
446 for (; First != Last; ++First) {
447 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
448 continue;
449
450 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000451 if (!PPE)
452 continue;
453
Guy Benyei11169dd2012-12-18 14:30:41 +0000454 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
455 if (Visit(MakeMacroExpansionCursor(ME, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
462 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
463 return true;
464
465 continue;
466 }
467
468 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
469 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
470 return true;
471
472 continue;
473 }
474 }
475
476 return false;
477}
478
479/// \brief Visit the children of the given cursor.
480///
481/// \returns true if the visitation should be aborted, false if it
482/// should continue.
483bool CursorVisitor::VisitChildren(CXCursor Cursor) {
484 if (clang_isReference(Cursor.kind) &&
485 Cursor.kind != CXCursor_CXXBaseSpecifier) {
486 // By definition, references have no children.
487 return false;
488 }
489
490 // Set the Parent field to Cursor, then back to its old value once we're
491 // done.
492 SetParentRAII SetParent(Parent, StmtParent, Cursor);
493
494 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000495 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000496 if (!D)
497 return false;
498
499 return VisitAttributes(D) || Visit(D);
500 }
501
502 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(S);
505
506 return false;
507 }
508
509 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000510 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000511 return Visit(E);
512
513 return false;
514 }
515
516 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000517 CXTranslationUnit TU = getCursorTU(Cursor);
518 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000519
520 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
521 for (unsigned I = 0; I != 2; ++I) {
522 if (VisitOrder[I]) {
523 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
524 RegionOfInterest.isInvalid()) {
525 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
526 TLEnd = CXXUnit->top_level_end();
527 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000528 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000529 return true;
530 }
531 } else if (VisitDeclContext(
532 CXXUnit->getASTContext().getTranslationUnitDecl()))
533 return true;
534 continue;
535 }
536
537 // Walk the preprocessing record.
538 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
539 visitPreprocessedEntitiesInRegion();
540 }
541
542 return false;
543 }
544
545 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000546 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
548 return Visit(BaseTSInfo->getTypeLoc());
549 }
550 }
551 }
552
553 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000554 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000555 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000556 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000557 return Visit(cxcursor::MakeCursorObjCClassRef(
558 ObjT->getInterface(),
559 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000560 }
561
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000562 // If pointing inside a macro definition, check if the token is an identifier
563 // that was ever defined as a macro. In such a case, create a "pseudo" macro
564 // expansion cursor for that token.
565 SourceLocation BeginLoc = RegionOfInterest.getBegin();
566 if (Cursor.kind == CXCursor_MacroDefinition &&
567 BeginLoc == RegionOfInterest.getEnd()) {
568 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000569 const MacroInfo *MI =
570 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000571 if (MacroDefinition *MacroDef =
572 checkForMacroInMacroDefinition(MI, Loc, TU))
573 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
574 }
575
Guy Benyei11169dd2012-12-18 14:30:41 +0000576 // Nothing to visit at the moment.
577 return false;
578}
579
580bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
581 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
582 if (Visit(TSInfo->getTypeLoc()))
583 return true;
584
585 if (Stmt *Body = B->getBody())
586 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
587
588 return false;
589}
590
Ted Kremenek03325582013-02-21 01:29:01 +0000591Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000592 if (RegionOfInterest.isValid()) {
593 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
594 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000595 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000596
597 switch (CompareRegionOfInterest(Range)) {
598 case RangeBefore:
599 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000600 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000601
602 case RangeAfter:
603 // This declaration comes after the region of interest; we're done.
604 return false;
605
606 case RangeOverlap:
607 // This declaration overlaps the region of interest; visit it.
608 break;
609 }
610 }
611 return true;
612}
613
614bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
615 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
616
617 // FIXME: Eventually remove. This part of a hack to support proper
618 // iteration over all Decls contained lexically within an ObjC container.
619 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
620 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
621
622 for ( ; I != E; ++I) {
623 Decl *D = *I;
624 if (D->getLexicalDeclContext() != DC)
625 continue;
626 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
627
628 // Ignore synthesized ivars here, otherwise if we have something like:
629 // @synthesize prop = _prop;
630 // and '_prop' is not declared, we will encounter a '_prop' ivar before
631 // encountering the 'prop' synthesize declaration and we will think that
632 // we passed the region-of-interest.
633 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
634 if (ivarD->getSynthesize())
635 continue;
636 }
637
638 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
639 // declarations is a mismatch with the compiler semantics.
640 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
641 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
642 if (!ID->isThisDeclarationADefinition())
643 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
644
645 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
646 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
647 if (!PD->isThisDeclarationADefinition())
648 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
649 }
650
Ted Kremenek03325582013-02-21 01:29:01 +0000651 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000652 if (!V.hasValue())
653 continue;
654 if (!V.getValue())
655 return false;
656 if (Visit(Cursor, true))
657 return true;
658 }
659 return false;
660}
661
662bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
663 llvm_unreachable("Translation units are visited directly by Visit()");
664}
665
666bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
674 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
675 return Visit(TSInfo->getTypeLoc());
676
677 return false;
678}
679
680bool CursorVisitor::VisitTagDecl(TagDecl *D) {
681 return VisitDeclContext(D);
682}
683
684bool CursorVisitor::VisitClassTemplateSpecializationDecl(
685 ClassTemplateSpecializationDecl *D) {
686 bool ShouldVisitBody = false;
687 switch (D->getSpecializationKind()) {
688 case TSK_Undeclared:
689 case TSK_ImplicitInstantiation:
690 // Nothing to visit
691 return false;
692
693 case TSK_ExplicitInstantiationDeclaration:
694 case TSK_ExplicitInstantiationDefinition:
695 break;
696
697 case TSK_ExplicitSpecialization:
698 ShouldVisitBody = true;
699 break;
700 }
701
702 // Visit the template arguments used in the specialization.
703 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
704 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000705 if (TemplateSpecializationTypeLoc TSTLoc =
706 TL.getAs<TemplateSpecializationTypeLoc>()) {
707 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
708 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000709 return true;
710 }
711 }
712
713 if (ShouldVisitBody && VisitCXXRecordDecl(D))
714 return true;
715
716 return false;
717}
718
719bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
720 ClassTemplatePartialSpecializationDecl *D) {
721 // FIXME: Visit the "outer" template parameter lists on the TagDecl
722 // before visiting these template parameters.
723 if (VisitTemplateParameters(D->getTemplateParameters()))
724 return true;
725
726 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000727 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
728 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
729 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000730 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
731 return true;
732
733 return VisitCXXRecordDecl(D);
734}
735
736bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
737 // Visit the default argument.
738 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
739 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
740 if (Visit(DefArg->getTypeLoc()))
741 return true;
742
743 return false;
744}
745
746bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
747 if (Expr *Init = D->getInitExpr())
748 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
749 return false;
750}
751
752bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000753 unsigned NumParamList = DD->getNumTemplateParameterLists();
754 for (unsigned i = 0; i < NumParamList; i++) {
755 TemplateParameterList* Params = DD->getTemplateParameterList(i);
756 if (VisitTemplateParameters(Params))
757 return true;
758 }
759
Guy Benyei11169dd2012-12-18 14:30:41 +0000760 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
761 if (Visit(TSInfo->getTypeLoc()))
762 return true;
763
764 // Visit the nested-name-specifier, if present.
765 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
766 if (VisitNestedNameSpecifierLoc(QualifierLoc))
767 return true;
768
769 return false;
770}
771
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000772/// \brief Compare two base or member initializers based on their source order.
773static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
774 CXXCtorInitializer *const *Y) {
775 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
776}
777
Guy Benyei11169dd2012-12-18 14:30:41 +0000778bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000779 unsigned NumParamList = ND->getNumTemplateParameterLists();
780 for (unsigned i = 0; i < NumParamList; i++) {
781 TemplateParameterList* Params = ND->getTemplateParameterList(i);
782 if (VisitTemplateParameters(Params))
783 return true;
784 }
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
787 // Visit the function declaration's syntactic components in the order
788 // written. This requires a bit of work.
789 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000790 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000791
792 // If we have a function declared directly (without the use of a typedef),
793 // visit just the return type. Otherwise, just visit the function's type
794 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000795 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000796 (!FTL && Visit(TL)))
797 return true;
798
799 // Visit the nested-name-specifier, if present.
800 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
801 if (VisitNestedNameSpecifierLoc(QualifierLoc))
802 return true;
803
804 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000805 if (!isa<CXXDestructorDecl>(ND))
806 if (VisitDeclarationNameInfo(ND->getNameInfo()))
807 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000808
809 // FIXME: Visit explicitly-specified template arguments!
810
811 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000812 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 return true;
814
Bill Wendling44426052012-12-20 19:22:21 +0000815 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000816 }
817
818 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
819 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
820 // Find the initializers that were written in the source.
821 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000822 for (auto *I : Constructor->inits()) {
823 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 continue;
825
Aaron Ballman0ad78302014-03-13 17:34:31 +0000826 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000827 }
828
829 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000830 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
831 &CompareCXXCtorInitializers);
832
Guy Benyei11169dd2012-12-18 14:30:41 +0000833 // Visit the initializers in source order
834 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
835 CXXCtorInitializer *Init = WrittenInits[I];
836 if (Init->isAnyMemberInitializer()) {
837 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
838 Init->getMemberLocation(), TU)))
839 return true;
840 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
841 if (Visit(TInfo->getTypeLoc()))
842 return true;
843 }
844
845 // Visit the initializer value.
846 if (Expr *Initializer = Init->getInit())
847 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
848 return true;
849 }
850 }
851
852 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
853 return true;
854 }
855
856 return false;
857}
858
859bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
860 if (VisitDeclaratorDecl(D))
861 return true;
862
863 if (Expr *BitWidth = D->getBitWidth())
864 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
865
866 return false;
867}
868
869bool CursorVisitor::VisitVarDecl(VarDecl *D) {
870 if (VisitDeclaratorDecl(D))
871 return true;
872
873 if (Expr *Init = D->getInit())
874 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
875
876 return false;
877}
878
879bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
880 if (VisitDeclaratorDecl(D))
881 return true;
882
883 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
884 if (Expr *DefArg = D->getDefaultArgument())
885 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
886
887 return false;
888}
889
890bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
891 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
892 // before visiting these template parameters.
893 if (VisitTemplateParameters(D->getTemplateParameters()))
894 return true;
895
896 return VisitFunctionDecl(D->getTemplatedDecl());
897}
898
899bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
900 // FIXME: Visit the "outer" template parameter lists on the TagDecl
901 // before visiting these template parameters.
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 return VisitCXXRecordDecl(D->getTemplatedDecl());
906}
907
908bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
909 if (VisitTemplateParameters(D->getTemplateParameters()))
910 return true;
911
912 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
913 VisitTemplateArgumentLoc(D->getDefaultArgument()))
914 return true;
915
916 return false;
917}
918
919bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000920 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000921 if (Visit(TSInfo->getTypeLoc()))
922 return true;
923
Aaron Ballman43b68be2014-03-07 17:50:17 +0000924 for (const auto *P : ND->params()) {
925 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000926 return true;
927 }
928
929 if (ND->isThisDeclarationADefinition() &&
930 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
931 return true;
932
933 return false;
934}
935
936template <typename DeclIt>
937static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
938 SourceManager &SM, SourceLocation EndLoc,
939 SmallVectorImpl<Decl *> &Decls) {
940 DeclIt next = *DI_current;
941 while (++next != DE_current) {
942 Decl *D_next = *next;
943 if (!D_next)
944 break;
945 SourceLocation L = D_next->getLocStart();
946 if (!L.isValid())
947 break;
948 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
949 *DI_current = next;
950 Decls.push_back(D_next);
951 continue;
952 }
953 break;
954 }
955}
956
Guy Benyei11169dd2012-12-18 14:30:41 +0000957bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
958 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
959 // an @implementation can lexically contain Decls that are not properly
960 // nested in the AST. When we identify such cases, we need to retrofit
961 // this nesting here.
962 if (!DI_current && !FileDI_current)
963 return VisitDeclContext(D);
964
965 // Scan the Decls that immediately come after the container
966 // in the current DeclContext. If any fall within the
967 // container's lexical region, stash them into a vector
968 // for later processing.
969 SmallVector<Decl *, 24> DeclsInContainer;
970 SourceLocation EndLoc = D->getSourceRange().getEnd();
971 SourceManager &SM = AU->getSourceManager();
972 if (EndLoc.isValid()) {
973 if (DI_current) {
974 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
975 DeclsInContainer);
976 } else {
977 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
978 DeclsInContainer);
979 }
980 }
981
982 // The common case.
983 if (DeclsInContainer.empty())
984 return VisitDeclContext(D);
985
986 // Get all the Decls in the DeclContext, and sort them with the
987 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000988 for (auto *SubDecl : D->decls()) {
989 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
990 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000991 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000992 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000993 }
994
995 // Now sort the Decls so that they appear in lexical order.
996 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000997 [&SM](Decl *A, Decl *B) {
998 SourceLocation L_A = A->getLocStart();
999 SourceLocation L_B = B->getLocStart();
1000 assert(L_A.isValid() && L_B.isValid());
1001 return SM.isBeforeInTranslationUnit(L_A, L_B);
1002 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001003
1004 // Now visit the decls.
1005 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1006 E = DeclsInContainer.end(); I != E; ++I) {
1007 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001008 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001009 if (!V.hasValue())
1010 continue;
1011 if (!V.getValue())
1012 return false;
1013 if (Visit(Cursor, true))
1014 return true;
1015 }
1016 return false;
1017}
1018
1019bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1020 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1021 TU)))
1022 return true;
1023
1024 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1025 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1026 E = ND->protocol_end(); I != E; ++I, ++PL)
1027 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1028 return true;
1029
1030 return VisitObjCContainerDecl(ND);
1031}
1032
1033bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1034 if (!PID->isThisDeclarationADefinition())
1035 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1036
1037 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1038 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1039 E = PID->protocol_end(); I != E; ++I, ++PL)
1040 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1041 return true;
1042
1043 return VisitObjCContainerDecl(PID);
1044}
1045
1046bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1047 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1048 return true;
1049
1050 // FIXME: This implements a workaround with @property declarations also being
1051 // installed in the DeclContext for the @interface. Eventually this code
1052 // should be removed.
1053 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1054 if (!CDecl || !CDecl->IsClassExtension())
1055 return false;
1056
1057 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1058 if (!ID)
1059 return false;
1060
1061 IdentifierInfo *PropertyId = PD->getIdentifier();
1062 ObjCPropertyDecl *prevDecl =
1063 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1064
1065 if (!prevDecl)
1066 return false;
1067
1068 // Visit synthesized methods since they will be skipped when visiting
1069 // the @interface.
1070 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1071 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1072 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1073 return true;
1074
1075 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1076 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1077 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1078 return true;
1079
1080 return false;
1081}
1082
1083bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1084 if (!D->isThisDeclarationADefinition()) {
1085 // Forward declaration is treated like a reference.
1086 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1087 }
1088
1089 // Issue callbacks for super class.
1090 if (D->getSuperClass() &&
1091 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1092 D->getSuperClassLoc(),
1093 TU)))
1094 return true;
1095
1096 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1097 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1098 E = D->protocol_end(); I != E; ++I, ++PL)
1099 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1100 return true;
1101
1102 return VisitObjCContainerDecl(D);
1103}
1104
1105bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1106 return VisitObjCContainerDecl(D);
1107}
1108
1109bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1110 // 'ID' could be null when dealing with invalid code.
1111 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1112 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1113 return true;
1114
1115 return VisitObjCImplDecl(D);
1116}
1117
1118bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1119#if 0
1120 // Issue callbacks for super class.
1121 // FIXME: No source location information!
1122 if (D->getSuperClass() &&
1123 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1124 D->getSuperClassLoc(),
1125 TU)))
1126 return true;
1127#endif
1128
1129 return VisitObjCImplDecl(D);
1130}
1131
1132bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1133 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1134 if (PD->isIvarNameSpecified())
1135 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1136
1137 return false;
1138}
1139
1140bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1141 return VisitDeclContext(D);
1142}
1143
1144bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1145 // Visit nested-name-specifier.
1146 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1147 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1148 return true;
1149
1150 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1151 D->getTargetNameLoc(), TU));
1152}
1153
1154bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1155 // Visit nested-name-specifier.
1156 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1157 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1158 return true;
1159 }
1160
1161 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1162 return true;
1163
1164 return VisitDeclarationNameInfo(D->getNameInfo());
1165}
1166
1167bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1168 // Visit nested-name-specifier.
1169 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1170 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1171 return true;
1172
1173 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1174 D->getIdentLocation(), TU));
1175}
1176
1177bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1178 // Visit nested-name-specifier.
1179 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1180 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1181 return true;
1182 }
1183
1184 return VisitDeclarationNameInfo(D->getNameInfo());
1185}
1186
1187bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1188 UnresolvedUsingTypenameDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return false;
1195}
1196
1197bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1198 switch (Name.getName().getNameKind()) {
1199 case clang::DeclarationName::Identifier:
1200 case clang::DeclarationName::CXXLiteralOperatorName:
1201 case clang::DeclarationName::CXXOperatorName:
1202 case clang::DeclarationName::CXXUsingDirective:
1203 return false;
1204
1205 case clang::DeclarationName::CXXConstructorName:
1206 case clang::DeclarationName::CXXDestructorName:
1207 case clang::DeclarationName::CXXConversionFunctionName:
1208 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1209 return Visit(TSInfo->getTypeLoc());
1210 return false;
1211
1212 case clang::DeclarationName::ObjCZeroArgSelector:
1213 case clang::DeclarationName::ObjCOneArgSelector:
1214 case clang::DeclarationName::ObjCMultiArgSelector:
1215 // FIXME: Per-identifier location info?
1216 return false;
1217 }
1218
1219 llvm_unreachable("Invalid DeclarationName::Kind!");
1220}
1221
1222bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1223 SourceRange Range) {
1224 // FIXME: This whole routine is a hack to work around the lack of proper
1225 // source information in nested-name-specifiers (PR5791). Since we do have
1226 // a beginning source location, we can visit the first component of the
1227 // nested-name-specifier, if it's a single-token component.
1228 if (!NNS)
1229 return false;
1230
1231 // Get the first component in the nested-name-specifier.
1232 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1233 NNS = Prefix;
1234
1235 switch (NNS->getKind()) {
1236 case NestedNameSpecifier::Namespace:
1237 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1238 TU));
1239
1240 case NestedNameSpecifier::NamespaceAlias:
1241 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1242 Range.getBegin(), TU));
1243
1244 case NestedNameSpecifier::TypeSpec: {
1245 // If the type has a form where we know that the beginning of the source
1246 // range matches up with a reference cursor. Visit the appropriate reference
1247 // cursor.
1248 const Type *T = NNS->getAsType();
1249 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1250 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1251 if (const TagType *Tag = dyn_cast<TagType>(T))
1252 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1253 if (const TemplateSpecializationType *TST
1254 = dyn_cast<TemplateSpecializationType>(T))
1255 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1256 break;
1257 }
1258
1259 case NestedNameSpecifier::TypeSpecWithTemplate:
1260 case NestedNameSpecifier::Global:
1261 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001262 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001263 break;
1264 }
1265
1266 return false;
1267}
1268
1269bool
1270CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1271 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1272 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1273 Qualifiers.push_back(Qualifier);
1274
1275 while (!Qualifiers.empty()) {
1276 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1277 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1278 switch (NNS->getKind()) {
1279 case NestedNameSpecifier::Namespace:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::NamespaceAlias:
1288 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1289 Q.getLocalBeginLoc(),
1290 TU)))
1291 return true;
1292
1293 break;
1294
1295 case NestedNameSpecifier::TypeSpec:
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 if (Visit(Q.getTypeLoc()))
1298 return true;
1299
1300 break;
1301
1302 case NestedNameSpecifier::Global:
1303 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001304 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001305 break;
1306 }
1307 }
1308
1309 return false;
1310}
1311
1312bool CursorVisitor::VisitTemplateParameters(
1313 const TemplateParameterList *Params) {
1314 if (!Params)
1315 return false;
1316
1317 for (TemplateParameterList::const_iterator P = Params->begin(),
1318 PEnd = Params->end();
1319 P != PEnd; ++P) {
1320 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1321 return true;
1322 }
1323
1324 return false;
1325}
1326
1327bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1328 switch (Name.getKind()) {
1329 case TemplateName::Template:
1330 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1331
1332 case TemplateName::OverloadedTemplate:
1333 // Visit the overloaded template set.
1334 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1335 return true;
1336
1337 return false;
1338
1339 case TemplateName::DependentTemplate:
1340 // FIXME: Visit nested-name-specifier.
1341 return false;
1342
1343 case TemplateName::QualifiedTemplate:
1344 // FIXME: Visit nested-name-specifier.
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsQualifiedTemplateName()->getDecl(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParm:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1352 Loc, TU));
1353
1354 case TemplateName::SubstTemplateTemplateParmPack:
1355 return Visit(MakeCursorTemplateRef(
1356 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1357 Loc, TU));
1358 }
1359
1360 llvm_unreachable("Invalid TemplateName::Kind!");
1361}
1362
1363bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1364 switch (TAL.getArgument().getKind()) {
1365 case TemplateArgument::Null:
1366 case TemplateArgument::Integral:
1367 case TemplateArgument::Pack:
1368 return false;
1369
1370 case TemplateArgument::Type:
1371 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1372 return Visit(TSInfo->getTypeLoc());
1373 return false;
1374
1375 case TemplateArgument::Declaration:
1376 if (Expr *E = TAL.getSourceDeclExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::NullPtr:
1381 if (Expr *E = TAL.getSourceNullPtrExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Expression:
1386 if (Expr *E = TAL.getSourceExpression())
1387 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1388 return false;
1389
1390 case TemplateArgument::Template:
1391 case TemplateArgument::TemplateExpansion:
1392 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1393 return true;
1394
1395 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1396 TAL.getTemplateNameLoc());
1397 }
1398
1399 llvm_unreachable("Invalid TemplateArgument::Kind!");
1400}
1401
1402bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1403 return VisitDeclContext(D);
1404}
1405
1406bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1407 return Visit(TL.getUnqualifiedLoc());
1408}
1409
1410bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1411 ASTContext &Context = AU->getASTContext();
1412
1413 // Some builtin types (such as Objective-C's "id", "sel", and
1414 // "Class") have associated declarations. Create cursors for those.
1415 QualType VisitType;
1416 switch (TL.getTypePtr()->getKind()) {
1417
1418 case BuiltinType::Void:
1419 case BuiltinType::NullPtr:
1420 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001421 case BuiltinType::OCLImage1d:
1422 case BuiltinType::OCLImage1dArray:
1423 case BuiltinType::OCLImage1dBuffer:
1424 case BuiltinType::OCLImage2d:
1425 case BuiltinType::OCLImage2dArray:
1426 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001427 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001428 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001429#define BUILTIN_TYPE(Id, SingletonId)
1430#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1434#include "clang/AST/BuiltinTypes.def"
1435 break;
1436
1437 case BuiltinType::ObjCId:
1438 VisitType = Context.getObjCIdType();
1439 break;
1440
1441 case BuiltinType::ObjCClass:
1442 VisitType = Context.getObjCClassType();
1443 break;
1444
1445 case BuiltinType::ObjCSel:
1446 VisitType = Context.getObjCSelType();
1447 break;
1448 }
1449
1450 if (!VisitType.isNull()) {
1451 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1452 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1453 TU));
1454 }
1455
1456 return false;
1457}
1458
1459bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1460 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1468 if (TL.isDefinition())
1469 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1470
1471 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1472}
1473
1474bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1475 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1476}
1477
1478bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1479 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1480 return true;
1481
1482 return false;
1483}
1484
1485bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1486 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1487 return true;
1488
1489 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1490 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1491 TU)))
1492 return true;
1493 }
1494
1495 return false;
1496}
1497
1498bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1499 return Visit(TL.getPointeeLoc());
1500}
1501
1502bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1503 return Visit(TL.getInnerLoc());
1504}
1505
1506bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1507 return Visit(TL.getPointeeLoc());
1508}
1509
1510bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1511 return Visit(TL.getPointeeLoc());
1512}
1513
1514bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1515 return Visit(TL.getPointeeLoc());
1516}
1517
1518bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1519 return Visit(TL.getPointeeLoc());
1520}
1521
1522bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1523 return Visit(TL.getPointeeLoc());
1524}
1525
1526bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1527 return Visit(TL.getModifiedLoc());
1528}
1529
1530bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1531 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001532 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001533 return true;
1534
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001535 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1536 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001537 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1538 return true;
1539
1540 return false;
1541}
1542
1543bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1544 if (Visit(TL.getElementLoc()))
1545 return true;
1546
1547 if (Expr *Size = TL.getSizeExpr())
1548 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1549
1550 return false;
1551}
1552
Reid Kleckner8a365022013-06-24 17:51:48 +00001553bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1554 return Visit(TL.getOriginalLoc());
1555}
1556
Reid Kleckner0503a872013-12-05 01:23:43 +00001557bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1558 return Visit(TL.getOriginalLoc());
1559}
1560
Guy Benyei11169dd2012-12-18 14:30:41 +00001561bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1562 TemplateSpecializationTypeLoc TL) {
1563 // Visit the template name.
1564 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1565 TL.getTemplateNameLoc()))
1566 return true;
1567
1568 // Visit the template arguments.
1569 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1570 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1571 return true;
1572
1573 return false;
1574}
1575
1576bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1577 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1578}
1579
1580bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1581 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1582 return Visit(TSInfo->getTypeLoc());
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1588 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1589 return Visit(TSInfo->getTypeLoc());
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1595 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1596 return true;
1597
1598 return false;
1599}
1600
1601bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1602 DependentTemplateSpecializationTypeLoc TL) {
1603 // Visit the nested-name-specifier, if there is one.
1604 if (TL.getQualifierLoc() &&
1605 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1606 return true;
1607
1608 // Visit the template arguments.
1609 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1610 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1611 return true;
1612
1613 return false;
1614}
1615
1616bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1617 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1618 return true;
1619
1620 return Visit(TL.getNamedTypeLoc());
1621}
1622
1623bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1624 return Visit(TL.getPatternLoc());
1625}
1626
1627bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1628 if (Expr *E = TL.getUnderlyingExpr())
1629 return Visit(MakeCXCursor(E, StmtParent, TU));
1630
1631 return false;
1632}
1633
1634bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1635 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1636}
1637
1638bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1639 return Visit(TL.getValueLoc());
1640}
1641
1642#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1643bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1644 return Visit##PARENT##Loc(TL); \
1645}
1646
1647DEFAULT_TYPELOC_IMPL(Complex, Type)
1648DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1652DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1653DEFAULT_TYPELOC_IMPL(Vector, Type)
1654DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1655DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1656DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1657DEFAULT_TYPELOC_IMPL(Record, TagType)
1658DEFAULT_TYPELOC_IMPL(Enum, TagType)
1659DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1660DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1661DEFAULT_TYPELOC_IMPL(Auto, Type)
1662
1663bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1664 // Visit the nested-name-specifier, if present.
1665 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1666 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1667 return true;
1668
1669 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001670 for (const auto &I : D->bases()) {
1671 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001672 return true;
1673 }
1674 }
1675
1676 return VisitTagDecl(D);
1677}
1678
1679bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001680 for (const auto *I : D->attrs())
1681 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001682 return true;
1683
1684 return false;
1685}
1686
1687//===----------------------------------------------------------------------===//
1688// Data-recursive visitor methods.
1689//===----------------------------------------------------------------------===//
1690
1691namespace {
1692#define DEF_JOB(NAME, DATA, KIND)\
1693class NAME : public VisitorJob {\
1694public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001695 NAME(const DATA *d, CXCursor parent) : \
1696 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001697 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001698 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001699};
1700
1701DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1702DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1703DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1704DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1705DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1706 ExplicitTemplateArgsVisitKind)
1707DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1708DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1709DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1710#undef DEF_JOB
1711
1712class DeclVisit : public VisitorJob {
1713public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001714 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001715 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001716 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001717 static bool classof(const VisitorJob *VJ) {
1718 return VJ->getKind() == DeclVisitKind;
1719 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001720 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001721 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001722};
1723class TypeLocVisit : public VisitorJob {
1724public:
1725 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1726 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1727 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1728
1729 static bool classof(const VisitorJob *VJ) {
1730 return VJ->getKind() == TypeLocVisitKind;
1731 }
1732
1733 TypeLoc get() const {
1734 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001735 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001736 }
1737};
1738
1739class LabelRefVisit : public VisitorJob {
1740public:
1741 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1742 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1743 labelLoc.getPtrEncoding()) {}
1744
1745 static bool classof(const VisitorJob *VJ) {
1746 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1747 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 const LabelDecl *get() const {
1749 return static_cast<const LabelDecl *>(data[0]);
1750 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001751 SourceLocation getLoc() const {
1752 return SourceLocation::getFromPtrEncoding(data[1]); }
1753};
1754
1755class NestedNameSpecifierLocVisit : public VisitorJob {
1756public:
1757 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1758 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1759 Qualifier.getNestedNameSpecifier(),
1760 Qualifier.getOpaqueData()) { }
1761
1762 static bool classof(const VisitorJob *VJ) {
1763 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1764 }
1765
1766 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 return NestedNameSpecifierLoc(
1768 const_cast<NestedNameSpecifier *>(
1769 static_cast<const NestedNameSpecifier *>(data[0])),
1770 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001771 }
1772};
1773
1774class DeclarationNameInfoVisit : public VisitorJob {
1775public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001776 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001777 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 static bool classof(const VisitorJob *VJ) {
1779 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1780 }
1781 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001782 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001783 switch (S->getStmtClass()) {
1784 default:
1785 llvm_unreachable("Unhandled Stmt");
1786 case clang::Stmt::MSDependentExistsStmtClass:
1787 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1788 case Stmt::CXXDependentScopeMemberExprClass:
1789 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1790 case Stmt::DependentScopeDeclRefExprClass:
1791 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001792 case Stmt::OMPCriticalDirectiveClass:
1793 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001794 }
1795 }
1796};
1797class MemberRefVisit : public VisitorJob {
1798public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001799 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1801 L.getPtrEncoding()) {}
1802 static bool classof(const VisitorJob *VJ) {
1803 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1804 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001805 const FieldDecl *get() const {
1806 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001807 }
1808 SourceLocation getLoc() const {
1809 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1810 }
1811};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001812class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001813 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001814 VisitorWorkList &WL;
1815 CXCursor Parent;
1816public:
1817 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1818 : WL(wl), Parent(parent) {}
1819
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001820 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1821 void VisitBlockExpr(const BlockExpr *B);
1822 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1823 void VisitCompoundStmt(const CompoundStmt *S);
1824 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1825 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1826 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1827 void VisitCXXNewExpr(const CXXNewExpr *E);
1828 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1829 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1830 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1831 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1832 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1833 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1834 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1835 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001836 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001837 void VisitDeclRefExpr(const DeclRefExpr *D);
1838 void VisitDeclStmt(const DeclStmt *S);
1839 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1840 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1841 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1842 void VisitForStmt(const ForStmt *FS);
1843 void VisitGotoStmt(const GotoStmt *GS);
1844 void VisitIfStmt(const IfStmt *If);
1845 void VisitInitListExpr(const InitListExpr *IE);
1846 void VisitMemberExpr(const MemberExpr *M);
1847 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1848 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1849 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1850 void VisitOverloadExpr(const OverloadExpr *E);
1851 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1852 void VisitStmt(const Stmt *S);
1853 void VisitSwitchStmt(const SwitchStmt *S);
1854 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1856 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1857 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1858 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1859 void VisitVAArgExpr(const VAArgExpr *E);
1860 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1861 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1862 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1863 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001865 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001867 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001868 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001869 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001870 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001871 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001872 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001873 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001874 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001875 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001876 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001877 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001878 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001879 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001880 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001881 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001882 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001883 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001884 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001885 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001886 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887
Guy Benyei11169dd2012-12-18 14:30:41 +00001888private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1891 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1893 void AddStmt(const Stmt *S);
1894 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001897 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001898};
1899} // end anonyous namespace
1900
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 // 'S' should always be non-null, since it comes from the
1903 // statement we are visiting.
1904 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1905}
1906
1907void
1908EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1909 if (Qualifier)
1910 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1911}
1912
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 if (S)
1915 WL.push_back(StmtVisit(S, Parent));
1916}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001918 if (D)
1919 WL.push_back(DeclVisit(D, Parent, isFirst));
1920}
1921void EnqueueVisitor::
1922 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1923 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001924 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001925}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001926void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001927 if (D)
1928 WL.push_back(MemberRefVisit(D, L, Parent));
1929}
1930void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1931 if (TI)
1932 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1933 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001934void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001935 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001936 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 AddStmt(*Child);
1938 }
1939 if (size == WL.size())
1940 return;
1941 // Now reverse the entries we just added. This will match the DFS
1942 // ordering performed by the worklist.
1943 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1944 std::reverse(I, E);
1945}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946namespace {
1947class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1948 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001949 /// \brief Process clauses with list of variables.
1950 template <typename T>
1951 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001952public:
1953 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1954#define OPENMP_CLAUSE(Name, Class) \
1955 void Visit##Class(const Class *C);
1956#include "clang/Basic/OpenMPKinds.def"
1957};
1958
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001959void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1960 Visitor->AddStmt(C->getCondition());
1961}
1962
Alexey Bataev3778b602014-07-17 07:32:53 +00001963void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1964 Visitor->AddStmt(C->getCondition());
1965}
1966
Alexey Bataev568a8332014-03-06 06:15:19 +00001967void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1968 Visitor->AddStmt(C->getNumThreads());
1969}
1970
Alexey Bataev62c87d22014-03-21 04:51:18 +00001971void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1972 Visitor->AddStmt(C->getSafelen());
1973}
1974
Alexander Musman8bd31e62014-05-27 15:12:19 +00001975void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1976 Visitor->AddStmt(C->getNumForLoops());
1977}
1978
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001979void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001980
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001981void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1982
Alexey Bataev56dafe82014-06-20 07:16:17 +00001983void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1984 Visitor->AddStmt(C->getChunkSize());
1985}
1986
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001987void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1988
Alexey Bataev236070f2014-06-20 11:19:47 +00001989void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1990
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001991void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1992
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001993void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1994
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001995void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1996
Alexey Bataevdea47612014-07-23 07:46:59 +00001997void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1998
Alexey Bataev67a4f222014-07-23 10:25:33 +00001999void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2000
Alexey Bataev459dec02014-07-24 06:46:57 +00002001void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2002
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002003void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2004
Alexey Bataev756c1962013-09-24 03:17:45 +00002005template<typename T>
2006void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002007 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002008 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002009 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002010}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002011
2012void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002013 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002014 for (const auto *E : C->private_copies()) {
2015 Visitor->AddStmt(E);
2016 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002017}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002018void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2019 const OMPFirstprivateClause *C) {
2020 VisitOMPClauseList(C);
2021}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002022void OMPClauseEnqueue::VisitOMPLastprivateClause(
2023 const OMPLastprivateClause *C) {
2024 VisitOMPClauseList(C);
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);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002031 for (auto *E : C->lhs_exprs()) {
2032 Visitor->AddStmt(E);
2033 }
2034 for (auto *E : C->rhs_exprs()) {
2035 Visitor->AddStmt(E);
2036 }
2037 for (auto *E : C->reduction_ops()) {
2038 Visitor->AddStmt(E);
2039 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002040}
Alexander Musman8dba6642014-04-22 13:09:42 +00002041void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2042 VisitOMPClauseList(C);
Alexander Musman3276a272015-03-21 10:12:56 +00002043 for (const auto *E : C->inits()) {
2044 Visitor->AddStmt(E);
2045 }
2046 for (const auto *E : C->updates()) {
2047 Visitor->AddStmt(E);
2048 }
2049 for (const auto *E : C->finals()) {
2050 Visitor->AddStmt(E);
2051 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002052 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002053 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002054}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002055void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2056 VisitOMPClauseList(C);
2057 Visitor->AddStmt(C->getAlignment());
2058}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002059void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2060 VisitOMPClauseList(C);
2061}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002062void
2063OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2064 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002065 for (auto *E : C->source_exprs()) {
2066 Visitor->AddStmt(E);
2067 }
2068 for (auto *E : C->destination_exprs()) {
2069 Visitor->AddStmt(E);
2070 }
2071 for (auto *E : C->assignment_ops()) {
2072 Visitor->AddStmt(E);
2073 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002074}
Alexey Bataev6125da92014-07-21 11:26:11 +00002075void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2076 VisitOMPClauseList(C);
2077}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002078}
Alexey Bataev756c1962013-09-24 03:17:45 +00002079
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002080void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2081 unsigned size = WL.size();
2082 OMPClauseEnqueue Visitor(this);
2083 Visitor.Visit(S);
2084 if (size == WL.size())
2085 return;
2086 // Now reverse the entries we just added. This will match the DFS
2087 // ordering performed by the worklist.
2088 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2089 std::reverse(I, E);
2090}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002091void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002092 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2093}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002094void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002095 AddDecl(B->getBlockDecl());
2096}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 EnqueueChildren(E);
2099 AddTypeLoc(E->getTypeSourceInfo());
2100}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002101void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2102 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002103 E = S->body_rend(); I != E; ++I) {
2104 AddStmt(*I);
2105 }
2106}
2107void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002109 AddStmt(S->getSubStmt());
2110 AddDeclarationNameInfo(S);
2111 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2112 AddNestedNameSpecifierLoc(QualifierLoc);
2113}
2114
2115void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2118 AddDeclarationNameInfo(E);
2119 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2120 AddNestedNameSpecifierLoc(QualifierLoc);
2121 if (!E->isImplicitAccess())
2122 AddStmt(E->getBase());
2123}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 // Enqueue the initializer , if any.
2126 AddStmt(E->getInitializer());
2127 // Enqueue the array size, if any.
2128 AddStmt(E->getArraySize());
2129 // Enqueue the allocated type.
2130 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2131 // Enqueue the placement arguments.
2132 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2133 AddStmt(E->getPlacementArg(I-1));
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2137 AddStmt(CE->getArg(I-1));
2138 AddStmt(CE->getCallee());
2139 AddStmt(CE->getArg(0));
2140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2142 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 // Visit the name of the type being destroyed.
2144 AddTypeLoc(E->getDestroyedTypeInfo());
2145 // Visit the scope type that looks disturbingly like the nested-name-specifier
2146 // but isn't.
2147 AddTypeLoc(E->getScopeTypeInfo());
2148 // Visit the nested-name-specifier.
2149 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2150 AddNestedNameSpecifierLoc(QualifierLoc);
2151 // Visit base expression.
2152 AddStmt(E->getBase());
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2155 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 AddTypeLoc(E->getTypeSourceInfo());
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2159 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002160 EnqueueChildren(E);
2161 AddTypeLoc(E->getTypeSourceInfo());
2162}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 EnqueueChildren(E);
2165 if (E->isTypeOperand())
2166 AddTypeLoc(E->getTypeOperandSourceInfo());
2167}
2168
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2170 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002171 EnqueueChildren(E);
2172 AddTypeLoc(E->getTypeSourceInfo());
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 EnqueueChildren(E);
2176 if (E->isTypeOperand())
2177 AddTypeLoc(E->getTypeOperandSourceInfo());
2178}
2179
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 EnqueueChildren(S);
2182 AddDecl(S->getExceptionDecl());
2183}
2184
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002185void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002186 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002187 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002188 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002189}
2190
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 if (DR->hasExplicitTemplateArgs()) {
2193 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2194 }
2195 WL.push_back(DeclRefExprParts(DR, Parent));
2196}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2198 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2200 AddDeclarationNameInfo(E);
2201 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2202}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 unsigned size = WL.size();
2205 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002206 for (const auto *D : S->decls()) {
2207 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 isFirst = false;
2209 }
2210 if (size == WL.size())
2211 return;
2212 // Now reverse the entries we just added. This will match the DFS
2213 // ordering performed by the worklist.
2214 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2215 std::reverse(I, E);
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002219 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 D = E->designators_rbegin(), DEnd = E->designators_rend();
2221 D != DEnd; ++D) {
2222 if (D->isFieldDesignator()) {
2223 if (FieldDecl *Field = D->getField())
2224 AddMemberRef(Field, D->getFieldLoc());
2225 continue;
2226 }
2227 if (D->isArrayDesignator()) {
2228 AddStmt(E->getArrayIndex(*D));
2229 continue;
2230 }
2231 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2232 AddStmt(E->getArrayRangeEnd(*D));
2233 AddStmt(E->getArrayRangeStart(*D));
2234 }
2235}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 EnqueueChildren(E);
2238 AddTypeLoc(E->getTypeInfoAsWritten());
2239}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002240void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 AddStmt(FS->getBody());
2242 AddStmt(FS->getInc());
2243 AddStmt(FS->getCond());
2244 AddDecl(FS->getConditionVariable());
2245 AddStmt(FS->getInit());
2246}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2249}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 AddStmt(If->getElse());
2252 AddStmt(If->getThen());
2253 AddStmt(If->getCond());
2254 AddDecl(If->getConditionVariable());
2255}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002256void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 // We care about the syntactic form of the initializer list, only.
2258 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2259 IE = Syntactic;
2260 EnqueueChildren(IE);
2261}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 WL.push_back(MemberExprParts(M, Parent));
2264
2265 // If the base of the member access expression is an implicit 'this', don't
2266 // visit it.
2267 // FIXME: If we ever want to show these implicit accesses, this will be
2268 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002269 if (M->isImplicitAccess())
2270 return;
2271
2272 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2273 // real field that that we are interested in.
2274 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2275 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2276 if (FD->isAnonymousStructOrUnion()) {
2277 AddStmt(SubME->getBase());
2278 return;
2279 }
2280 }
2281 }
2282
2283 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002284}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 AddTypeLoc(E->getEncodedTypeSourceInfo());
2287}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 EnqueueChildren(M);
2290 AddTypeLoc(M->getClassReceiverTypeInfo());
2291}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 // Visit the components of the offsetof expression.
2294 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2295 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2296 const OffsetOfNode &Node = E->getComponent(I-1);
2297 switch (Node.getKind()) {
2298 case OffsetOfNode::Array:
2299 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2300 break;
2301 case OffsetOfNode::Field:
2302 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2303 break;
2304 case OffsetOfNode::Identifier:
2305 case OffsetOfNode::Base:
2306 continue;
2307 }
2308 }
2309 // Visit the type into which we're computing the offset.
2310 AddTypeLoc(E->getTypeSourceInfo());
2311}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2314 WL.push_back(OverloadExprParts(E, Parent));
2315}
2316void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002317 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002318 EnqueueChildren(E);
2319 if (E->isArgumentType())
2320 AddTypeLoc(E->getArgumentTypeInfo());
2321}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002322void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 EnqueueChildren(S);
2324}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002325void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002326 AddStmt(S->getBody());
2327 AddStmt(S->getCond());
2328 AddDecl(S->getConditionVariable());
2329}
2330
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 AddStmt(W->getBody());
2333 AddStmt(W->getCond());
2334 AddDecl(W->getConditionVariable());
2335}
2336
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002337void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002338 for (unsigned I = E->getNumArgs(); I > 0; --I)
2339 AddTypeLoc(E->getArg(I-1));
2340}
2341
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002343 AddTypeLoc(E->getQueriedTypeSourceInfo());
2344}
2345
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002346void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002347 EnqueueChildren(E);
2348}
2349
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002350void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002351 VisitOverloadExpr(U);
2352 if (!U->isImplicitAccess())
2353 AddStmt(U->getBase());
2354}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002355void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002356 AddStmt(E->getSubExpr());
2357 AddTypeLoc(E->getWrittenTypeInfo());
2358}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002359void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002360 WL.push_back(SizeOfPackExprParts(E, Parent));
2361}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002362void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002363 // If the opaque value has a source expression, just transparently
2364 // visit that. This is useful for (e.g.) pseudo-object expressions.
2365 if (Expr *SourceExpr = E->getSourceExpr())
2366 return Visit(SourceExpr);
2367}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002368void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002369 AddStmt(E->getBody());
2370 WL.push_back(LambdaExprParts(E, Parent));
2371}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002372void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 // Treat the expression like its syntactic form.
2374 Visit(E->getSyntacticForm());
2375}
2376
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002377void EnqueueVisitor::VisitOMPExecutableDirective(
2378 const OMPExecutableDirective *D) {
2379 EnqueueChildren(D);
2380 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2381 E = D->clauses().end();
2382 I != E; ++I)
2383 EnqueueChildren(*I);
2384}
2385
Alexander Musman3aaab662014-08-19 11:27:13 +00002386void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2387 VisitOMPExecutableDirective(D);
2388}
2389
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002390void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2391 VisitOMPExecutableDirective(D);
2392}
2393
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002394void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002395 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002396}
2397
Alexey Bataevf29276e2014-06-18 04:14:57 +00002398void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002399 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002400}
2401
Alexander Musmanf82886e2014-09-18 05:12:34 +00002402void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2403 VisitOMPLoopDirective(D);
2404}
2405
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002406void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2407 VisitOMPExecutableDirective(D);
2408}
2409
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002410void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2411 VisitOMPExecutableDirective(D);
2412}
2413
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002414void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2415 VisitOMPExecutableDirective(D);
2416}
2417
Alexander Musman80c22892014-07-17 08:54:58 +00002418void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2419 VisitOMPExecutableDirective(D);
2420}
2421
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002422void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2423 VisitOMPExecutableDirective(D);
2424 AddDeclarationNameInfo(D);
2425}
2426
Alexey Bataev4acb8592014-07-07 13:01:15 +00002427void
2428EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002429 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002430}
2431
Alexander Musmane4e893b2014-09-23 09:33:00 +00002432void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2433 const OMPParallelForSimdDirective *D) {
2434 VisitOMPLoopDirective(D);
2435}
2436
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002437void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2438 const OMPParallelSectionsDirective *D) {
2439 VisitOMPExecutableDirective(D);
2440}
2441
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002442void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2443 VisitOMPExecutableDirective(D);
2444}
2445
Alexey Bataev68446b72014-07-18 07:47:19 +00002446void
2447EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2448 VisitOMPExecutableDirective(D);
2449}
2450
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002451void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2452 VisitOMPExecutableDirective(D);
2453}
2454
Alexey Bataev2df347a2014-07-18 10:17:07 +00002455void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2456 VisitOMPExecutableDirective(D);
2457}
2458
Alexey Bataev6125da92014-07-21 11:26:11 +00002459void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2460 VisitOMPExecutableDirective(D);
2461}
2462
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002463void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2464 VisitOMPExecutableDirective(D);
2465}
2466
Alexey Bataev0162e452014-07-22 10:10:35 +00002467void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2468 VisitOMPExecutableDirective(D);
2469}
2470
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002471void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2472 VisitOMPExecutableDirective(D);
2473}
2474
Alexey Bataev13314bf2014-10-09 04:18:56 +00002475void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2476 VisitOMPExecutableDirective(D);
2477}
2478
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002479void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002480 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2481}
2482
2483bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2484 if (RegionOfInterest.isValid()) {
2485 SourceRange Range = getRawCursorExtent(C);
2486 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2487 return false;
2488 }
2489 return true;
2490}
2491
2492bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2493 while (!WL.empty()) {
2494 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002495 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002496
2497 // Set the Parent field, then back to its old value once we're done.
2498 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2499
2500 switch (LI.getKind()) {
2501 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002502 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002503 if (!D)
2504 continue;
2505
2506 // For now, perform default visitation for Decls.
2507 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2508 cast<DeclVisit>(&LI)->isFirst())))
2509 return true;
2510
2511 continue;
2512 }
2513 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2514 const ASTTemplateArgumentListInfo *ArgList =
2515 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2516 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2517 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2518 Arg != ArgEnd; ++Arg) {
2519 if (VisitTemplateArgumentLoc(*Arg))
2520 return true;
2521 }
2522 continue;
2523 }
2524 case VisitorJob::TypeLocVisitKind: {
2525 // Perform default visitation for TypeLocs.
2526 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2527 return true;
2528 continue;
2529 }
2530 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002531 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002532 if (LabelStmt *stmt = LS->getStmt()) {
2533 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2534 TU))) {
2535 return true;
2536 }
2537 }
2538 continue;
2539 }
2540
2541 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2542 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2543 if (VisitNestedNameSpecifierLoc(V->get()))
2544 return true;
2545 continue;
2546 }
2547
2548 case VisitorJob::DeclarationNameInfoVisitKind: {
2549 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2550 ->get()))
2551 return true;
2552 continue;
2553 }
2554 case VisitorJob::MemberRefVisitKind: {
2555 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2556 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2557 return true;
2558 continue;
2559 }
2560 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002561 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002562 if (!S)
2563 continue;
2564
2565 // Update the current cursor.
2566 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2567 if (!IsInRegionOfInterest(Cursor))
2568 continue;
2569 switch (Visitor(Cursor, Parent, ClientData)) {
2570 case CXChildVisit_Break: return true;
2571 case CXChildVisit_Continue: break;
2572 case CXChildVisit_Recurse:
2573 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002574 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002575 EnqueueWorkList(WL, S);
2576 break;
2577 }
2578 continue;
2579 }
2580 case VisitorJob::MemberExprPartsKind: {
2581 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002582 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002583
2584 // Visit the nested-name-specifier
2585 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2586 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2587 return true;
2588
2589 // Visit the declaration name.
2590 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2591 return true;
2592
2593 // Visit the explicitly-specified template arguments, if any.
2594 if (M->hasExplicitTemplateArgs()) {
2595 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2596 *ArgEnd = Arg + M->getNumTemplateArgs();
2597 Arg != ArgEnd; ++Arg) {
2598 if (VisitTemplateArgumentLoc(*Arg))
2599 return true;
2600 }
2601 }
2602 continue;
2603 }
2604 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002605 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002606 // Visit nested-name-specifier, if present.
2607 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2608 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2609 return true;
2610 // Visit declaration name.
2611 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2612 return true;
2613 continue;
2614 }
2615 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002616 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002617 // Visit the nested-name-specifier.
2618 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2619 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2620 return true;
2621 // Visit the declaration name.
2622 if (VisitDeclarationNameInfo(O->getNameInfo()))
2623 return true;
2624 // Visit the overloaded declaration reference.
2625 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2626 return true;
2627 continue;
2628 }
2629 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002630 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002631 NamedDecl *Pack = E->getPack();
2632 if (isa<TemplateTypeParmDecl>(Pack)) {
2633 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2634 E->getPackLoc(), TU)))
2635 return true;
2636
2637 continue;
2638 }
2639
2640 if (isa<TemplateTemplateParmDecl>(Pack)) {
2641 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2642 E->getPackLoc(), TU)))
2643 return true;
2644
2645 continue;
2646 }
2647
2648 // Non-type template parameter packs and function parameter packs are
2649 // treated like DeclRefExpr cursors.
2650 continue;
2651 }
2652
2653 case VisitorJob::LambdaExprPartsKind: {
2654 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002655 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002656 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2657 CEnd = E->explicit_capture_end();
2658 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002659 // FIXME: Lambda init-captures.
2660 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002661 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002662
Guy Benyei11169dd2012-12-18 14:30:41 +00002663 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2664 C->getLocation(),
2665 TU)))
2666 return true;
2667 }
2668
2669 // Visit parameters and return type, if present.
2670 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2671 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2672 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2673 // Visit the whole type.
2674 if (Visit(TL))
2675 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002676 } else if (FunctionProtoTypeLoc Proto =
2677 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002678 if (E->hasExplicitParameters()) {
2679 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002680 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2681 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002682 return true;
2683 } else {
2684 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002685 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002686 return true;
2687 }
2688 }
2689 }
2690 break;
2691 }
2692
2693 case VisitorJob::PostChildrenVisitKind:
2694 if (PostChildrenVisitor(Parent, ClientData))
2695 return true;
2696 break;
2697 }
2698 }
2699 return false;
2700}
2701
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002702bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002703 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002704 if (!WorkListFreeList.empty()) {
2705 WL = WorkListFreeList.back();
2706 WL->clear();
2707 WorkListFreeList.pop_back();
2708 }
2709 else {
2710 WL = new VisitorWorkList();
2711 WorkListCache.push_back(WL);
2712 }
2713 EnqueueWorkList(*WL, S);
2714 bool result = RunVisitorWorkList(*WL);
2715 WorkListFreeList.push_back(WL);
2716 return result;
2717}
2718
2719namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002720typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002721RefNamePieces
2722buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2723 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2724 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002725 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2726 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2727 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2728
2729 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2730
2731 RefNamePieces Pieces;
2732
2733 if (WantQualifier && QLoc.isValid())
2734 Pieces.push_back(QLoc);
2735
2736 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2737 Pieces.push_back(NI.getLoc());
2738
2739 if (WantTemplateArgs && TemplateArgs)
2740 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2741 TemplateArgs->RAngleLoc));
2742
2743 if (Kind == DeclarationName::CXXOperatorName) {
2744 Pieces.push_back(SourceLocation::getFromRawEncoding(
2745 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2746 Pieces.push_back(SourceLocation::getFromRawEncoding(
2747 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2748 }
2749
2750 if (WantSinglePiece) {
2751 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2752 Pieces.clear();
2753 Pieces.push_back(R);
2754 }
2755
2756 return Pieces;
2757}
2758}
2759
2760//===----------------------------------------------------------------------===//
2761// Misc. API hooks.
2762//===----------------------------------------------------------------------===//
2763
Chad Rosier05c71aa2013-03-27 18:28:23 +00002764static void fatal_error_handler(void *user_data, const std::string& reason,
2765 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002766 // Write the result out to stderr avoiding errs() because raw_ostreams can
2767 // call report_fatal_error.
2768 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2769 ::abort();
2770}
2771
Chandler Carruth66660742014-06-27 16:37:27 +00002772namespace {
2773struct RegisterFatalErrorHandler {
2774 RegisterFatalErrorHandler() {
2775 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2776 }
2777};
2778}
2779
2780static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2781
Guy Benyei11169dd2012-12-18 14:30:41 +00002782extern "C" {
2783CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2784 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002785 // We use crash recovery to make some of our APIs more reliable, implicitly
2786 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002787 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2788 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002789
Chandler Carruth66660742014-06-27 16:37:27 +00002790 // Look through the managed static to trigger construction of the managed
2791 // static which registers our fatal error handler. This ensures it is only
2792 // registered once.
2793 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002794
2795 CIndexer *CIdxr = new CIndexer();
2796 if (excludeDeclarationsFromPCH)
2797 CIdxr->setOnlyLocalDecls();
2798 if (displayDiagnostics)
2799 CIdxr->setDisplayDiagnostics();
2800
2801 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2802 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2803 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2804 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2805 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2806 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2807
2808 return CIdxr;
2809}
2810
2811void clang_disposeIndex(CXIndex CIdx) {
2812 if (CIdx)
2813 delete static_cast<CIndexer *>(CIdx);
2814}
2815
2816void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2817 if (CIdx)
2818 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2819}
2820
2821unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2822 if (CIdx)
2823 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2824 return 0;
2825}
2826
2827void clang_toggleCrashRecovery(unsigned isEnabled) {
2828 if (isEnabled)
2829 llvm::CrashRecoveryContext::Enable();
2830 else
2831 llvm::CrashRecoveryContext::Disable();
2832}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002833
Guy Benyei11169dd2012-12-18 14:30:41 +00002834CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2835 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002836 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002837 enum CXErrorCode Result =
2838 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002839 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002840 assert((TU && Result == CXError_Success) ||
2841 (!TU && Result != CXError_Success));
2842 return TU;
2843}
2844
2845enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2846 const char *ast_filename,
2847 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002848 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002849 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002850
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002851 if (!CIdx || !ast_filename || !out_TU)
2852 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002853
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002854 LOG_FUNC_SECTION {
2855 *Log << ast_filename;
2856 }
2857
Guy Benyei11169dd2012-12-18 14:30:41 +00002858 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2859 FileSystemOptions FileSystemOpts;
2860
Justin Bognerd512c1e2014-10-15 00:33:06 +00002861 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2862 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002863 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2864 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2865 /*CaptureDiagnostics=*/true,
2866 /*AllowPCHWithCompilerErrors=*/true,
2867 /*UserFilesAreVolatile=*/true);
2868 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002869 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002870}
2871
2872unsigned clang_defaultEditingTranslationUnitOptions() {
2873 return CXTranslationUnit_PrecompiledPreamble |
2874 CXTranslationUnit_CacheCompletionResults;
2875}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002876
Guy Benyei11169dd2012-12-18 14:30:41 +00002877CXTranslationUnit
2878clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2879 const char *source_filename,
2880 int num_command_line_args,
2881 const char * const *command_line_args,
2882 unsigned num_unsaved_files,
2883 struct CXUnsavedFile *unsaved_files) {
2884 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2885 return clang_parseTranslationUnit(CIdx, source_filename,
2886 command_line_args, num_command_line_args,
2887 unsaved_files, num_unsaved_files,
2888 Options);
2889}
2890
2891struct ParseTranslationUnitInfo {
2892 CXIndex CIdx;
2893 const char *source_filename;
2894 const char *const *command_line_args;
2895 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002896 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002897 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002898 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002899 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002900};
2901static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002902 const ParseTranslationUnitInfo *PTUI =
2903 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002904 CXIndex CIdx = PTUI->CIdx;
2905 const char *source_filename = PTUI->source_filename;
2906 const char * const *command_line_args = PTUI->command_line_args;
2907 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002908 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002909 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002910
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002911 // Set up the initial return values.
2912 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002913 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002914
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002915 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002916 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002917 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002918 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002919 }
2920
Guy Benyei11169dd2012-12-18 14:30:41 +00002921 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2922
2923 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2924 setThreadBackgroundPriority();
2925
2926 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2927 // FIXME: Add a flag for modules.
2928 TranslationUnitKind TUKind
2929 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002930 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002931 = options & CXTranslationUnit_CacheCompletionResults;
2932 bool IncludeBriefCommentsInCodeCompletion
2933 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2934 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2935 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2936
2937 // Configure the diagnostics.
2938 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002939 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002940
2941 // Recover resources if we crash before exiting this function.
2942 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2943 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002944 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002945
Ahmed Charlesb8984322014-03-07 20:03:18 +00002946 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2947 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002948
2949 // Recover resources if we crash before exiting this function.
2950 llvm::CrashRecoveryContextCleanupRegistrar<
2951 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2952
Alp Toker9d85b182014-07-07 01:23:14 +00002953 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002954 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002955 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002956 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002957 }
2958
Ahmed Charlesb8984322014-03-07 20:03:18 +00002959 std::unique_ptr<std::vector<const char *>> Args(
2960 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002961
2962 // Recover resources if we crash before exiting this method.
2963 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2964 ArgsCleanup(Args.get());
2965
2966 // Since the Clang C library is primarily used by batch tools dealing with
2967 // (often very broken) source code, where spell-checking can have a
2968 // significant negative impact on performance (particularly when
2969 // precompiled headers are involved), we disable it by default.
2970 // Only do this if we haven't found a spell-checking-related argument.
2971 bool FoundSpellCheckingArgument = false;
2972 for (int I = 0; I != num_command_line_args; ++I) {
2973 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2974 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2975 FoundSpellCheckingArgument = true;
2976 break;
2977 }
2978 }
2979 if (!FoundSpellCheckingArgument)
2980 Args->push_back("-fno-spell-checking");
2981
2982 Args->insert(Args->end(), command_line_args,
2983 command_line_args + num_command_line_args);
2984
2985 // The 'source_filename' argument is optional. If the caller does not
2986 // specify it then it is assumed that the source file is specified
2987 // in the actual argument list.
2988 // Put the source file after command_line_args otherwise if '-x' flag is
2989 // present it will be unused.
2990 if (source_filename)
2991 Args->push_back(source_filename);
2992
2993 // Do we need the detailed preprocessing record?
2994 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2995 Args->push_back("-Xclang");
2996 Args->push_back("-detailed-preprocessing-record");
2997 }
2998
2999 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003000 std::unique_ptr<ASTUnit> ErrUnit;
3001 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00003002 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003003 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3004 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3005 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3006 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3007 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3008 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003009
3010 if (NumErrors != Diags->getClient()->getNumErrors()) {
3011 // Make sure to check that 'Unit' is non-NULL.
3012 if (CXXIdx->getDisplayDiagnostics())
3013 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3014 }
3015
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003016 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
3017 PTUI->result = CXError_ASTReadError;
3018 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00003019 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003020 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
3021 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003022}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003023
3024CXTranslationUnit
3025clang_parseTranslationUnit(CXIndex CIdx,
3026 const char *source_filename,
3027 const char *const *command_line_args,
3028 int num_command_line_args,
3029 struct CXUnsavedFile *unsaved_files,
3030 unsigned num_unsaved_files,
3031 unsigned options) {
3032 CXTranslationUnit TU;
3033 enum CXErrorCode Result = clang_parseTranslationUnit2(
3034 CIdx, source_filename, command_line_args, num_command_line_args,
3035 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003036 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003037 assert((TU && Result == CXError_Success) ||
3038 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003039 return TU;
3040}
3041
3042enum CXErrorCode clang_parseTranslationUnit2(
3043 CXIndex CIdx,
3044 const char *source_filename,
3045 const char *const *command_line_args,
3046 int num_command_line_args,
3047 struct CXUnsavedFile *unsaved_files,
3048 unsigned num_unsaved_files,
3049 unsigned options,
3050 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003051 LOG_FUNC_SECTION {
3052 *Log << source_filename << ": ";
3053 for (int i = 0; i != num_command_line_args; ++i)
3054 *Log << command_line_args[i] << " ";
3055 }
3056
Alp Toker9d85b182014-07-07 01:23:14 +00003057 if (num_unsaved_files && !unsaved_files)
3058 return CXError_InvalidArguments;
3059
Alp Toker5c532982014-07-07 22:42:03 +00003060 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003061 ParseTranslationUnitInfo PTUI = {
3062 CIdx,
3063 source_filename,
3064 command_line_args,
3065 num_command_line_args,
3066 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3067 options,
3068 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003069 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003070 llvm::CrashRecoveryContext CRC;
3071
3072 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3073 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3074 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3075 fprintf(stderr, " 'command_line_args' : [");
3076 for (int i = 0; i != num_command_line_args; ++i) {
3077 if (i)
3078 fprintf(stderr, ", ");
3079 fprintf(stderr, "'%s'", command_line_args[i]);
3080 }
3081 fprintf(stderr, "],\n");
3082 fprintf(stderr, " 'unsaved_files' : [");
3083 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3084 if (i)
3085 fprintf(stderr, ", ");
3086 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3087 unsaved_files[i].Length);
3088 }
3089 fprintf(stderr, "],\n");
3090 fprintf(stderr, " 'options' : %d,\n", options);
3091 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003092
3093 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003094 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003095 if (CXTranslationUnit *TU = PTUI.out_TU)
3096 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003097 }
Alp Toker5c532982014-07-07 22:42:03 +00003098
3099 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003100}
3101
3102unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3103 return CXSaveTranslationUnit_None;
3104}
3105
3106namespace {
3107
3108struct SaveTranslationUnitInfo {
3109 CXTranslationUnit TU;
3110 const char *FileName;
3111 unsigned options;
3112 CXSaveError result;
3113};
3114
3115}
3116
3117static void clang_saveTranslationUnit_Impl(void *UserData) {
3118 SaveTranslationUnitInfo *STUI =
3119 static_cast<SaveTranslationUnitInfo*>(UserData);
3120
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003121 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3123 setThreadBackgroundPriority();
3124
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003125 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3127}
3128
3129int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3130 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003131 LOG_FUNC_SECTION {
3132 *Log << TU << ' ' << FileName;
3133 }
3134
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003135 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003136 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003137 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003138 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003139
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003140 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3142 if (!CXXUnit->hasSema())
3143 return CXSaveError_InvalidTU;
3144
3145 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3146
3147 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3148 getenv("LIBCLANG_NOTHREADS")) {
3149 clang_saveTranslationUnit_Impl(&STUI);
3150
3151 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3152 PrintLibclangResourceUsage(TU);
3153
3154 return STUI.result;
3155 }
3156
3157 // We have an AST that has invalid nodes due to compiler errors.
3158 // Use a crash recovery thread for protection.
3159
3160 llvm::CrashRecoveryContext CRC;
3161
3162 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3163 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3164 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3165 fprintf(stderr, " 'options' : %d,\n", options);
3166 fprintf(stderr, "}\n");
3167
3168 return CXSaveError_Unknown;
3169
3170 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3171 PrintLibclangResourceUsage(TU);
3172 }
3173
3174 return STUI.result;
3175}
3176
3177void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3178 if (CTUnit) {
3179 // If the translation unit has been marked as unsafe to free, just discard
3180 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003181 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3182 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 return;
3184
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003185 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003186 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3188 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003189 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 delete CTUnit;
3191 }
3192}
3193
3194unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3195 return CXReparse_None;
3196}
3197
3198struct ReparseTranslationUnitInfo {
3199 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003200 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003202 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003203};
3204
3205static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003206 const ReparseTranslationUnitInfo *RTUI =
3207 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003209 unsigned options = RTUI->options;
3210 (void) options;
3211
3212 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003213 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003214 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003215 RTUI->result = CXError_InvalidArguments;
3216 return;
3217 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003218
3219 // Reset the associated diagnostics.
3220 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003221 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003222
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003223 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003224 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3225 setThreadBackgroundPriority();
3226
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003227 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003228 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003229
3230 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3231 new std::vector<ASTUnit::RemappedFile>());
3232
Guy Benyei11169dd2012-12-18 14:30:41 +00003233 // Recover resources if we crash before exiting this function.
3234 llvm::CrashRecoveryContextCleanupRegistrar<
3235 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003236
3237 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003238 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003239 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003240 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003242
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003243 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003244 RTUI->result = CXError_Success;
3245 else if (isASTReadError(CXXUnit))
3246 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003247}
3248
3249int clang_reparseTranslationUnit(CXTranslationUnit TU,
3250 unsigned num_unsaved_files,
3251 struct CXUnsavedFile *unsaved_files,
3252 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003253 LOG_FUNC_SECTION {
3254 *Log << TU;
3255 }
3256
Alp Toker9d85b182014-07-07 01:23:14 +00003257 if (num_unsaved_files && !unsaved_files)
3258 return CXError_InvalidArguments;
3259
Alp Toker5c532982014-07-07 22:42:03 +00003260 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003261 ReparseTranslationUnitInfo RTUI = {
3262 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003263 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003264
3265 if (getenv("LIBCLANG_NOTHREADS")) {
3266 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003267 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 }
3269
3270 llvm::CrashRecoveryContext CRC;
3271
3272 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3273 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003274 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003275 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3277 PrintLibclangResourceUsage(TU);
3278
Alp Toker5c532982014-07-07 22:42:03 +00003279 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003280}
3281
3282
3283CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003284 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003285 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003286 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003287 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003288
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003289 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003290 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003291}
3292
3293CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003294 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003295 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003296 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003297 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003298
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003299 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003300 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3301}
3302
3303} // end: extern "C"
3304
3305//===----------------------------------------------------------------------===//
3306// CXFile Operations.
3307//===----------------------------------------------------------------------===//
3308
3309extern "C" {
3310CXString clang_getFileName(CXFile SFile) {
3311 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003312 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003313
3314 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003315 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003316}
3317
3318time_t clang_getFileTime(CXFile SFile) {
3319 if (!SFile)
3320 return 0;
3321
3322 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3323 return FEnt->getModificationTime();
3324}
3325
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003326CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003327 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003328 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003329 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003330 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003331
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003332 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003333
3334 FileManager &FMgr = CXXUnit->getFileManager();
3335 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3336}
3337
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003338unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3339 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003340 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003341 LOG_BAD_TU(TU);
3342 return 0;
3343 }
3344
3345 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 return 0;
3347
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003348 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 FileEntry *FEnt = static_cast<FileEntry *>(file);
3350 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3351 .isFileMultipleIncludeGuarded(FEnt);
3352}
3353
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003354int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3355 if (!file || !outID)
3356 return 1;
3357
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003358 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003359 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3360 outID->data[0] = ID.getDevice();
3361 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003362 outID->data[2] = FEnt->getModificationTime();
3363 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003364}
3365
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003366int clang_File_isEqual(CXFile file1, CXFile file2) {
3367 if (file1 == file2)
3368 return true;
3369
3370 if (!file1 || !file2)
3371 return false;
3372
3373 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3374 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3375 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3376}
3377
Guy Benyei11169dd2012-12-18 14:30:41 +00003378} // end: extern "C"
3379
3380//===----------------------------------------------------------------------===//
3381// CXCursor Operations.
3382//===----------------------------------------------------------------------===//
3383
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003384static const Decl *getDeclFromExpr(const Stmt *E) {
3385 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 return getDeclFromExpr(CE->getSubExpr());
3387
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003388 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003390 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003392 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003394 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003395 if (PRE->isExplicitProperty())
3396 return PRE->getExplicitProperty();
3397 // It could be messaging both getter and setter as in:
3398 // ++myobj.myprop;
3399 // in which case prefer to associate the setter since it is less obvious
3400 // from inspecting the source that the setter is going to get called.
3401 if (PRE->isMessagingSetter())
3402 return PRE->getImplicitPropertySetter();
3403 return PRE->getImplicitPropertyGetter();
3404 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003405 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003406 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003407 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 if (Expr *Src = OVE->getSourceExpr())
3409 return getDeclFromExpr(Src);
3410
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003411 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003413 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003414 if (!CE->isElidable())
3415 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003416 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 return OME->getMethodDecl();
3418
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003419 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003421 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3423 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003424 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3426 isa<ParmVarDecl>(SizeOfPack->getPack()))
3427 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003428
3429 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003430}
3431
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003432static SourceLocation getLocationFromExpr(const Expr *E) {
3433 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 return getLocationFromExpr(CE->getSubExpr());
3435
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003436 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003438 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003440 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003442 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003444 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003446 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003447 return PropRef->getLocation();
3448
3449 return E->getLocStart();
3450}
3451
3452extern "C" {
3453
3454unsigned clang_visitChildren(CXCursor parent,
3455 CXCursorVisitor visitor,
3456 CXClientData client_data) {
3457 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3458 /*VisitPreprocessorLast=*/false);
3459 return CursorVis.VisitChildren(parent);
3460}
3461
3462#ifndef __has_feature
3463#define __has_feature(x) 0
3464#endif
3465#if __has_feature(blocks)
3466typedef enum CXChildVisitResult
3467 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3468
3469static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3470 CXClientData client_data) {
3471 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3472 return block(cursor, parent);
3473}
3474#else
3475// If we are compiled with a compiler that doesn't have native blocks support,
3476// define and call the block manually, so the
3477typedef struct _CXChildVisitResult
3478{
3479 void *isa;
3480 int flags;
3481 int reserved;
3482 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3483 CXCursor);
3484} *CXCursorVisitorBlock;
3485
3486static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3487 CXClientData client_data) {
3488 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3489 return block->invoke(block, cursor, parent);
3490}
3491#endif
3492
3493
3494unsigned clang_visitChildrenWithBlock(CXCursor parent,
3495 CXCursorVisitorBlock block) {
3496 return clang_visitChildren(parent, visitWithBlock, block);
3497}
3498
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003499static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003501 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003502
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003503 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003505 if (const ObjCPropertyImplDecl *PropImpl =
3506 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003508 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003509
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003510 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003512 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003513
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003514 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003515 }
3516
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003517 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003518 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003519
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003520 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3522 // and returns different names. NamedDecl returns the class name and
3523 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003524 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003525
3526 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003527 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003528
3529 SmallString<1024> S;
3530 llvm::raw_svector_ostream os(S);
3531 ND->printName(os);
3532
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003533 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003534}
3535
3536CXString clang_getCursorSpelling(CXCursor C) {
3537 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003538 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003539
3540 if (clang_isReference(C.kind)) {
3541 switch (C.kind) {
3542 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003543 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003544 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 }
3546 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003547 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003548 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 }
3550 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003551 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003553 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 }
3555 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003556 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003557 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 }
3559 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003560 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 assert(Type && "Missing type decl");
3562
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003563 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 getAsString());
3565 }
3566 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003567 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 assert(Template && "Missing template decl");
3569
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003570 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 }
3572
3573 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003574 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 assert(NS && "Missing namespace decl");
3576
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003577 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 }
3579
3580 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003581 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 assert(Field && "Missing member decl");
3583
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003584 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 }
3586
3587 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003588 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 assert(Label && "Missing label");
3590
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003591 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 }
3593
3594 case CXCursor_OverloadedDeclRef: {
3595 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003596 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3597 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003598 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003599 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003601 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003602 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 OverloadedTemplateStorage *Ovl
3604 = Storage.get<OverloadedTemplateStorage*>();
3605 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003606 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003607 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 }
3609
3610 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003611 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 assert(Var && "Missing variable decl");
3613
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003614 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 }
3616
3617 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 }
3620 }
3621
3622 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003623 const Expr *E = getCursorExpr(C);
3624
3625 if (C.kind == CXCursor_ObjCStringLiteral ||
3626 C.kind == CXCursor_StringLiteral) {
3627 const StringLiteral *SLit;
3628 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3629 SLit = OSL->getString();
3630 } else {
3631 SLit = cast<StringLiteral>(E);
3632 }
3633 SmallString<256> Buf;
3634 llvm::raw_svector_ostream OS(Buf);
3635 SLit->outputString(OS);
3636 return cxstring::createDup(OS.str());
3637 }
3638
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003639 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 if (D)
3641 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003642 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 }
3644
3645 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003646 const Stmt *S = getCursorStmt(C);
3647 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003649
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003650 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 }
3652
3653 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 ->getNameStart());
3656
3657 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 ->getNameStart());
3660
3661 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003662 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003663
3664 if (clang_isDeclaration(C.kind))
3665 return getDeclSpelling(getCursorDecl(C));
3666
3667 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003668 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003669 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 }
3671
3672 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003673 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003674 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 }
3676
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003677 if (C.kind == CXCursor_PackedAttr) {
3678 return cxstring::createRef("packed");
3679 }
3680
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003681 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003682}
3683
3684CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3685 unsigned pieceIndex,
3686 unsigned options) {
3687 if (clang_Cursor_isNull(C))
3688 return clang_getNullRange();
3689
3690 ASTContext &Ctx = getCursorContext(C);
3691
3692 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003693 const Stmt *S = getCursorStmt(C);
3694 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 if (pieceIndex > 0)
3696 return clang_getNullRange();
3697 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3698 }
3699
3700 return clang_getNullRange();
3701 }
3702
3703 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003704 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3706 if (pieceIndex >= ME->getNumSelectorLocs())
3707 return clang_getNullRange();
3708 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3709 }
3710 }
3711
3712 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3713 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003714 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3716 if (pieceIndex >= MD->getNumSelectorLocs())
3717 return clang_getNullRange();
3718 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3719 }
3720 }
3721
3722 if (C.kind == CXCursor_ObjCCategoryDecl ||
3723 C.kind == CXCursor_ObjCCategoryImplDecl) {
3724 if (pieceIndex > 0)
3725 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003726 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3728 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003729 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3731 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3732 }
3733
3734 if (C.kind == CXCursor_ModuleImportDecl) {
3735 if (pieceIndex > 0)
3736 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003737 if (const ImportDecl *ImportD =
3738 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3740 if (!Locs.empty())
3741 return cxloc::translateSourceRange(Ctx,
3742 SourceRange(Locs.front(), Locs.back()));
3743 }
3744 return clang_getNullRange();
3745 }
3746
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003747 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3748 C.kind == CXCursor_ConversionFunction) {
3749 if (pieceIndex > 0)
3750 return clang_getNullRange();
3751 if (const FunctionDecl *FD =
3752 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3753 DeclarationNameInfo FunctionName = FD->getNameInfo();
3754 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3755 }
3756 return clang_getNullRange();
3757 }
3758
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 // FIXME: A CXCursor_InclusionDirective should give the location of the
3760 // filename, but we don't keep track of this.
3761
3762 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3763 // but we don't keep track of this.
3764
3765 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3766 // but we don't keep track of this.
3767
3768 // Default handling, give the location of the cursor.
3769
3770 if (pieceIndex > 0)
3771 return clang_getNullRange();
3772
3773 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3774 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3775 return cxloc::translateSourceRange(Ctx, Loc);
3776}
3777
Eli Bendersky44a206f2014-07-31 18:04:56 +00003778CXString clang_Cursor_getMangling(CXCursor C) {
3779 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3780 return cxstring::createEmpty();
3781
Eli Bendersky44a206f2014-07-31 18:04:56 +00003782 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003783 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003784 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3785 return cxstring::createEmpty();
3786
Eli Bendersky79759592014-08-01 15:01:10 +00003787 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003788 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003789 ASTContext &Ctx = ND->getASTContext();
3790 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003791
Eli Bendersky79759592014-08-01 15:01:10 +00003792 std::string FrontendBuf;
3793 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3794 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003795
Eli Bendersky79759592014-08-01 15:01:10 +00003796 // Now apply backend mangling.
3797 std::unique_ptr<llvm::DataLayout> DL(
3798 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3799 llvm::Mangler BackendMangler(DL.get());
3800
3801 std::string FinalBuf;
3802 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3803 BackendMangler.getNameWithPrefix(FinalBufOS,
3804 llvm::Twine(FrontendBufOS.str()));
3805
3806 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003807}
3808
Guy Benyei11169dd2012-12-18 14:30:41 +00003809CXString clang_getCursorDisplayName(CXCursor C) {
3810 if (!clang_isDeclaration(C.kind))
3811 return clang_getCursorSpelling(C);
3812
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003813 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003815 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003816
3817 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003818 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 D = FunTmpl->getTemplatedDecl();
3820
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003821 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 SmallString<64> Str;
3823 llvm::raw_svector_ostream OS(Str);
3824 OS << *Function;
3825 if (Function->getPrimaryTemplate())
3826 OS << "<>";
3827 OS << "(";
3828 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3829 if (I)
3830 OS << ", ";
3831 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3832 }
3833
3834 if (Function->isVariadic()) {
3835 if (Function->getNumParams())
3836 OS << ", ";
3837 OS << "...";
3838 }
3839 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003840 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 }
3842
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003843 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 SmallString<64> Str;
3845 llvm::raw_svector_ostream OS(Str);
3846 OS << *ClassTemplate;
3847 OS << "<";
3848 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3849 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3850 if (I)
3851 OS << ", ";
3852
3853 NamedDecl *Param = Params->getParam(I);
3854 if (Param->getIdentifier()) {
3855 OS << Param->getIdentifier()->getName();
3856 continue;
3857 }
3858
3859 // There is no parameter name, which makes this tricky. Try to come up
3860 // with something useful that isn't too long.
3861 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3862 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3863 else if (NonTypeTemplateParmDecl *NTTP
3864 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3865 OS << NTTP->getType().getAsString(Policy);
3866 else
3867 OS << "template<...> class";
3868 }
3869
3870 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003871 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 }
3873
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003874 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3876 // If the type was explicitly written, use that.
3877 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003878 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003879
Benjamin Kramer9170e912013-02-22 15:46:01 +00003880 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 llvm::raw_svector_ostream OS(Str);
3882 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003883 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 ClassSpec->getTemplateArgs().data(),
3885 ClassSpec->getTemplateArgs().size(),
3886 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003887 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 }
3889
3890 return clang_getCursorSpelling(C);
3891}
3892
3893CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3894 switch (Kind) {
3895 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004023 case CXCursor_ObjCSelfExpr:
4024 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004113 case CXCursor_SEHLeaveStmt:
4114 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004143 case CXCursor_PackedAttr:
4144 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004145 case CXCursor_PureAttr:
4146 return cxstring::createRef("attribute(pure)");
4147 case CXCursor_ConstAttr:
4148 return cxstring::createRef("attribute(const)");
4149 case CXCursor_NoDuplicateAttr:
4150 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004151 case CXCursor_CUDAConstantAttr:
4152 return cxstring::createRef("attribute(constant)");
4153 case CXCursor_CUDADeviceAttr:
4154 return cxstring::createRef("attribute(device)");
4155 case CXCursor_CUDAGlobalAttr:
4156 return cxstring::createRef("attribute(global)");
4157 case CXCursor_CUDAHostAttr:
4158 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004159 case CXCursor_CUDASharedAttr:
4160 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004209 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004210 return cxstring::createRef("OMPParallelDirective");
4211 case CXCursor_OMPSimdDirective:
4212 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004213 case CXCursor_OMPForDirective:
4214 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004215 case CXCursor_OMPForSimdDirective:
4216 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004217 case CXCursor_OMPSectionsDirective:
4218 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004219 case CXCursor_OMPSectionDirective:
4220 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004221 case CXCursor_OMPSingleDirective:
4222 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004223 case CXCursor_OMPMasterDirective:
4224 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004225 case CXCursor_OMPCriticalDirective:
4226 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004227 case CXCursor_OMPParallelForDirective:
4228 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004229 case CXCursor_OMPParallelForSimdDirective:
4230 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004231 case CXCursor_OMPParallelSectionsDirective:
4232 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004233 case CXCursor_OMPTaskDirective:
4234 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004235 case CXCursor_OMPTaskyieldDirective:
4236 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004237 case CXCursor_OMPBarrierDirective:
4238 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004239 case CXCursor_OMPTaskwaitDirective:
4240 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004241 case CXCursor_OMPFlushDirective:
4242 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004243 case CXCursor_OMPOrderedDirective:
4244 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004245 case CXCursor_OMPAtomicDirective:
4246 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004247 case CXCursor_OMPTargetDirective:
4248 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004249 case CXCursor_OMPTeamsDirective:
4250 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004251 case CXCursor_OverloadCandidate:
4252 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 }
4254
4255 llvm_unreachable("Unhandled CXCursorKind");
4256}
4257
4258struct GetCursorData {
4259 SourceLocation TokenBeginLoc;
4260 bool PointsAtMacroArgExpansion;
4261 bool VisitedObjCPropertyImplDecl;
4262 SourceLocation VisitedDeclaratorDeclStartLoc;
4263 CXCursor &BestCursor;
4264
4265 GetCursorData(SourceManager &SM,
4266 SourceLocation tokenBegin, CXCursor &outputCursor)
4267 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4268 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4269 VisitedObjCPropertyImplDecl = false;
4270 }
4271};
4272
4273static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4274 CXCursor parent,
4275 CXClientData client_data) {
4276 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4277 CXCursor *BestCursor = &Data->BestCursor;
4278
4279 // If we point inside a macro argument we should provide info of what the
4280 // token is so use the actual cursor, don't replace it with a macro expansion
4281 // cursor.
4282 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4283 return CXChildVisit_Recurse;
4284
4285 if (clang_isDeclaration(cursor.kind)) {
4286 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004287 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4289 if (MD->isImplicit())
4290 return CXChildVisit_Break;
4291
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004292 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4294 // Check that when we have multiple @class references in the same line,
4295 // that later ones do not override the previous ones.
4296 // If we have:
4297 // @class Foo, Bar;
4298 // source ranges for both start at '@', so 'Bar' will end up overriding
4299 // 'Foo' even though the cursor location was at 'Foo'.
4300 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4301 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004302 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4304 if (PrevID != ID &&
4305 !PrevID->isThisDeclarationADefinition() &&
4306 !ID->isThisDeclarationADefinition())
4307 return CXChildVisit_Break;
4308 }
4309
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004310 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4312 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4313 // Check that when we have multiple declarators in the same line,
4314 // that later ones do not override the previous ones.
4315 // If we have:
4316 // int Foo, Bar;
4317 // source ranges for both start at 'int', so 'Bar' will end up overriding
4318 // 'Foo' even though the cursor location was at 'Foo'.
4319 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4320 return CXChildVisit_Break;
4321 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4322
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004323 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004324 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4325 (void)PropImp;
4326 // Check that when we have multiple @synthesize in the same line,
4327 // that later ones do not override the previous ones.
4328 // If we have:
4329 // @synthesize Foo, Bar;
4330 // source ranges for both start at '@', so 'Bar' will end up overriding
4331 // 'Foo' even though the cursor location was at 'Foo'.
4332 if (Data->VisitedObjCPropertyImplDecl)
4333 return CXChildVisit_Break;
4334 Data->VisitedObjCPropertyImplDecl = true;
4335 }
4336 }
4337
4338 if (clang_isExpression(cursor.kind) &&
4339 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004340 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004341 // Avoid having the cursor of an expression replace the declaration cursor
4342 // when the expression source range overlaps the declaration range.
4343 // This can happen for C++ constructor expressions whose range generally
4344 // include the variable declaration, e.g.:
4345 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4346 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4347 D->getLocation() == Data->TokenBeginLoc)
4348 return CXChildVisit_Break;
4349 }
4350 }
4351
4352 // If our current best cursor is the construction of a temporary object,
4353 // don't replace that cursor with a type reference, because we want
4354 // clang_getCursor() to point at the constructor.
4355 if (clang_isExpression(BestCursor->kind) &&
4356 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4357 cursor.kind == CXCursor_TypeRef) {
4358 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4359 // as having the actual point on the type reference.
4360 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4361 return CXChildVisit_Recurse;
4362 }
4363
4364 *BestCursor = cursor;
4365 return CXChildVisit_Recurse;
4366}
4367
4368CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004369 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004370 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004371 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004372 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004373
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004374 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004375 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4376
4377 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4378 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4379
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004380 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004381 CXFile SearchFile;
4382 unsigned SearchLine, SearchColumn;
4383 CXFile ResultFile;
4384 unsigned ResultLine, ResultColumn;
4385 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4386 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4387 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004388
4389 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4390 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004391 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004392 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 SearchFileName = clang_getFileName(SearchFile);
4394 ResultFileName = clang_getFileName(ResultFile);
4395 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4396 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004397 *Log << llvm::format("(%s:%d:%d) = %s",
4398 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4399 clang_getCString(KindSpelling))
4400 << llvm::format("(%s:%d:%d):%s%s",
4401 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4402 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 clang_disposeString(SearchFileName);
4404 clang_disposeString(ResultFileName);
4405 clang_disposeString(KindSpelling);
4406 clang_disposeString(USR);
4407
4408 CXCursor Definition = clang_getCursorDefinition(Result);
4409 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4410 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4411 CXString DefinitionKindSpelling
4412 = clang_getCursorKindSpelling(Definition.kind);
4413 CXFile DefinitionFile;
4414 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004415 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004416 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004417 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004418 *Log << llvm::format(" -> %s(%s:%d:%d)",
4419 clang_getCString(DefinitionKindSpelling),
4420 clang_getCString(DefinitionFileName),
4421 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 clang_disposeString(DefinitionFileName);
4423 clang_disposeString(DefinitionKindSpelling);
4424 }
4425 }
4426
4427 return Result;
4428}
4429
4430CXCursor clang_getNullCursor(void) {
4431 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4432}
4433
4434unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004435 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4436 // can't set consistently. For example, when visiting a DeclStmt we will set
4437 // it but we don't set it on the result of clang_getCursorDefinition for
4438 // a reference of the same declaration.
4439 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4440 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4441 // to provide that kind of info.
4442 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004443 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004444 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004445 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004446
Guy Benyei11169dd2012-12-18 14:30:41 +00004447 return X == Y;
4448}
4449
4450unsigned clang_hashCursor(CXCursor C) {
4451 unsigned Index = 0;
4452 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4453 Index = 1;
4454
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004455 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004456 std::make_pair(C.kind, C.data[Index]));
4457}
4458
4459unsigned clang_isInvalid(enum CXCursorKind K) {
4460 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4461}
4462
4463unsigned clang_isDeclaration(enum CXCursorKind K) {
4464 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4465 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4466}
4467
4468unsigned clang_isReference(enum CXCursorKind K) {
4469 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4470}
4471
4472unsigned clang_isExpression(enum CXCursorKind K) {
4473 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4474}
4475
4476unsigned clang_isStatement(enum CXCursorKind K) {
4477 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4478}
4479
4480unsigned clang_isAttribute(enum CXCursorKind K) {
4481 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4482}
4483
4484unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4485 return K == CXCursor_TranslationUnit;
4486}
4487
4488unsigned clang_isPreprocessing(enum CXCursorKind K) {
4489 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4490}
4491
4492unsigned clang_isUnexposed(enum CXCursorKind K) {
4493 switch (K) {
4494 case CXCursor_UnexposedDecl:
4495 case CXCursor_UnexposedExpr:
4496 case CXCursor_UnexposedStmt:
4497 case CXCursor_UnexposedAttr:
4498 return true;
4499 default:
4500 return false;
4501 }
4502}
4503
4504CXCursorKind clang_getCursorKind(CXCursor C) {
4505 return C.kind;
4506}
4507
4508CXSourceLocation clang_getCursorLocation(CXCursor C) {
4509 if (clang_isReference(C.kind)) {
4510 switch (C.kind) {
4511 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004512 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 = getCursorObjCSuperClassRef(C);
4514 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4515 }
4516
4517 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004518 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 = getCursorObjCProtocolRef(C);
4520 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4521 }
4522
4523 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004524 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 = getCursorObjCClassRef(C);
4526 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4527 }
4528
4529 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004530 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4532 }
4533
4534 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004535 std::pair<const TemplateDecl *, SourceLocation> P =
4536 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4538 }
4539
4540 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004541 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4543 }
4544
4545 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004546 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4548 }
4549
4550 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004551 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4553 }
4554
4555 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004556 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 if (!BaseSpec)
4558 return clang_getNullLocation();
4559
4560 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4561 return cxloc::translateSourceLocation(getCursorContext(C),
4562 TSInfo->getTypeLoc().getBeginLoc());
4563
4564 return cxloc::translateSourceLocation(getCursorContext(C),
4565 BaseSpec->getLocStart());
4566 }
4567
4568 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004569 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4571 }
4572
4573 case CXCursor_OverloadedDeclRef:
4574 return cxloc::translateSourceLocation(getCursorContext(C),
4575 getCursorOverloadedDeclRef(C).second);
4576
4577 default:
4578 // FIXME: Need a way to enumerate all non-reference cases.
4579 llvm_unreachable("Missed a reference kind");
4580 }
4581 }
4582
4583 if (clang_isExpression(C.kind))
4584 return cxloc::translateSourceLocation(getCursorContext(C),
4585 getLocationFromExpr(getCursorExpr(C)));
4586
4587 if (clang_isStatement(C.kind))
4588 return cxloc::translateSourceLocation(getCursorContext(C),
4589 getCursorStmt(C)->getLocStart());
4590
4591 if (C.kind == CXCursor_PreprocessingDirective) {
4592 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4593 return cxloc::translateSourceLocation(getCursorContext(C), L);
4594 }
4595
4596 if (C.kind == CXCursor_MacroExpansion) {
4597 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004598 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 return cxloc::translateSourceLocation(getCursorContext(C), L);
4600 }
4601
4602 if (C.kind == CXCursor_MacroDefinition) {
4603 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4604 return cxloc::translateSourceLocation(getCursorContext(C), L);
4605 }
4606
4607 if (C.kind == CXCursor_InclusionDirective) {
4608 SourceLocation L
4609 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4610 return cxloc::translateSourceLocation(getCursorContext(C), L);
4611 }
4612
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004613 if (clang_isAttribute(C.kind)) {
4614 SourceLocation L
4615 = cxcursor::getCursorAttr(C)->getLocation();
4616 return cxloc::translateSourceLocation(getCursorContext(C), L);
4617 }
4618
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 if (!clang_isDeclaration(C.kind))
4620 return clang_getNullLocation();
4621
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004622 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 if (!D)
4624 return clang_getNullLocation();
4625
4626 SourceLocation Loc = D->getLocation();
4627 // FIXME: Multiple variables declared in a single declaration
4628 // currently lack the information needed to correctly determine their
4629 // ranges when accounting for the type-specifier. We use context
4630 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4631 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004632 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 if (!cxcursor::isFirstInDeclGroup(C))
4634 Loc = VD->getLocation();
4635 }
4636
4637 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004638 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 Loc = MD->getSelectorStartLoc();
4640
4641 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4642}
4643
4644} // end extern "C"
4645
4646CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4647 assert(TU);
4648
4649 // Guard against an invalid SourceLocation, or we may assert in one
4650 // of the following calls.
4651 if (SLoc.isInvalid())
4652 return clang_getNullCursor();
4653
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004654 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004655
4656 // Translate the given source location to make it point at the beginning of
4657 // the token under the cursor.
4658 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4659 CXXUnit->getASTContext().getLangOpts());
4660
4661 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4662 if (SLoc.isValid()) {
4663 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4664 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4665 /*VisitPreprocessorLast=*/true,
4666 /*VisitIncludedEntities=*/false,
4667 SourceLocation(SLoc));
4668 CursorVis.visitFileRegion();
4669 }
4670
4671 return Result;
4672}
4673
4674static SourceRange getRawCursorExtent(CXCursor C) {
4675 if (clang_isReference(C.kind)) {
4676 switch (C.kind) {
4677 case CXCursor_ObjCSuperClassRef:
4678 return getCursorObjCSuperClassRef(C).second;
4679
4680 case CXCursor_ObjCProtocolRef:
4681 return getCursorObjCProtocolRef(C).second;
4682
4683 case CXCursor_ObjCClassRef:
4684 return getCursorObjCClassRef(C).second;
4685
4686 case CXCursor_TypeRef:
4687 return getCursorTypeRef(C).second;
4688
4689 case CXCursor_TemplateRef:
4690 return getCursorTemplateRef(C).second;
4691
4692 case CXCursor_NamespaceRef:
4693 return getCursorNamespaceRef(C).second;
4694
4695 case CXCursor_MemberRef:
4696 return getCursorMemberRef(C).second;
4697
4698 case CXCursor_CXXBaseSpecifier:
4699 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4700
4701 case CXCursor_LabelRef:
4702 return getCursorLabelRef(C).second;
4703
4704 case CXCursor_OverloadedDeclRef:
4705 return getCursorOverloadedDeclRef(C).second;
4706
4707 case CXCursor_VariableRef:
4708 return getCursorVariableRef(C).second;
4709
4710 default:
4711 // FIXME: Need a way to enumerate all non-reference cases.
4712 llvm_unreachable("Missed a reference kind");
4713 }
4714 }
4715
4716 if (clang_isExpression(C.kind))
4717 return getCursorExpr(C)->getSourceRange();
4718
4719 if (clang_isStatement(C.kind))
4720 return getCursorStmt(C)->getSourceRange();
4721
4722 if (clang_isAttribute(C.kind))
4723 return getCursorAttr(C)->getRange();
4724
4725 if (C.kind == CXCursor_PreprocessingDirective)
4726 return cxcursor::getCursorPreprocessingDirective(C);
4727
4728 if (C.kind == CXCursor_MacroExpansion) {
4729 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004730 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 return TU->mapRangeFromPreamble(Range);
4732 }
4733
4734 if (C.kind == CXCursor_MacroDefinition) {
4735 ASTUnit *TU = getCursorASTUnit(C);
4736 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4737 return TU->mapRangeFromPreamble(Range);
4738 }
4739
4740 if (C.kind == CXCursor_InclusionDirective) {
4741 ASTUnit *TU = getCursorASTUnit(C);
4742 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4743 return TU->mapRangeFromPreamble(Range);
4744 }
4745
4746 if (C.kind == CXCursor_TranslationUnit) {
4747 ASTUnit *TU = getCursorASTUnit(C);
4748 FileID MainID = TU->getSourceManager().getMainFileID();
4749 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4750 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4751 return SourceRange(Start, End);
4752 }
4753
4754 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004755 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 if (!D)
4757 return SourceRange();
4758
4759 SourceRange R = D->getSourceRange();
4760 // FIXME: Multiple variables declared in a single declaration
4761 // currently lack the information needed to correctly determine their
4762 // ranges when accounting for the type-specifier. We use context
4763 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4764 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004765 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 if (!cxcursor::isFirstInDeclGroup(C))
4767 R.setBegin(VD->getLocation());
4768 }
4769 return R;
4770 }
4771 return SourceRange();
4772}
4773
4774/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4775/// the decl-specifier-seq for declarations.
4776static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4777 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004778 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 if (!D)
4780 return SourceRange();
4781
4782 SourceRange R = D->getSourceRange();
4783
4784 // Adjust the start of the location for declarations preceded by
4785 // declaration specifiers.
4786 SourceLocation StartLoc;
4787 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4788 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4789 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004790 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4792 StartLoc = TI->getTypeLoc().getLocStart();
4793 }
4794
4795 if (StartLoc.isValid() && R.getBegin().isValid() &&
4796 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4797 R.setBegin(StartLoc);
4798
4799 // FIXME: Multiple variables declared in a single declaration
4800 // currently lack the information needed to correctly determine their
4801 // ranges when accounting for the type-specifier. We use context
4802 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4803 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004804 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004805 if (!cxcursor::isFirstInDeclGroup(C))
4806 R.setBegin(VD->getLocation());
4807 }
4808
4809 return R;
4810 }
4811
4812 return getRawCursorExtent(C);
4813}
4814
4815extern "C" {
4816
4817CXSourceRange clang_getCursorExtent(CXCursor C) {
4818 SourceRange R = getRawCursorExtent(C);
4819 if (R.isInvalid())
4820 return clang_getNullRange();
4821
4822 return cxloc::translateSourceRange(getCursorContext(C), R);
4823}
4824
4825CXCursor clang_getCursorReferenced(CXCursor C) {
4826 if (clang_isInvalid(C.kind))
4827 return clang_getNullCursor();
4828
4829 CXTranslationUnit tu = getCursorTU(C);
4830 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004831 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 if (!D)
4833 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004834 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004836 if (const ObjCPropertyImplDecl *PropImpl =
4837 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4839 return MakeCXCursor(Property, tu);
4840
4841 return C;
4842 }
4843
4844 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004845 const Expr *E = getCursorExpr(C);
4846 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004847 if (D) {
4848 CXCursor declCursor = MakeCXCursor(D, tu);
4849 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4850 declCursor);
4851 return declCursor;
4852 }
4853
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004854 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004855 return MakeCursorOverloadedDeclRef(Ovl, tu);
4856
4857 return clang_getNullCursor();
4858 }
4859
4860 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004861 const Stmt *S = getCursorStmt(C);
4862 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004863 if (LabelDecl *label = Goto->getLabel())
4864 if (LabelStmt *labelS = label->getStmt())
4865 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4866
4867 return clang_getNullCursor();
4868 }
4869
4870 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004871 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004872 return MakeMacroDefinitionCursor(Def, tu);
4873 }
4874
4875 if (!clang_isReference(C.kind))
4876 return clang_getNullCursor();
4877
4878 switch (C.kind) {
4879 case CXCursor_ObjCSuperClassRef:
4880 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4881
4882 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004883 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4884 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 return MakeCXCursor(Def, tu);
4886
4887 return MakeCXCursor(Prot, tu);
4888 }
4889
4890 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004891 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4892 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004893 return MakeCXCursor(Def, tu);
4894
4895 return MakeCXCursor(Class, tu);
4896 }
4897
4898 case CXCursor_TypeRef:
4899 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4900
4901 case CXCursor_TemplateRef:
4902 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4903
4904 case CXCursor_NamespaceRef:
4905 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4906
4907 case CXCursor_MemberRef:
4908 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4909
4910 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004911 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004912 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4913 tu ));
4914 }
4915
4916 case CXCursor_LabelRef:
4917 // FIXME: We end up faking the "parent" declaration here because we
4918 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004919 return MakeCXCursor(getCursorLabelRef(C).first,
4920 cxtu::getASTUnit(tu)->getASTContext()
4921 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004922 tu);
4923
4924 case CXCursor_OverloadedDeclRef:
4925 return C;
4926
4927 case CXCursor_VariableRef:
4928 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4929
4930 default:
4931 // We would prefer to enumerate all non-reference cursor kinds here.
4932 llvm_unreachable("Unhandled reference cursor kind");
4933 }
4934}
4935
4936CXCursor clang_getCursorDefinition(CXCursor C) {
4937 if (clang_isInvalid(C.kind))
4938 return clang_getNullCursor();
4939
4940 CXTranslationUnit TU = getCursorTU(C);
4941
4942 bool WasReference = false;
4943 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4944 C = clang_getCursorReferenced(C);
4945 WasReference = true;
4946 }
4947
4948 if (C.kind == CXCursor_MacroExpansion)
4949 return clang_getCursorReferenced(C);
4950
4951 if (!clang_isDeclaration(C.kind))
4952 return clang_getNullCursor();
4953
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004954 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 if (!D)
4956 return clang_getNullCursor();
4957
4958 switch (D->getKind()) {
4959 // Declaration kinds that don't really separate the notions of
4960 // declaration and definition.
4961 case Decl::Namespace:
4962 case Decl::Typedef:
4963 case Decl::TypeAlias:
4964 case Decl::TypeAliasTemplate:
4965 case Decl::TemplateTypeParm:
4966 case Decl::EnumConstant:
4967 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004968 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004969 case Decl::IndirectField:
4970 case Decl::ObjCIvar:
4971 case Decl::ObjCAtDefsField:
4972 case Decl::ImplicitParam:
4973 case Decl::ParmVar:
4974 case Decl::NonTypeTemplateParm:
4975 case Decl::TemplateTemplateParm:
4976 case Decl::ObjCCategoryImpl:
4977 case Decl::ObjCImplementation:
4978 case Decl::AccessSpec:
4979 case Decl::LinkageSpec:
4980 case Decl::ObjCPropertyImpl:
4981 case Decl::FileScopeAsm:
4982 case Decl::StaticAssert:
4983 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004984 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 case Decl::Label: // FIXME: Is this right??
4986 case Decl::ClassScopeFunctionSpecialization:
4987 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004988 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004989 return C;
4990
4991 // Declaration kinds that don't make any sense here, but are
4992 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004993 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00004995 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00004996 break;
4997
4998 // Declaration kinds for which the definition is not resolvable.
4999 case Decl::UnresolvedUsingTypename:
5000 case Decl::UnresolvedUsingValue:
5001 break;
5002
5003 case Decl::UsingDirective:
5004 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5005 TU);
5006
5007 case Decl::NamespaceAlias:
5008 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5009
5010 case Decl::Enum:
5011 case Decl::Record:
5012 case Decl::CXXRecord:
5013 case Decl::ClassTemplateSpecialization:
5014 case Decl::ClassTemplatePartialSpecialization:
5015 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5016 return MakeCXCursor(Def, TU);
5017 return clang_getNullCursor();
5018
5019 case Decl::Function:
5020 case Decl::CXXMethod:
5021 case Decl::CXXConstructor:
5022 case Decl::CXXDestructor:
5023 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005024 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005025 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005026 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005027 return clang_getNullCursor();
5028 }
5029
Larisse Voufo39a1e502013-08-06 01:03:05 +00005030 case Decl::Var:
5031 case Decl::VarTemplateSpecialization:
5032 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005033 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005034 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005035 return MakeCXCursor(Def, TU);
5036 return clang_getNullCursor();
5037 }
5038
5039 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005040 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005041 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5042 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5043 return clang_getNullCursor();
5044 }
5045
5046 case Decl::ClassTemplate: {
5047 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5048 ->getDefinition())
5049 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5050 TU);
5051 return clang_getNullCursor();
5052 }
5053
Larisse Voufo39a1e502013-08-06 01:03:05 +00005054 case Decl::VarTemplate: {
5055 if (VarDecl *Def =
5056 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5057 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5058 return clang_getNullCursor();
5059 }
5060
Guy Benyei11169dd2012-12-18 14:30:41 +00005061 case Decl::Using:
5062 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5063 D->getLocation(), TU);
5064
5065 case Decl::UsingShadow:
5066 return clang_getCursorDefinition(
5067 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5068 TU));
5069
5070 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005071 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005072 if (Method->isThisDeclarationADefinition())
5073 return C;
5074
5075 // Dig out the method definition in the associated
5076 // @implementation, if we have it.
5077 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005078 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005079 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5080 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5081 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5082 Method->isInstanceMethod()))
5083 if (Def->isThisDeclarationADefinition())
5084 return MakeCXCursor(Def, TU);
5085
5086 return clang_getNullCursor();
5087 }
5088
5089 case Decl::ObjCCategory:
5090 if (ObjCCategoryImplDecl *Impl
5091 = cast<ObjCCategoryDecl>(D)->getImplementation())
5092 return MakeCXCursor(Impl, TU);
5093 return clang_getNullCursor();
5094
5095 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005096 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005097 return MakeCXCursor(Def, TU);
5098 return clang_getNullCursor();
5099
5100 case Decl::ObjCInterface: {
5101 // There are two notions of a "definition" for an Objective-C
5102 // class: the interface and its implementation. When we resolved a
5103 // reference to an Objective-C class, produce the @interface as
5104 // the definition; when we were provided with the interface,
5105 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005106 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005107 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005108 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 return MakeCXCursor(Def, TU);
5110 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5111 return MakeCXCursor(Impl, TU);
5112 return clang_getNullCursor();
5113 }
5114
5115 case Decl::ObjCProperty:
5116 // FIXME: We don't really know where to find the
5117 // ObjCPropertyImplDecls that implement this property.
5118 return clang_getNullCursor();
5119
5120 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005121 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005123 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 return MakeCXCursor(Def, TU);
5125
5126 return clang_getNullCursor();
5127
5128 case Decl::Friend:
5129 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5130 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5131 return clang_getNullCursor();
5132
5133 case Decl::FriendTemplate:
5134 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5135 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5136 return clang_getNullCursor();
5137 }
5138
5139 return clang_getNullCursor();
5140}
5141
5142unsigned clang_isCursorDefinition(CXCursor C) {
5143 if (!clang_isDeclaration(C.kind))
5144 return 0;
5145
5146 return clang_getCursorDefinition(C) == C;
5147}
5148
5149CXCursor clang_getCanonicalCursor(CXCursor C) {
5150 if (!clang_isDeclaration(C.kind))
5151 return C;
5152
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005153 if (const Decl *D = getCursorDecl(C)) {
5154 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005155 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5156 return MakeCXCursor(CatD, getCursorTU(C));
5157
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005158 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5159 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 return MakeCXCursor(IFD, getCursorTU(C));
5161
5162 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5163 }
5164
5165 return C;
5166}
5167
5168int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5169 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5170}
5171
5172unsigned clang_getNumOverloadedDecls(CXCursor C) {
5173 if (C.kind != CXCursor_OverloadedDeclRef)
5174 return 0;
5175
5176 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005177 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 return E->getNumDecls();
5179
5180 if (OverloadedTemplateStorage *S
5181 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5182 return S->size();
5183
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005184 const Decl *D = Storage.get<const Decl *>();
5185 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 return Using->shadow_size();
5187
5188 return 0;
5189}
5190
5191CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5192 if (cursor.kind != CXCursor_OverloadedDeclRef)
5193 return clang_getNullCursor();
5194
5195 if (index >= clang_getNumOverloadedDecls(cursor))
5196 return clang_getNullCursor();
5197
5198 CXTranslationUnit TU = getCursorTU(cursor);
5199 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005200 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 return MakeCXCursor(E->decls_begin()[index], TU);
5202
5203 if (OverloadedTemplateStorage *S
5204 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5205 return MakeCXCursor(S->begin()[index], TU);
5206
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005207 const Decl *D = Storage.get<const Decl *>();
5208 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 // FIXME: This is, unfortunately, linear time.
5210 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5211 std::advance(Pos, index);
5212 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5213 }
5214
5215 return clang_getNullCursor();
5216}
5217
5218void clang_getDefinitionSpellingAndExtent(CXCursor C,
5219 const char **startBuf,
5220 const char **endBuf,
5221 unsigned *startLine,
5222 unsigned *startColumn,
5223 unsigned *endLine,
5224 unsigned *endColumn) {
5225 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005226 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5228
5229 SourceManager &SM = FD->getASTContext().getSourceManager();
5230 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5231 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5232 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5233 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5234 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5235 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5236}
5237
5238
5239CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5240 unsigned PieceIndex) {
5241 RefNamePieces Pieces;
5242
5243 switch (C.kind) {
5244 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005245 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5247 E->getQualifierLoc().getSourceRange());
5248 break;
5249
5250 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005251 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5253 E->getQualifierLoc().getSourceRange(),
5254 E->getOptionalExplicitTemplateArgs());
5255 break;
5256
5257 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005258 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005259 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005260 const Expr *Callee = OCE->getCallee();
5261 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 Callee = ICE->getSubExpr();
5263
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005264 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005265 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5266 DRE->getQualifierLoc().getSourceRange());
5267 }
5268 break;
5269
5270 default:
5271 break;
5272 }
5273
5274 if (Pieces.empty()) {
5275 if (PieceIndex == 0)
5276 return clang_getCursorExtent(C);
5277 } else if (PieceIndex < Pieces.size()) {
5278 SourceRange R = Pieces[PieceIndex];
5279 if (R.isValid())
5280 return cxloc::translateSourceRange(getCursorContext(C), R);
5281 }
5282
5283 return clang_getNullRange();
5284}
5285
5286void clang_enableStackTraces(void) {
5287 llvm::sys::PrintStackTraceOnErrorSignal();
5288}
5289
5290void clang_executeOnThread(void (*fn)(void*), void *user_data,
5291 unsigned stack_size) {
5292 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5293}
5294
5295} // end: extern "C"
5296
5297//===----------------------------------------------------------------------===//
5298// Token-based Operations.
5299//===----------------------------------------------------------------------===//
5300
5301/* CXToken layout:
5302 * int_data[0]: a CXTokenKind
5303 * int_data[1]: starting token location
5304 * int_data[2]: token length
5305 * int_data[3]: reserved
5306 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5307 * otherwise unused.
5308 */
5309extern "C" {
5310
5311CXTokenKind clang_getTokenKind(CXToken CXTok) {
5312 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5313}
5314
5315CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5316 switch (clang_getTokenKind(CXTok)) {
5317 case CXToken_Identifier:
5318 case CXToken_Keyword:
5319 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005320 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005321 ->getNameStart());
5322
5323 case CXToken_Literal: {
5324 // We have stashed the starting pointer in the ptr_data field. Use it.
5325 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005326 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005327 }
5328
5329 case CXToken_Punctuation:
5330 case CXToken_Comment:
5331 break;
5332 }
5333
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005334 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005335 LOG_BAD_TU(TU);
5336 return cxstring::createEmpty();
5337 }
5338
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 // We have to find the starting buffer pointer the hard way, by
5340 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005341 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005343 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005344
5345 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5346 std::pair<FileID, unsigned> LocInfo
5347 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5348 bool Invalid = false;
5349 StringRef Buffer
5350 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5351 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005352 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005353
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005354 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005355}
5356
5357CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005358 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005359 LOG_BAD_TU(TU);
5360 return clang_getNullLocation();
5361 }
5362
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005363 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 if (!CXXUnit)
5365 return clang_getNullLocation();
5366
5367 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5368 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5369}
5370
5371CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005372 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005373 LOG_BAD_TU(TU);
5374 return clang_getNullRange();
5375 }
5376
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005377 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 if (!CXXUnit)
5379 return clang_getNullRange();
5380
5381 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5382 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5383}
5384
5385static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5386 SmallVectorImpl<CXToken> &CXTokens) {
5387 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5388 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005389 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005390 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005391 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005392
5393 // Cannot tokenize across files.
5394 if (BeginLocInfo.first != EndLocInfo.first)
5395 return;
5396
5397 // Create a lexer
5398 bool Invalid = false;
5399 StringRef Buffer
5400 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5401 if (Invalid)
5402 return;
5403
5404 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5405 CXXUnit->getASTContext().getLangOpts(),
5406 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5407 Lex.SetCommentRetentionState(true);
5408
5409 // Lex tokens until we hit the end of the range.
5410 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5411 Token Tok;
5412 bool previousWasAt = false;
5413 do {
5414 // Lex the next token
5415 Lex.LexFromRawLexer(Tok);
5416 if (Tok.is(tok::eof))
5417 break;
5418
5419 // Initialize the CXToken.
5420 CXToken CXTok;
5421
5422 // - Common fields
5423 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5424 CXTok.int_data[2] = Tok.getLength();
5425 CXTok.int_data[3] = 0;
5426
5427 // - Kind-specific fields
5428 if (Tok.isLiteral()) {
5429 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005430 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 } else if (Tok.is(tok::raw_identifier)) {
5432 // Lookup the identifier to determine whether we have a keyword.
5433 IdentifierInfo *II
5434 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5435
5436 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5437 CXTok.int_data[0] = CXToken_Keyword;
5438 }
5439 else {
5440 CXTok.int_data[0] = Tok.is(tok::identifier)
5441 ? CXToken_Identifier
5442 : CXToken_Keyword;
5443 }
5444 CXTok.ptr_data = II;
5445 } else if (Tok.is(tok::comment)) {
5446 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005447 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005448 } else {
5449 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005450 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 }
5452 CXTokens.push_back(CXTok);
5453 previousWasAt = Tok.is(tok::at);
5454 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5455}
5456
5457void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5458 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005459 LOG_FUNC_SECTION {
5460 *Log << TU << ' ' << Range;
5461 }
5462
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005464 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 if (NumTokens)
5466 *NumTokens = 0;
5467
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005468 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005469 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005470 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005471 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005472
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005473 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 if (!CXXUnit || !Tokens || !NumTokens)
5475 return;
5476
5477 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5478
5479 SourceRange R = cxloc::translateCXSourceRange(Range);
5480 if (R.isInvalid())
5481 return;
5482
5483 SmallVector<CXToken, 32> CXTokens;
5484 getTokens(CXXUnit, R, CXTokens);
5485
5486 if (CXTokens.empty())
5487 return;
5488
5489 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5490 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5491 *NumTokens = CXTokens.size();
5492}
5493
5494void clang_disposeTokens(CXTranslationUnit TU,
5495 CXToken *Tokens, unsigned NumTokens) {
5496 free(Tokens);
5497}
5498
5499} // end: extern "C"
5500
5501//===----------------------------------------------------------------------===//
5502// Token annotation APIs.
5503//===----------------------------------------------------------------------===//
5504
Guy Benyei11169dd2012-12-18 14:30:41 +00005505static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5506 CXCursor parent,
5507 CXClientData client_data);
5508static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5509 CXClientData client_data);
5510
5511namespace {
5512class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005513 CXToken *Tokens;
5514 CXCursor *Cursors;
5515 unsigned NumTokens;
5516 unsigned TokIdx;
5517 unsigned PreprocessingTokIdx;
5518 CursorVisitor AnnotateVis;
5519 SourceManager &SrcMgr;
5520 bool HasContextSensitiveKeywords;
5521
5522 struct PostChildrenInfo {
5523 CXCursor Cursor;
5524 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005525 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005526 unsigned BeforeChildrenTokenIdx;
5527 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005528 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005529
5530 CXToken &getTok(unsigned Idx) {
5531 assert(Idx < NumTokens);
5532 return Tokens[Idx];
5533 }
5534 const CXToken &getTok(unsigned Idx) const {
5535 assert(Idx < NumTokens);
5536 return Tokens[Idx];
5537 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005538 bool MoreTokens() const { return TokIdx < NumTokens; }
5539 unsigned NextToken() const { return TokIdx; }
5540 void AdvanceToken() { ++TokIdx; }
5541 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005542 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005543 }
5544 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005545 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 }
5547 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005548 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005549 }
5550
5551 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005552 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005553 SourceRange);
5554
5555public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005556 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005557 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005558 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005559 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005560 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005561 AnnotateTokensVisitor, this,
5562 /*VisitPreprocessorLast=*/true,
5563 /*VisitIncludedEntities=*/false,
5564 RegionOfInterest,
5565 /*VisitDeclsOnly=*/false,
5566 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005567 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005568 HasContextSensitiveKeywords(false) { }
5569
5570 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5571 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5572 bool postVisitChildren(CXCursor cursor);
5573 void AnnotateTokens();
5574
5575 /// \brief Determine whether the annotator saw any cursors that have
5576 /// context-sensitive keywords.
5577 bool hasContextSensitiveKeywords() const {
5578 return HasContextSensitiveKeywords;
5579 }
5580
5581 ~AnnotateTokensWorker() {
5582 assert(PostChildrenInfos.empty());
5583 }
5584};
5585}
5586
5587void AnnotateTokensWorker::AnnotateTokens() {
5588 // Walk the AST within the region of interest, annotating tokens
5589 // along the way.
5590 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005591}
Guy Benyei11169dd2012-12-18 14:30:41 +00005592
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005593static inline void updateCursorAnnotation(CXCursor &Cursor,
5594 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005595 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005597 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005598}
5599
5600/// \brief It annotates and advances tokens with a cursor until the comparison
5601//// between the cursor location and the source range is the same as
5602/// \arg compResult.
5603///
5604/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5605/// Pass RangeOverlap to annotate tokens inside a range.
5606void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5607 RangeComparisonResult compResult,
5608 SourceRange range) {
5609 while (MoreTokens()) {
5610 const unsigned I = NextToken();
5611 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005612 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5613 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005614
5615 SourceLocation TokLoc = GetTokenLoc(I);
5616 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005617 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005618 AdvanceToken();
5619 continue;
5620 }
5621 break;
5622 }
5623}
5624
5625/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005626/// \returns true if it advanced beyond all macro tokens, false otherwise.
5627bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005628 CXCursor updateC,
5629 RangeComparisonResult compResult,
5630 SourceRange range) {
5631 assert(MoreTokens());
5632 assert(isFunctionMacroToken(NextToken()) &&
5633 "Should be called only for macro arg tokens");
5634
5635 // This works differently than annotateAndAdvanceTokens; because expanded
5636 // macro arguments can have arbitrary translation-unit source order, we do not
5637 // advance the token index one by one until a token fails the range test.
5638 // We only advance once past all of the macro arg tokens if all of them
5639 // pass the range test. If one of them fails we keep the token index pointing
5640 // at the start of the macro arg tokens so that the failing token will be
5641 // annotated by a subsequent annotation try.
5642
5643 bool atLeastOneCompFail = false;
5644
5645 unsigned I = NextToken();
5646 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5647 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5648 if (TokLoc.isFileID())
5649 continue; // not macro arg token, it's parens or comma.
5650 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5651 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5652 Cursors[I] = updateC;
5653 } else
5654 atLeastOneCompFail = true;
5655 }
5656
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005657 if (atLeastOneCompFail)
5658 return false;
5659
5660 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5661 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005662}
5663
5664enum CXChildVisitResult
5665AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005666 SourceRange cursorRange = getRawCursorExtent(cursor);
5667 if (cursorRange.isInvalid())
5668 return CXChildVisit_Recurse;
5669
5670 if (!HasContextSensitiveKeywords) {
5671 // Objective-C properties can have context-sensitive keywords.
5672 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005673 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5675 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5676 }
5677 // Objective-C methods can have context-sensitive keywords.
5678 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5679 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005680 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5682 if (Method->getObjCDeclQualifier())
5683 HasContextSensitiveKeywords = true;
5684 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005685 for (const auto *P : Method->params()) {
5686 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005687 HasContextSensitiveKeywords = true;
5688 break;
5689 }
5690 }
5691 }
5692 }
5693 }
5694 // C++ methods can have context-sensitive keywords.
5695 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005696 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005697 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5698 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5699 HasContextSensitiveKeywords = true;
5700 }
5701 }
5702 // C++ classes can have context-sensitive keywords.
5703 else if (cursor.kind == CXCursor_StructDecl ||
5704 cursor.kind == CXCursor_ClassDecl ||
5705 cursor.kind == CXCursor_ClassTemplate ||
5706 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005707 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005708 if (D->hasAttr<FinalAttr>())
5709 HasContextSensitiveKeywords = true;
5710 }
5711 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005712
5713 // Don't override a property annotation with its getter/setter method.
5714 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5715 parent.kind == CXCursor_ObjCPropertyDecl)
5716 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005717
5718 if (clang_isPreprocessing(cursor.kind)) {
5719 // Items in the preprocessing record are kept separate from items in
5720 // declarations, so we keep a separate token index.
5721 unsigned SavedTokIdx = TokIdx;
5722 TokIdx = PreprocessingTokIdx;
5723
5724 // Skip tokens up until we catch up to the beginning of the preprocessing
5725 // entry.
5726 while (MoreTokens()) {
5727 const unsigned I = NextToken();
5728 SourceLocation TokLoc = GetTokenLoc(I);
5729 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5730 case RangeBefore:
5731 AdvanceToken();
5732 continue;
5733 case RangeAfter:
5734 case RangeOverlap:
5735 break;
5736 }
5737 break;
5738 }
5739
5740 // Look at all of the tokens within this range.
5741 while (MoreTokens()) {
5742 const unsigned I = NextToken();
5743 SourceLocation TokLoc = GetTokenLoc(I);
5744 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5745 case RangeBefore:
5746 llvm_unreachable("Infeasible");
5747 case RangeAfter:
5748 break;
5749 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005750 // For macro expansions, just note where the beginning of the macro
5751 // expansion occurs.
5752 if (cursor.kind == CXCursor_MacroExpansion) {
5753 if (TokLoc == cursorRange.getBegin())
5754 Cursors[I] = cursor;
5755 AdvanceToken();
5756 break;
5757 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005758 // We may have already annotated macro names inside macro definitions.
5759 if (Cursors[I].kind != CXCursor_MacroExpansion)
5760 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 continue;
5763 }
5764 break;
5765 }
5766
5767 // Save the preprocessing token index; restore the non-preprocessing
5768 // token index.
5769 PreprocessingTokIdx = TokIdx;
5770 TokIdx = SavedTokIdx;
5771 return CXChildVisit_Recurse;
5772 }
5773
5774 if (cursorRange.isInvalid())
5775 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005776
5777 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005779 const enum CXCursorKind K = clang_getCursorKind(parent);
5780 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005781 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5782 // Attributes are annotated out-of-order, skip tokens until we reach it.
5783 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005784 ? clang_getNullCursor() : parent;
5785
5786 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5787
5788 // Avoid having the cursor of an expression "overwrite" the annotation of the
5789 // variable declaration that it belongs to.
5790 // This can happen for C++ constructor expressions whose range generally
5791 // include the variable declaration, e.g.:
5792 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005793 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005794 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005795 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 const unsigned I = NextToken();
5797 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5798 E->getLocStart() == D->getLocation() &&
5799 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005800 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005801 AdvanceToken();
5802 }
5803 }
5804 }
5805
5806 // Before recursing into the children keep some state that we are going
5807 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5808 // extra work after the child nodes are visited.
5809 // Note that we don't call VisitChildren here to avoid traversing statements
5810 // code-recursively which can blow the stack.
5811
5812 PostChildrenInfo Info;
5813 Info.Cursor = cursor;
5814 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005815 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005816 Info.BeforeChildrenTokenIdx = NextToken();
5817 PostChildrenInfos.push_back(Info);
5818
5819 return CXChildVisit_Recurse;
5820}
5821
5822bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5823 if (PostChildrenInfos.empty())
5824 return false;
5825 const PostChildrenInfo &Info = PostChildrenInfos.back();
5826 if (!clang_equalCursors(Info.Cursor, cursor))
5827 return false;
5828
5829 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5830 const unsigned AfterChildren = NextToken();
5831 SourceRange cursorRange = Info.CursorRange;
5832
5833 // Scan the tokens that are at the end of the cursor, but are not captured
5834 // but the child cursors.
5835 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5836
5837 // Scan the tokens that are at the beginning of the cursor, but are not
5838 // capture by the child cursors.
5839 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5840 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5841 break;
5842
5843 Cursors[I] = cursor;
5844 }
5845
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005846 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5847 // encountered the attribute cursor.
5848 if (clang_isAttribute(cursor.kind))
5849 TokIdx = Info.BeforeReachingCursorIdx;
5850
Guy Benyei11169dd2012-12-18 14:30:41 +00005851 PostChildrenInfos.pop_back();
5852 return false;
5853}
5854
5855static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5856 CXCursor parent,
5857 CXClientData client_data) {
5858 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5859}
5860
5861static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5862 CXClientData client_data) {
5863 return static_cast<AnnotateTokensWorker*>(client_data)->
5864 postVisitChildren(cursor);
5865}
5866
5867namespace {
5868
5869/// \brief Uses the macro expansions in the preprocessing record to find
5870/// and mark tokens that are macro arguments. This info is used by the
5871/// AnnotateTokensWorker.
5872class MarkMacroArgTokensVisitor {
5873 SourceManager &SM;
5874 CXToken *Tokens;
5875 unsigned NumTokens;
5876 unsigned CurIdx;
5877
5878public:
5879 MarkMacroArgTokensVisitor(SourceManager &SM,
5880 CXToken *tokens, unsigned numTokens)
5881 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5882
5883 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5884 if (cursor.kind != CXCursor_MacroExpansion)
5885 return CXChildVisit_Continue;
5886
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005887 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005888 if (macroRange.getBegin() == macroRange.getEnd())
5889 return CXChildVisit_Continue; // it's not a function macro.
5890
5891 for (; CurIdx < NumTokens; ++CurIdx) {
5892 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5893 macroRange.getBegin()))
5894 break;
5895 }
5896
5897 if (CurIdx == NumTokens)
5898 return CXChildVisit_Break;
5899
5900 for (; CurIdx < NumTokens; ++CurIdx) {
5901 SourceLocation tokLoc = getTokenLoc(CurIdx);
5902 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5903 break;
5904
5905 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5906 }
5907
5908 if (CurIdx == NumTokens)
5909 return CXChildVisit_Break;
5910
5911 return CXChildVisit_Continue;
5912 }
5913
5914private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005915 CXToken &getTok(unsigned Idx) {
5916 assert(Idx < NumTokens);
5917 return Tokens[Idx];
5918 }
5919 const CXToken &getTok(unsigned Idx) const {
5920 assert(Idx < NumTokens);
5921 return Tokens[Idx];
5922 }
5923
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005925 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005926 }
5927
5928 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5929 // The third field is reserved and currently not used. Use it here
5930 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005931 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005932 }
5933};
5934
5935} // end anonymous namespace
5936
5937static CXChildVisitResult
5938MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5939 CXClientData client_data) {
5940 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5941 parent);
5942}
5943
5944namespace {
5945 struct clang_annotateTokens_Data {
5946 CXTranslationUnit TU;
5947 ASTUnit *CXXUnit;
5948 CXToken *Tokens;
5949 unsigned NumTokens;
5950 CXCursor *Cursors;
5951 };
5952}
5953
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005954/// \brief Used by \c annotatePreprocessorTokens.
5955/// \returns true if lexing was finished, false otherwise.
5956static bool lexNext(Lexer &Lex, Token &Tok,
5957 unsigned &NextIdx, unsigned NumTokens) {
5958 if (NextIdx >= NumTokens)
5959 return true;
5960
5961 ++NextIdx;
5962 Lex.LexFromRawLexer(Tok);
5963 if (Tok.is(tok::eof))
5964 return true;
5965
5966 return false;
5967}
5968
Guy Benyei11169dd2012-12-18 14:30:41 +00005969static void annotatePreprocessorTokens(CXTranslationUnit TU,
5970 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005971 CXCursor *Cursors,
5972 CXToken *Tokens,
5973 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005974 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005975
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005976 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005977 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5978 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005979 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005980 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005981 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005982
5983 if (BeginLocInfo.first != EndLocInfo.first)
5984 return;
5985
5986 StringRef Buffer;
5987 bool Invalid = false;
5988 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5989 if (Buffer.empty() || Invalid)
5990 return;
5991
5992 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5993 CXXUnit->getASTContext().getLangOpts(),
5994 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5995 Buffer.end());
5996 Lex.SetCommentRetentionState(true);
5997
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005998 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005999 // Lex tokens in raw mode until we hit the end of the range, to avoid
6000 // entering #includes or expanding macros.
6001 while (true) {
6002 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006003 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6004 break;
6005 unsigned TokIdx = NextIdx-1;
6006 assert(Tok.getLocation() ==
6007 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006008
6009 reprocess:
6010 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006011 // We have found a preprocessing directive. Annotate the tokens
6012 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006013 //
6014 // FIXME: Some simple tests here could identify macro definitions and
6015 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006016
6017 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006018 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6019 break;
6020
Craig Topper69186e72014-06-08 08:38:04 +00006021 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006022 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006023 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6024 break;
6025
6026 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006027 IdentifierInfo &II =
6028 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006029 SourceLocation MappedTokLoc =
6030 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6031 MI = getMacroInfo(II, MappedTokLoc, TU);
6032 }
6033 }
6034
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006035 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006036 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006037 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6038 finished = true;
6039 break;
6040 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006041 // If we are in a macro definition, check if the token was ever a
6042 // macro name and annotate it if that's the case.
6043 if (MI) {
6044 SourceLocation SaveLoc = Tok.getLocation();
6045 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6046 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
6047 Tok.setLocation(SaveLoc);
6048 if (MacroDef)
6049 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6050 Tok.getLocation(), TU);
6051 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006052 } while (!Tok.isAtStartOfLine());
6053
6054 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6055 assert(TokIdx <= LastIdx);
6056 SourceLocation EndLoc =
6057 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6058 CXCursor Cursor =
6059 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6060
6061 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006062 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006063
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006064 if (finished)
6065 break;
6066 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006067 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006068 }
6069}
6070
6071// This gets run a separate thread to avoid stack blowout.
6072static void clang_annotateTokensImpl(void *UserData) {
6073 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6074 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6075 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6076 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6077 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6078
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006079 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006080 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6081 setThreadBackgroundPriority();
6082
6083 // Determine the region of interest, which contains all of the tokens.
6084 SourceRange RegionOfInterest;
6085 RegionOfInterest.setBegin(
6086 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6087 RegionOfInterest.setEnd(
6088 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6089 Tokens[NumTokens-1])));
6090
Guy Benyei11169dd2012-12-18 14:30:41 +00006091 // Relex the tokens within the source range to look for preprocessing
6092 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006093 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006094
6095 // If begin location points inside a macro argument, set it to the expansion
6096 // location so we can have the full context when annotating semantically.
6097 {
6098 SourceManager &SM = CXXUnit->getSourceManager();
6099 SourceLocation Loc =
6100 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6101 if (Loc.isMacroID())
6102 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6103 }
6104
Guy Benyei11169dd2012-12-18 14:30:41 +00006105 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6106 // Search and mark tokens that are macro argument expansions.
6107 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6108 Tokens, NumTokens);
6109 CursorVisitor MacroArgMarker(TU,
6110 MarkMacroArgTokensVisitorDelegate, &Visitor,
6111 /*VisitPreprocessorLast=*/true,
6112 /*VisitIncludedEntities=*/false,
6113 RegionOfInterest);
6114 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6115 }
6116
6117 // Annotate all of the source locations in the region of interest that map to
6118 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006119 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006120
6121 // FIXME: We use a ridiculous stack size here because the data-recursion
6122 // algorithm uses a large stack frame than the non-data recursive version,
6123 // and AnnotationTokensWorker currently transforms the data-recursion
6124 // algorithm back into a traditional recursion by explicitly calling
6125 // VisitChildren(). We will need to remove this explicit recursive call.
6126 W.AnnotateTokens();
6127
6128 // If we ran into any entities that involve context-sensitive keywords,
6129 // take another pass through the tokens to mark them as such.
6130 if (W.hasContextSensitiveKeywords()) {
6131 for (unsigned I = 0; I != NumTokens; ++I) {
6132 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6133 continue;
6134
6135 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6136 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006137 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006138 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6139 if (Property->getPropertyAttributesAsWritten() != 0 &&
6140 llvm::StringSwitch<bool>(II->getName())
6141 .Case("readonly", true)
6142 .Case("assign", true)
6143 .Case("unsafe_unretained", true)
6144 .Case("readwrite", true)
6145 .Case("retain", true)
6146 .Case("copy", true)
6147 .Case("nonatomic", true)
6148 .Case("atomic", true)
6149 .Case("getter", true)
6150 .Case("setter", true)
6151 .Case("strong", true)
6152 .Case("weak", true)
6153 .Default(false))
6154 Tokens[I].int_data[0] = CXToken_Keyword;
6155 }
6156 continue;
6157 }
6158
6159 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6160 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6161 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6162 if (llvm::StringSwitch<bool>(II->getName())
6163 .Case("in", true)
6164 .Case("out", true)
6165 .Case("inout", true)
6166 .Case("oneway", true)
6167 .Case("bycopy", true)
6168 .Case("byref", true)
6169 .Default(false))
6170 Tokens[I].int_data[0] = CXToken_Keyword;
6171 continue;
6172 }
6173
6174 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6175 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6176 Tokens[I].int_data[0] = CXToken_Keyword;
6177 continue;
6178 }
6179 }
6180 }
6181}
6182
6183extern "C" {
6184
6185void clang_annotateTokens(CXTranslationUnit TU,
6186 CXToken *Tokens, unsigned NumTokens,
6187 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006188 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006189 LOG_BAD_TU(TU);
6190 return;
6191 }
6192 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006193 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006194 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006195 }
6196
6197 LOG_FUNC_SECTION {
6198 *Log << TU << ' ';
6199 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6200 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6201 *Log << clang_getRange(bloc, eloc);
6202 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006203
6204 // Any token we don't specifically annotate will have a NULL cursor.
6205 CXCursor C = clang_getNullCursor();
6206 for (unsigned I = 0; I != NumTokens; ++I)
6207 Cursors[I] = C;
6208
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006209 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006210 if (!CXXUnit)
6211 return;
6212
6213 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6214
6215 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6216 llvm::CrashRecoveryContext CRC;
6217 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6218 GetSafetyThreadStackSize() * 2)) {
6219 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6220 }
6221}
6222
6223} // end: extern "C"
6224
6225//===----------------------------------------------------------------------===//
6226// Operations for querying linkage of a cursor.
6227//===----------------------------------------------------------------------===//
6228
6229extern "C" {
6230CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6231 if (!clang_isDeclaration(cursor.kind))
6232 return CXLinkage_Invalid;
6233
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006234 const Decl *D = cxcursor::getCursorDecl(cursor);
6235 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006236 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006237 case NoLinkage:
6238 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006239 case InternalLinkage: return CXLinkage_Internal;
6240 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6241 case ExternalLinkage: return CXLinkage_External;
6242 };
6243
6244 return CXLinkage_Invalid;
6245}
6246} // end: extern "C"
6247
6248//===----------------------------------------------------------------------===//
6249// Operations for querying language of a cursor.
6250//===----------------------------------------------------------------------===//
6251
6252static CXLanguageKind getDeclLanguage(const Decl *D) {
6253 if (!D)
6254 return CXLanguage_C;
6255
6256 switch (D->getKind()) {
6257 default:
6258 break;
6259 case Decl::ImplicitParam:
6260 case Decl::ObjCAtDefsField:
6261 case Decl::ObjCCategory:
6262 case Decl::ObjCCategoryImpl:
6263 case Decl::ObjCCompatibleAlias:
6264 case Decl::ObjCImplementation:
6265 case Decl::ObjCInterface:
6266 case Decl::ObjCIvar:
6267 case Decl::ObjCMethod:
6268 case Decl::ObjCProperty:
6269 case Decl::ObjCPropertyImpl:
6270 case Decl::ObjCProtocol:
6271 return CXLanguage_ObjC;
6272 case Decl::CXXConstructor:
6273 case Decl::CXXConversion:
6274 case Decl::CXXDestructor:
6275 case Decl::CXXMethod:
6276 case Decl::CXXRecord:
6277 case Decl::ClassTemplate:
6278 case Decl::ClassTemplatePartialSpecialization:
6279 case Decl::ClassTemplateSpecialization:
6280 case Decl::Friend:
6281 case Decl::FriendTemplate:
6282 case Decl::FunctionTemplate:
6283 case Decl::LinkageSpec:
6284 case Decl::Namespace:
6285 case Decl::NamespaceAlias:
6286 case Decl::NonTypeTemplateParm:
6287 case Decl::StaticAssert:
6288 case Decl::TemplateTemplateParm:
6289 case Decl::TemplateTypeParm:
6290 case Decl::UnresolvedUsingTypename:
6291 case Decl::UnresolvedUsingValue:
6292 case Decl::Using:
6293 case Decl::UsingDirective:
6294 case Decl::UsingShadow:
6295 return CXLanguage_CPlusPlus;
6296 }
6297
6298 return CXLanguage_C;
6299}
6300
6301extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006302
6303static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6304 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6305 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006306
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006307 switch (D->getAvailability()) {
6308 case AR_Available:
6309 case AR_NotYetIntroduced:
6310 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006311 return getCursorAvailabilityForDecl(
6312 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006313 return CXAvailability_Available;
6314
6315 case AR_Deprecated:
6316 return CXAvailability_Deprecated;
6317
6318 case AR_Unavailable:
6319 return CXAvailability_NotAvailable;
6320 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006321
6322 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006323}
6324
Guy Benyei11169dd2012-12-18 14:30:41 +00006325enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6326 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006327 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6328 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006329
6330 return CXAvailability_Available;
6331}
6332
6333static CXVersion convertVersion(VersionTuple In) {
6334 CXVersion Out = { -1, -1, -1 };
6335 if (In.empty())
6336 return Out;
6337
6338 Out.Major = In.getMajor();
6339
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006340 Optional<unsigned> Minor = In.getMinor();
6341 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006342 Out.Minor = *Minor;
6343 else
6344 return Out;
6345
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006346 Optional<unsigned> Subminor = In.getSubminor();
6347 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006348 Out.Subminor = *Subminor;
6349
6350 return Out;
6351}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006352
6353static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6354 int *always_deprecated,
6355 CXString *deprecated_message,
6356 int *always_unavailable,
6357 CXString *unavailable_message,
6358 CXPlatformAvailability *availability,
6359 int availability_size) {
6360 bool HadAvailAttr = false;
6361 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006362 for (auto A : D->attrs()) {
6363 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006364 HadAvailAttr = true;
6365 if (always_deprecated)
6366 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006367 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006368 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006369 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006370 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006371 continue;
6372 }
6373
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006374 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006375 HadAvailAttr = true;
6376 if (always_unavailable)
6377 *always_unavailable = 1;
6378 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006379 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006380 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6381 }
6382 continue;
6383 }
6384
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006385 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006386 HadAvailAttr = true;
6387 if (N < availability_size) {
6388 availability[N].Platform
6389 = cxstring::createDup(Avail->getPlatform()->getName());
6390 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6391 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6392 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6393 availability[N].Unavailable = Avail->getUnavailable();
6394 availability[N].Message = cxstring::createDup(Avail->getMessage());
6395 }
6396 ++N;
6397 }
6398 }
6399
6400 if (!HadAvailAttr)
6401 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6402 return getCursorPlatformAvailabilityForDecl(
6403 cast<Decl>(EnumConst->getDeclContext()),
6404 always_deprecated,
6405 deprecated_message,
6406 always_unavailable,
6407 unavailable_message,
6408 availability,
6409 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006410
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006411 return N;
6412}
6413
Guy Benyei11169dd2012-12-18 14:30:41 +00006414int clang_getCursorPlatformAvailability(CXCursor cursor,
6415 int *always_deprecated,
6416 CXString *deprecated_message,
6417 int *always_unavailable,
6418 CXString *unavailable_message,
6419 CXPlatformAvailability *availability,
6420 int availability_size) {
6421 if (always_deprecated)
6422 *always_deprecated = 0;
6423 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006424 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006425 if (always_unavailable)
6426 *always_unavailable = 0;
6427 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006428 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006429
Guy Benyei11169dd2012-12-18 14:30:41 +00006430 if (!clang_isDeclaration(cursor.kind))
6431 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006432
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006433 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006434 if (!D)
6435 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006436
6437 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6438 deprecated_message,
6439 always_unavailable,
6440 unavailable_message,
6441 availability,
6442 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006443}
6444
6445void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6446 clang_disposeString(availability->Platform);
6447 clang_disposeString(availability->Message);
6448}
6449
6450CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6451 if (clang_isDeclaration(cursor.kind))
6452 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6453
6454 return CXLanguage_Invalid;
6455}
6456
6457 /// \brief If the given cursor is the "templated" declaration
6458 /// descibing a class or function template, return the class or
6459 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006460static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006461 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006462 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006463
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006464 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006465 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6466 return FunTmpl;
6467
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006468 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006469 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6470 return ClassTmpl;
6471
6472 return D;
6473}
6474
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006475
6476enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6477 StorageClass sc = SC_None;
6478 const Decl *D = getCursorDecl(C);
6479 if (D) {
6480 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6481 sc = FD->getStorageClass();
6482 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6483 sc = VD->getStorageClass();
6484 } else {
6485 return CX_SC_Invalid;
6486 }
6487 } else {
6488 return CX_SC_Invalid;
6489 }
6490 switch (sc) {
6491 case SC_None:
6492 return CX_SC_None;
6493 case SC_Extern:
6494 return CX_SC_Extern;
6495 case SC_Static:
6496 return CX_SC_Static;
6497 case SC_PrivateExtern:
6498 return CX_SC_PrivateExtern;
6499 case SC_OpenCLWorkGroupLocal:
6500 return CX_SC_OpenCLWorkGroupLocal;
6501 case SC_Auto:
6502 return CX_SC_Auto;
6503 case SC_Register:
6504 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006505 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006506 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006507}
6508
Guy Benyei11169dd2012-12-18 14:30:41 +00006509CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6510 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006511 if (const Decl *D = getCursorDecl(cursor)) {
6512 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006513 if (!DC)
6514 return clang_getNullCursor();
6515
6516 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6517 getCursorTU(cursor));
6518 }
6519 }
6520
6521 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006522 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006523 return MakeCXCursor(D, getCursorTU(cursor));
6524 }
6525
6526 return clang_getNullCursor();
6527}
6528
6529CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6530 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006531 if (const Decl *D = getCursorDecl(cursor)) {
6532 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006533 if (!DC)
6534 return clang_getNullCursor();
6535
6536 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6537 getCursorTU(cursor));
6538 }
6539 }
6540
6541 // FIXME: Note that we can't easily compute the lexical context of a
6542 // statement or expression, so we return nothing.
6543 return clang_getNullCursor();
6544}
6545
6546CXFile clang_getIncludedFile(CXCursor cursor) {
6547 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006548 return nullptr;
6549
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006550 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006551 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006552}
6553
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006554unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6555 if (C.kind != CXCursor_ObjCPropertyDecl)
6556 return CXObjCPropertyAttr_noattr;
6557
6558 unsigned Result = CXObjCPropertyAttr_noattr;
6559 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6560 ObjCPropertyDecl::PropertyAttributeKind Attr =
6561 PD->getPropertyAttributesAsWritten();
6562
6563#define SET_CXOBJCPROP_ATTR(A) \
6564 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6565 Result |= CXObjCPropertyAttr_##A
6566 SET_CXOBJCPROP_ATTR(readonly);
6567 SET_CXOBJCPROP_ATTR(getter);
6568 SET_CXOBJCPROP_ATTR(assign);
6569 SET_CXOBJCPROP_ATTR(readwrite);
6570 SET_CXOBJCPROP_ATTR(retain);
6571 SET_CXOBJCPROP_ATTR(copy);
6572 SET_CXOBJCPROP_ATTR(nonatomic);
6573 SET_CXOBJCPROP_ATTR(setter);
6574 SET_CXOBJCPROP_ATTR(atomic);
6575 SET_CXOBJCPROP_ATTR(weak);
6576 SET_CXOBJCPROP_ATTR(strong);
6577 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6578#undef SET_CXOBJCPROP_ATTR
6579
6580 return Result;
6581}
6582
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006583unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6584 if (!clang_isDeclaration(C.kind))
6585 return CXObjCDeclQualifier_None;
6586
6587 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6588 const Decl *D = getCursorDecl(C);
6589 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6590 QT = MD->getObjCDeclQualifier();
6591 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6592 QT = PD->getObjCDeclQualifier();
6593 if (QT == Decl::OBJC_TQ_None)
6594 return CXObjCDeclQualifier_None;
6595
6596 unsigned Result = CXObjCDeclQualifier_None;
6597 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6598 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6599 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6600 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6601 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6602 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6603
6604 return Result;
6605}
6606
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006607unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6608 if (!clang_isDeclaration(C.kind))
6609 return 0;
6610
6611 const Decl *D = getCursorDecl(C);
6612 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6613 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6614 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6615 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6616
6617 return 0;
6618}
6619
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006620unsigned clang_Cursor_isVariadic(CXCursor C) {
6621 if (!clang_isDeclaration(C.kind))
6622 return 0;
6623
6624 const Decl *D = getCursorDecl(C);
6625 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6626 return FD->isVariadic();
6627 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6628 return MD->isVariadic();
6629
6630 return 0;
6631}
6632
Guy Benyei11169dd2012-12-18 14:30:41 +00006633CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6634 if (!clang_isDeclaration(C.kind))
6635 return clang_getNullRange();
6636
6637 const Decl *D = getCursorDecl(C);
6638 ASTContext &Context = getCursorContext(C);
6639 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6640 if (!RC)
6641 return clang_getNullRange();
6642
6643 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6644}
6645
6646CXString clang_Cursor_getRawCommentText(CXCursor C) {
6647 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006648 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006649
6650 const Decl *D = getCursorDecl(C);
6651 ASTContext &Context = getCursorContext(C);
6652 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6653 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6654 StringRef();
6655
6656 // Don't duplicate the string because RawText points directly into source
6657 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006658 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006659}
6660
6661CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6662 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006663 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006664
6665 const Decl *D = getCursorDecl(C);
6666 const ASTContext &Context = getCursorContext(C);
6667 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6668
6669 if (RC) {
6670 StringRef BriefText = RC->getBriefText(Context);
6671
6672 // Don't duplicate the string because RawComment ensures that this memory
6673 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006674 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006675 }
6676
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006677 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006678}
6679
Guy Benyei11169dd2012-12-18 14:30:41 +00006680CXModule clang_Cursor_getModule(CXCursor C) {
6681 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006682 if (const ImportDecl *ImportD =
6683 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006684 return ImportD->getImportedModule();
6685 }
6686
Craig Topper69186e72014-06-08 08:38:04 +00006687 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006688}
6689
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006690CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6691 if (isNotUsableTU(TU)) {
6692 LOG_BAD_TU(TU);
6693 return nullptr;
6694 }
6695 if (!File)
6696 return nullptr;
6697 FileEntry *FE = static_cast<FileEntry *>(File);
6698
6699 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6700 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6701 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6702
Richard Smithfeb54b62014-10-23 02:01:19 +00006703 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006704}
6705
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006706CXFile clang_Module_getASTFile(CXModule CXMod) {
6707 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006708 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006709 Module *Mod = static_cast<Module*>(CXMod);
6710 return const_cast<FileEntry *>(Mod->getASTFile());
6711}
6712
Guy Benyei11169dd2012-12-18 14:30:41 +00006713CXModule clang_Module_getParent(CXModule CXMod) {
6714 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006715 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006716 Module *Mod = static_cast<Module*>(CXMod);
6717 return Mod->Parent;
6718}
6719
6720CXString clang_Module_getName(CXModule CXMod) {
6721 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006722 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006723 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006724 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006725}
6726
6727CXString clang_Module_getFullName(CXModule CXMod) {
6728 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006729 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006730 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006731 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006732}
6733
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006734int clang_Module_isSystem(CXModule CXMod) {
6735 if (!CXMod)
6736 return 0;
6737 Module *Mod = static_cast<Module*>(CXMod);
6738 return Mod->IsSystem;
6739}
6740
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006741unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6742 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006743 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006744 LOG_BAD_TU(TU);
6745 return 0;
6746 }
6747 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006748 return 0;
6749 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006750 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6751 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6752 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006753}
6754
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006755CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6756 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006757 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006758 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006759 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006760 }
6761 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006762 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006763 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006764 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006765
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006766 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6767 if (Index < TopHeaders.size())
6768 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006769
Craig Topper69186e72014-06-08 08:38:04 +00006770 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006771}
6772
6773} // end: extern "C"
6774
6775//===----------------------------------------------------------------------===//
6776// C++ AST instrospection.
6777//===----------------------------------------------------------------------===//
6778
6779extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006780unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6781 if (!clang_isDeclaration(C.kind))
6782 return 0;
6783
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006784 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006785 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006786 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006787 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6788}
6789
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006790unsigned clang_CXXMethod_isConst(CXCursor C) {
6791 if (!clang_isDeclaration(C.kind))
6792 return 0;
6793
6794 const Decl *D = cxcursor::getCursorDecl(C);
6795 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006796 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006797 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6798}
6799
Guy Benyei11169dd2012-12-18 14:30:41 +00006800unsigned clang_CXXMethod_isStatic(CXCursor C) {
6801 if (!clang_isDeclaration(C.kind))
6802 return 0;
6803
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006804 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006805 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006806 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006807 return (Method && Method->isStatic()) ? 1 : 0;
6808}
6809
6810unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6811 if (!clang_isDeclaration(C.kind))
6812 return 0;
6813
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006814 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006815 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006816 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006817 return (Method && Method->isVirtual()) ? 1 : 0;
6818}
6819} // end: extern "C"
6820
6821//===----------------------------------------------------------------------===//
6822// Attribute introspection.
6823//===----------------------------------------------------------------------===//
6824
6825extern "C" {
6826CXType clang_getIBOutletCollectionType(CXCursor C) {
6827 if (C.kind != CXCursor_IBOutletCollectionAttr)
6828 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6829
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006830 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006831 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6832
6833 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6834}
6835} // end: extern "C"
6836
6837//===----------------------------------------------------------------------===//
6838// Inspecting memory usage.
6839//===----------------------------------------------------------------------===//
6840
6841typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6842
6843static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6844 enum CXTUResourceUsageKind k,
6845 unsigned long amount) {
6846 CXTUResourceUsageEntry entry = { k, amount };
6847 entries.push_back(entry);
6848}
6849
6850extern "C" {
6851
6852const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6853 const char *str = "";
6854 switch (kind) {
6855 case CXTUResourceUsage_AST:
6856 str = "ASTContext: expressions, declarations, and types";
6857 break;
6858 case CXTUResourceUsage_Identifiers:
6859 str = "ASTContext: identifiers";
6860 break;
6861 case CXTUResourceUsage_Selectors:
6862 str = "ASTContext: selectors";
6863 break;
6864 case CXTUResourceUsage_GlobalCompletionResults:
6865 str = "Code completion: cached global results";
6866 break;
6867 case CXTUResourceUsage_SourceManagerContentCache:
6868 str = "SourceManager: content cache allocator";
6869 break;
6870 case CXTUResourceUsage_AST_SideTables:
6871 str = "ASTContext: side tables";
6872 break;
6873 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6874 str = "SourceManager: malloc'ed memory buffers";
6875 break;
6876 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6877 str = "SourceManager: mmap'ed memory buffers";
6878 break;
6879 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6880 str = "ExternalASTSource: malloc'ed memory buffers";
6881 break;
6882 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6883 str = "ExternalASTSource: mmap'ed memory buffers";
6884 break;
6885 case CXTUResourceUsage_Preprocessor:
6886 str = "Preprocessor: malloc'ed memory";
6887 break;
6888 case CXTUResourceUsage_PreprocessingRecord:
6889 str = "Preprocessor: PreprocessingRecord";
6890 break;
6891 case CXTUResourceUsage_SourceManager_DataStructures:
6892 str = "SourceManager: data structures and tables";
6893 break;
6894 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6895 str = "Preprocessor: header search tables";
6896 break;
6897 }
6898 return str;
6899}
6900
6901CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006902 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006903 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006904 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006905 return usage;
6906 }
6907
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006908 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006909 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006910 ASTContext &astContext = astUnit->getASTContext();
6911
6912 // How much memory is used by AST nodes and types?
6913 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6914 (unsigned long) astContext.getASTAllocatedMemory());
6915
6916 // How much memory is used by identifiers?
6917 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6918 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6919
6920 // How much memory is used for selectors?
6921 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6922 (unsigned long) astContext.Selectors.getTotalMemory());
6923
6924 // How much memory is used by ASTContext's side tables?
6925 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6926 (unsigned long) astContext.getSideTableAllocatedMemory());
6927
6928 // How much memory is used for caching global code completion results?
6929 unsigned long completionBytes = 0;
6930 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006931 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006932 completionBytes = completionAllocator->getTotalMemory();
6933 }
6934 createCXTUResourceUsageEntry(*entries,
6935 CXTUResourceUsage_GlobalCompletionResults,
6936 completionBytes);
6937
6938 // How much memory is being used by SourceManager's content cache?
6939 createCXTUResourceUsageEntry(*entries,
6940 CXTUResourceUsage_SourceManagerContentCache,
6941 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6942
6943 // How much memory is being used by the MemoryBuffer's in SourceManager?
6944 const SourceManager::MemoryBufferSizes &srcBufs =
6945 astUnit->getSourceManager().getMemoryBufferSizes();
6946
6947 createCXTUResourceUsageEntry(*entries,
6948 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6949 (unsigned long) srcBufs.malloc_bytes);
6950 createCXTUResourceUsageEntry(*entries,
6951 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6952 (unsigned long) srcBufs.mmap_bytes);
6953 createCXTUResourceUsageEntry(*entries,
6954 CXTUResourceUsage_SourceManager_DataStructures,
6955 (unsigned long) astContext.getSourceManager()
6956 .getDataStructureSizes());
6957
6958 // How much memory is being used by the ExternalASTSource?
6959 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6960 const ExternalASTSource::MemoryBufferSizes &sizes =
6961 esrc->getMemoryBufferSizes();
6962
6963 createCXTUResourceUsageEntry(*entries,
6964 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6965 (unsigned long) sizes.malloc_bytes);
6966 createCXTUResourceUsageEntry(*entries,
6967 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6968 (unsigned long) sizes.mmap_bytes);
6969 }
6970
6971 // How much memory is being used by the Preprocessor?
6972 Preprocessor &pp = astUnit->getPreprocessor();
6973 createCXTUResourceUsageEntry(*entries,
6974 CXTUResourceUsage_Preprocessor,
6975 pp.getTotalMemory());
6976
6977 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6978 createCXTUResourceUsageEntry(*entries,
6979 CXTUResourceUsage_PreprocessingRecord,
6980 pRec->getTotalMemory());
6981 }
6982
6983 createCXTUResourceUsageEntry(*entries,
6984 CXTUResourceUsage_Preprocessor_HeaderSearch,
6985 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006986
Guy Benyei11169dd2012-12-18 14:30:41 +00006987 CXTUResourceUsage usage = { (void*) entries.get(),
6988 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00006989 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006990 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006991 return usage;
6992}
6993
6994void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6995 if (usage.data)
6996 delete (MemUsageEntries*) usage.data;
6997}
6998
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006999CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7000 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007001 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007002 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007003
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007004 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007005 LOG_BAD_TU(TU);
7006 return skipped;
7007 }
7008
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007009 if (!file)
7010 return skipped;
7011
7012 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7013 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7014 if (!ppRec)
7015 return skipped;
7016
7017 ASTContext &Ctx = astUnit->getASTContext();
7018 SourceManager &sm = Ctx.getSourceManager();
7019 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7020 FileID wantedFileID = sm.translateFile(fileEntry);
7021
7022 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7023 std::vector<SourceRange> wantedRanges;
7024 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7025 i != ei; ++i) {
7026 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7027 wantedRanges.push_back(*i);
7028 }
7029
7030 skipped->count = wantedRanges.size();
7031 skipped->ranges = new CXSourceRange[skipped->count];
7032 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7033 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7034
7035 return skipped;
7036}
7037
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007038void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7039 if (ranges) {
7040 delete[] ranges->ranges;
7041 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007042 }
7043}
7044
Guy Benyei11169dd2012-12-18 14:30:41 +00007045} // end extern "C"
7046
7047void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7048 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7049 for (unsigned I = 0; I != Usage.numEntries; ++I)
7050 fprintf(stderr, " %s: %lu\n",
7051 clang_getTUResourceUsageName(Usage.entries[I].kind),
7052 Usage.entries[I].amount);
7053
7054 clang_disposeCXTUResourceUsage(Usage);
7055}
7056
7057//===----------------------------------------------------------------------===//
7058// Misc. utility functions.
7059//===----------------------------------------------------------------------===//
7060
7061/// Default to using an 8 MB stack size on "safety" threads.
7062static unsigned SafetyStackThreadSize = 8 << 20;
7063
7064namespace clang {
7065
7066bool RunSafely(llvm::CrashRecoveryContext &CRC,
7067 void (*Fn)(void*), void *UserData,
7068 unsigned Size) {
7069 if (!Size)
7070 Size = GetSafetyThreadStackSize();
7071 if (Size)
7072 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7073 return CRC.RunSafely(Fn, UserData);
7074}
7075
7076unsigned GetSafetyThreadStackSize() {
7077 return SafetyStackThreadSize;
7078}
7079
7080void SetSafetyThreadStackSize(unsigned Value) {
7081 SafetyStackThreadSize = Value;
7082}
7083
7084}
7085
7086void clang::setThreadBackgroundPriority() {
7087 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7088 return;
7089
Alp Toker1a86ad22014-07-06 06:24:00 +00007090#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007091 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7092#endif
7093}
7094
7095void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7096 if (!Unit)
7097 return;
7098
7099 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7100 DEnd = Unit->stored_diag_end();
7101 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007102 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007103 CXString Msg = clang_formatDiagnostic(&Diag,
7104 clang_defaultDiagnosticDisplayOptions());
7105 fprintf(stderr, "%s\n", clang_getCString(Msg));
7106 clang_disposeString(Msg);
7107 }
7108#ifdef LLVM_ON_WIN32
7109 // On Windows, force a flush, since there may be multiple copies of
7110 // stderr and stdout in the file system, all with different buffers
7111 // but writing to the same device.
7112 fflush(stderr);
7113#endif
7114}
7115
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007116MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7117 SourceLocation MacroDefLoc,
7118 CXTranslationUnit TU){
7119 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007120 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007121 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007122 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007123
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007124 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007125 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007126 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007127 if (MD) {
7128 for (MacroDirective::DefInfo
7129 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7130 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7131 return Def.getMacroInfo();
7132 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007133 }
7134
Craig Topper69186e72014-06-08 08:38:04 +00007135 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007136}
7137
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007138const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7139 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007140 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007141 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007142 const IdentifierInfo *II = MacroDef->getName();
7143 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007144 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007145
7146 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7147}
7148
7149MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7150 const Token &Tok,
7151 CXTranslationUnit TU) {
7152 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007153 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007154 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007155 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007156
7157 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007158 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007159 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7160 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007161 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007162
7163 // Check that the token is inside the definition and not its argument list.
7164 SourceManager &SM = Unit->getSourceManager();
7165 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007166 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007167 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007168 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007169
7170 Preprocessor &PP = Unit->getPreprocessor();
7171 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7172 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007173 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007174
Alp Toker2d57cea2014-05-17 04:53:25 +00007175 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007176 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007177 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007178
7179 // Check that the identifier is not one of the macro arguments.
7180 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007181 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007182
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007183 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7184 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007185 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007186
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007187 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007188}
7189
7190MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7191 SourceLocation Loc,
7192 CXTranslationUnit TU) {
7193 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007194 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007195
7196 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007197 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007198 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007199 Preprocessor &PP = Unit->getPreprocessor();
7200 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007201 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007202 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7203 Token Tok;
7204 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007205 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007206
7207 return checkForMacroInMacroDefinition(MI, Tok, TU);
7208}
7209
Guy Benyei11169dd2012-12-18 14:30:41 +00007210extern "C" {
7211
7212CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007213 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007214}
7215
7216} // end: extern "C"
7217
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007218Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7219 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007220 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007221 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007222 if (Unit->isMainFileAST())
7223 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007224 return *this;
7225 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007226 } else {
7227 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007228 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007229 return *this;
7230}
7231
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007232Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7233 *this << FE->getName();
7234 return *this;
7235}
7236
7237Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7238 CXString cursorName = clang_getCursorDisplayName(cursor);
7239 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7240 clang_disposeString(cursorName);
7241 return *this;
7242}
7243
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007244Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7245 CXFile File;
7246 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007247 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007248 CXString FileName = clang_getFileName(File);
7249 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7250 clang_disposeString(FileName);
7251 return *this;
7252}
7253
7254Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7255 CXSourceLocation BLoc = clang_getRangeStart(range);
7256 CXSourceLocation ELoc = clang_getRangeEnd(range);
7257
7258 CXFile BFile;
7259 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007260 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007261
7262 CXFile EFile;
7263 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007264 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007265
7266 CXString BFileName = clang_getFileName(BFile);
7267 if (BFile == EFile) {
7268 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7269 BLine, BColumn, ELine, EColumn);
7270 } else {
7271 CXString EFileName = clang_getFileName(EFile);
7272 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7273 BLine, BColumn)
7274 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7275 ELine, EColumn);
7276 clang_disposeString(EFileName);
7277 }
7278 clang_disposeString(BFileName);
7279 return *this;
7280}
7281
7282Logger &cxindex::Logger::operator<<(CXString Str) {
7283 *this << clang_getCString(Str);
7284 return *this;
7285}
7286
7287Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7288 LogOS << Fmt;
7289 return *this;
7290}
7291
Chandler Carruth37ad2582014-06-27 15:14:39 +00007292static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7293
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007294cxindex::Logger::~Logger() {
7295 LogOS.flush();
7296
Chandler Carruth37ad2582014-06-27 15:14:39 +00007297 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007298
7299 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7300
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007301 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007302 OS << "[libclang:" << Name << ':';
7303
Alp Toker1a86ad22014-07-06 06:24:00 +00007304#ifdef USE_DARWIN_THREADS
7305 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007306 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7307 OS << tid << ':';
7308#endif
7309
7310 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7311 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007312 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007313
7314 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007315 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007316 OS << "--------------------------------------------------\n";
7317 }
7318}