blob: efe20e27d82272532a537802ea8058daa525f464 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000243 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
244 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000245 PPRec, FID);
246}
247
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000248bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000249 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000250 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000251
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000252 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000253 SourceManager &SM = Unit->getSourceManager();
254
255 std::pair<FileID, unsigned>
256 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
257 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
258
259 if (End.first != Begin.first) {
260 // If the end does not reside in the same file, try to recover by
261 // picking the end of the file of begin location.
262 End.first = Begin.first;
263 End.second = SM.getFileIDSize(Begin.first);
264 }
265
266 assert(Begin.first == End.first);
267 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000268 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
270 FileID File = Begin.first;
271 unsigned Offset = Begin.second;
272 unsigned Length = End.second - Begin.second;
273
274 if (!VisitDeclsOnly && !VisitPreprocessorLast)
275 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000276 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000277
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000278 if (visitDeclsFromFileRegion(File, Offset, Length))
279 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000280
281 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000282 return visitPreprocessedEntitiesInRegion();
283
284 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000285}
286
287static bool isInLexicalContext(Decl *D, DeclContext *DC) {
288 if (!DC)
289 return false;
290
291 for (DeclContext *DeclDC = D->getLexicalDeclContext();
292 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
293 if (DeclDC == DC)
294 return true;
295 }
296 return false;
297}
298
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000299bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000300 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000301 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000302 SourceManager &SM = Unit->getSourceManager();
303 SourceRange Range = RegionOfInterest;
304
305 SmallVector<Decl *, 16> Decls;
306 Unit->findFileRegionDecls(File, Offset, Length, Decls);
307
308 // If we didn't find any file level decls for the file, try looking at the
309 // file that it was included from.
310 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
311 bool Invalid = false;
312 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
313 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000314 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315
316 SourceLocation Outer;
317 if (SLEntry.isFile())
318 Outer = SLEntry.getFile().getIncludeLoc();
319 else
320 Outer = SLEntry.getExpansion().getExpansionLocStart();
321 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000322 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000323
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000324 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000325 Length = 0;
326 Unit->findFileRegionDecls(File, Offset, Length, Decls);
327 }
328
329 assert(!Decls.empty());
330
331 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000332 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000333 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
334 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000335 Decl *D = *DIt;
336 if (D->getSourceRange().isInvalid())
337 continue;
338
339 if (isInLexicalContext(D, CurDC))
340 continue;
341
342 CurDC = dyn_cast<DeclContext>(D);
343
344 if (TagDecl *TD = dyn_cast<TagDecl>(D))
345 if (!TD->isFreeStanding())
346 continue;
347
348 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
349 if (CompRes == RangeBefore)
350 continue;
351 if (CompRes == RangeAfter)
352 break;
353
354 assert(CompRes == RangeOverlap);
355 VisitedAtLeastOnce = true;
356
357 if (isa<ObjCContainerDecl>(D)) {
358 FileDI_current = &DIt;
359 FileDE_current = DE;
360 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000361 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000362 }
363
364 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000365 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000366 }
367
368 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000369 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000370
371 // No Decls overlapped with the range. Move up the lexical context until there
372 // is a context that contains the range or we reach the translation unit
373 // level.
374 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
375 : (*(DIt-1))->getLexicalDeclContext();
376
377 while (DC && !DC->isTranslationUnit()) {
378 Decl *D = cast<Decl>(DC);
379 SourceRange CurDeclRange = D->getSourceRange();
380 if (CurDeclRange.isInvalid())
381 break;
382
383 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000384 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
385 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000386 }
387
388 DC = D->getLexicalDeclContext();
389 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000390
391 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000392}
393
394bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
395 if (!AU->getPreprocessor().getPreprocessingRecord())
396 return false;
397
398 PreprocessingRecord &PPRec
399 = *AU->getPreprocessor().getPreprocessingRecord();
400 SourceManager &SM = AU->getSourceManager();
401
402 if (RegionOfInterest.isValid()) {
403 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
404 SourceLocation B = MappedRange.getBegin();
405 SourceLocation E = MappedRange.getEnd();
406
407 if (AU->isInPreambleFileID(B)) {
408 if (SM.isLoadedSourceLocation(E))
409 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
410 PPRec, *this);
411
412 // Beginning of range lies in the preamble but it also extends beyond
413 // it into the main file. Split the range into 2 parts, one covering
414 // the preamble and another covering the main file. This allows subsequent
415 // calls to visitPreprocessedEntitiesInRange to accept a source range that
416 // lies in the same FileID, allowing it to skip preprocessed entities that
417 // do not come from the same FileID.
418 bool breaked =
419 visitPreprocessedEntitiesInRange(
420 SourceRange(B, AU->getEndOfPreambleFileID()),
421 PPRec, *this);
422 if (breaked) return true;
423 return visitPreprocessedEntitiesInRange(
424 SourceRange(AU->getStartOfMainFileID(), E),
425 PPRec, *this);
426 }
427
428 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
429 }
430
431 bool OnlyLocalDecls
432 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
433
434 if (OnlyLocalDecls)
435 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
436 PPRec);
437
438 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
439}
440
441template<typename InputIterator>
442bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
443 InputIterator Last,
444 PreprocessingRecord &PPRec,
445 FileID FID) {
446 for (; First != Last; ++First) {
447 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
448 continue;
449
450 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000451 if (!PPE)
452 continue;
453
Guy Benyei11169dd2012-12-18 14:30:41 +0000454 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
455 if (Visit(MakeMacroExpansionCursor(ME, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
462 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
463 return true;
464
465 continue;
466 }
467
468 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
469 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
470 return true;
471
472 continue;
473 }
474 }
475
476 return false;
477}
478
479/// \brief Visit the children of the given cursor.
480///
481/// \returns true if the visitation should be aborted, false if it
482/// should continue.
483bool CursorVisitor::VisitChildren(CXCursor Cursor) {
484 if (clang_isReference(Cursor.kind) &&
485 Cursor.kind != CXCursor_CXXBaseSpecifier) {
486 // By definition, references have no children.
487 return false;
488 }
489
490 // Set the Parent field to Cursor, then back to its old value once we're
491 // done.
492 SetParentRAII SetParent(Parent, StmtParent, Cursor);
493
494 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000495 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000496 if (!D)
497 return false;
498
499 return VisitAttributes(D) || Visit(D);
500 }
501
502 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(S);
505
506 return false;
507 }
508
509 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000510 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000511 return Visit(E);
512
513 return false;
514 }
515
516 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000517 CXTranslationUnit TU = getCursorTU(Cursor);
518 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000519
520 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
521 for (unsigned I = 0; I != 2; ++I) {
522 if (VisitOrder[I]) {
523 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
524 RegionOfInterest.isInvalid()) {
525 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
526 TLEnd = CXXUnit->top_level_end();
527 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000528 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000529 return true;
530 }
531 } else if (VisitDeclContext(
532 CXXUnit->getASTContext().getTranslationUnitDecl()))
533 return true;
534 continue;
535 }
536
537 // Walk the preprocessing record.
538 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
539 visitPreprocessedEntitiesInRegion();
540 }
541
542 return false;
543 }
544
545 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000546 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
548 return Visit(BaseTSInfo->getTypeLoc());
549 }
550 }
551 }
552
553 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000554 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000555 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000556 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000557 return Visit(cxcursor::MakeCursorObjCClassRef(
558 ObjT->getInterface(),
559 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000560 }
561
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000562 // If pointing inside a macro definition, check if the token is an identifier
563 // that was ever defined as a macro. In such a case, create a "pseudo" macro
564 // expansion cursor for that token.
565 SourceLocation BeginLoc = RegionOfInterest.getBegin();
566 if (Cursor.kind == CXCursor_MacroDefinition &&
567 BeginLoc == RegionOfInterest.getEnd()) {
568 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000569 const MacroInfo *MI =
570 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000571 if (MacroDefinition *MacroDef =
572 checkForMacroInMacroDefinition(MI, Loc, TU))
573 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
574 }
575
Guy Benyei11169dd2012-12-18 14:30:41 +0000576 // Nothing to visit at the moment.
577 return false;
578}
579
580bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
581 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
582 if (Visit(TSInfo->getTypeLoc()))
583 return true;
584
585 if (Stmt *Body = B->getBody())
586 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
587
588 return false;
589}
590
Ted Kremenek03325582013-02-21 01:29:01 +0000591Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000592 if (RegionOfInterest.isValid()) {
593 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
594 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000595 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000596
597 switch (CompareRegionOfInterest(Range)) {
598 case RangeBefore:
599 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000600 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000601
602 case RangeAfter:
603 // This declaration comes after the region of interest; we're done.
604 return false;
605
606 case RangeOverlap:
607 // This declaration overlaps the region of interest; visit it.
608 break;
609 }
610 }
611 return true;
612}
613
614bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
615 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
616
617 // FIXME: Eventually remove. This part of a hack to support proper
618 // iteration over all Decls contained lexically within an ObjC container.
619 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
620 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
621
622 for ( ; I != E; ++I) {
623 Decl *D = *I;
624 if (D->getLexicalDeclContext() != DC)
625 continue;
626 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
627
628 // Ignore synthesized ivars here, otherwise if we have something like:
629 // @synthesize prop = _prop;
630 // and '_prop' is not declared, we will encounter a '_prop' ivar before
631 // encountering the 'prop' synthesize declaration and we will think that
632 // we passed the region-of-interest.
633 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
634 if (ivarD->getSynthesize())
635 continue;
636 }
637
638 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
639 // declarations is a mismatch with the compiler semantics.
640 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
641 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
642 if (!ID->isThisDeclarationADefinition())
643 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
644
645 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
646 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
647 if (!PD->isThisDeclarationADefinition())
648 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
649 }
650
Ted Kremenek03325582013-02-21 01:29:01 +0000651 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000652 if (!V.hasValue())
653 continue;
654 if (!V.getValue())
655 return false;
656 if (Visit(Cursor, true))
657 return true;
658 }
659 return false;
660}
661
662bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
663 llvm_unreachable("Translation units are visited directly by Visit()");
664}
665
666bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
674 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
675 return Visit(TSInfo->getTypeLoc());
676
677 return false;
678}
679
680bool CursorVisitor::VisitTagDecl(TagDecl *D) {
681 return VisitDeclContext(D);
682}
683
684bool CursorVisitor::VisitClassTemplateSpecializationDecl(
685 ClassTemplateSpecializationDecl *D) {
686 bool ShouldVisitBody = false;
687 switch (D->getSpecializationKind()) {
688 case TSK_Undeclared:
689 case TSK_ImplicitInstantiation:
690 // Nothing to visit
691 return false;
692
693 case TSK_ExplicitInstantiationDeclaration:
694 case TSK_ExplicitInstantiationDefinition:
695 break;
696
697 case TSK_ExplicitSpecialization:
698 ShouldVisitBody = true;
699 break;
700 }
701
702 // Visit the template arguments used in the specialization.
703 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
704 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000705 if (TemplateSpecializationTypeLoc TSTLoc =
706 TL.getAs<TemplateSpecializationTypeLoc>()) {
707 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
708 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000709 return true;
710 }
711 }
712
713 if (ShouldVisitBody && VisitCXXRecordDecl(D))
714 return true;
715
716 return false;
717}
718
719bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
720 ClassTemplatePartialSpecializationDecl *D) {
721 // FIXME: Visit the "outer" template parameter lists on the TagDecl
722 // before visiting these template parameters.
723 if (VisitTemplateParameters(D->getTemplateParameters()))
724 return true;
725
726 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000727 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
728 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
729 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000730 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
731 return true;
732
733 return VisitCXXRecordDecl(D);
734}
735
736bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
737 // Visit the default argument.
738 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
739 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
740 if (Visit(DefArg->getTypeLoc()))
741 return true;
742
743 return false;
744}
745
746bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
747 if (Expr *Init = D->getInitExpr())
748 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
749 return false;
750}
751
752bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000753 unsigned NumParamList = DD->getNumTemplateParameterLists();
754 for (unsigned i = 0; i < NumParamList; i++) {
755 TemplateParameterList* Params = DD->getTemplateParameterList(i);
756 if (VisitTemplateParameters(Params))
757 return true;
758 }
759
Guy Benyei11169dd2012-12-18 14:30:41 +0000760 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
761 if (Visit(TSInfo->getTypeLoc()))
762 return true;
763
764 // Visit the nested-name-specifier, if present.
765 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
766 if (VisitNestedNameSpecifierLoc(QualifierLoc))
767 return true;
768
769 return false;
770}
771
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000772/// \brief Compare two base or member initializers based on their source order.
773static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
774 CXXCtorInitializer *const *Y) {
775 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
776}
777
Guy Benyei11169dd2012-12-18 14:30:41 +0000778bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000779 unsigned NumParamList = ND->getNumTemplateParameterLists();
780 for (unsigned i = 0; i < NumParamList; i++) {
781 TemplateParameterList* Params = ND->getTemplateParameterList(i);
782 if (VisitTemplateParameters(Params))
783 return true;
784 }
785
Guy Benyei11169dd2012-12-18 14:30:41 +0000786 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
787 // Visit the function declaration's syntactic components in the order
788 // written. This requires a bit of work.
789 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000790 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000791
792 // If we have a function declared directly (without the use of a typedef),
793 // visit just the return type. Otherwise, just visit the function's type
794 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000795 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000796 (!FTL && Visit(TL)))
797 return true;
798
799 // Visit the nested-name-specifier, if present.
800 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
801 if (VisitNestedNameSpecifierLoc(QualifierLoc))
802 return true;
803
804 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000805 if (!isa<CXXDestructorDecl>(ND))
806 if (VisitDeclarationNameInfo(ND->getNameInfo()))
807 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000808
809 // FIXME: Visit explicitly-specified template arguments!
810
811 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000812 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000813 return true;
814
Bill Wendling44426052012-12-20 19:22:21 +0000815 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000816 }
817
818 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
819 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
820 // Find the initializers that were written in the source.
821 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000822 for (auto *I : Constructor->inits()) {
823 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000824 continue;
825
Aaron Ballman0ad78302014-03-13 17:34:31 +0000826 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000827 }
828
829 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000830 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
831 &CompareCXXCtorInitializers);
832
Guy Benyei11169dd2012-12-18 14:30:41 +0000833 // Visit the initializers in source order
834 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
835 CXXCtorInitializer *Init = WrittenInits[I];
836 if (Init->isAnyMemberInitializer()) {
837 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
838 Init->getMemberLocation(), TU)))
839 return true;
840 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
841 if (Visit(TInfo->getTypeLoc()))
842 return true;
843 }
844
845 // Visit the initializer value.
846 if (Expr *Initializer = Init->getInit())
847 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
848 return true;
849 }
850 }
851
852 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
853 return true;
854 }
855
856 return false;
857}
858
859bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
860 if (VisitDeclaratorDecl(D))
861 return true;
862
863 if (Expr *BitWidth = D->getBitWidth())
864 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
865
866 return false;
867}
868
869bool CursorVisitor::VisitVarDecl(VarDecl *D) {
870 if (VisitDeclaratorDecl(D))
871 return true;
872
873 if (Expr *Init = D->getInit())
874 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
875
876 return false;
877}
878
879bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
880 if (VisitDeclaratorDecl(D))
881 return true;
882
883 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
884 if (Expr *DefArg = D->getDefaultArgument())
885 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
886
887 return false;
888}
889
890bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
891 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
892 // before visiting these template parameters.
893 if (VisitTemplateParameters(D->getTemplateParameters()))
894 return true;
895
896 return VisitFunctionDecl(D->getTemplatedDecl());
897}
898
899bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
900 // FIXME: Visit the "outer" template parameter lists on the TagDecl
901 // before visiting these template parameters.
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 return VisitCXXRecordDecl(D->getTemplatedDecl());
906}
907
908bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
909 if (VisitTemplateParameters(D->getTemplateParameters()))
910 return true;
911
912 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
913 VisitTemplateArgumentLoc(D->getDefaultArgument()))
914 return true;
915
916 return false;
917}
918
919bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000920 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000921 if (Visit(TSInfo->getTypeLoc()))
922 return true;
923
Aaron Ballman43b68be2014-03-07 17:50:17 +0000924 for (const auto *P : ND->params()) {
925 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000926 return true;
927 }
928
929 if (ND->isThisDeclarationADefinition() &&
930 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
931 return true;
932
933 return false;
934}
935
936template <typename DeclIt>
937static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
938 SourceManager &SM, SourceLocation EndLoc,
939 SmallVectorImpl<Decl *> &Decls) {
940 DeclIt next = *DI_current;
941 while (++next != DE_current) {
942 Decl *D_next = *next;
943 if (!D_next)
944 break;
945 SourceLocation L = D_next->getLocStart();
946 if (!L.isValid())
947 break;
948 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
949 *DI_current = next;
950 Decls.push_back(D_next);
951 continue;
952 }
953 break;
954 }
955}
956
Guy Benyei11169dd2012-12-18 14:30:41 +0000957bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
958 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
959 // an @implementation can lexically contain Decls that are not properly
960 // nested in the AST. When we identify such cases, we need to retrofit
961 // this nesting here.
962 if (!DI_current && !FileDI_current)
963 return VisitDeclContext(D);
964
965 // Scan the Decls that immediately come after the container
966 // in the current DeclContext. If any fall within the
967 // container's lexical region, stash them into a vector
968 // for later processing.
969 SmallVector<Decl *, 24> DeclsInContainer;
970 SourceLocation EndLoc = D->getSourceRange().getEnd();
971 SourceManager &SM = AU->getSourceManager();
972 if (EndLoc.isValid()) {
973 if (DI_current) {
974 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
975 DeclsInContainer);
976 } else {
977 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
978 DeclsInContainer);
979 }
980 }
981
982 // The common case.
983 if (DeclsInContainer.empty())
984 return VisitDeclContext(D);
985
986 // Get all the Decls in the DeclContext, and sort them with the
987 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000988 for (auto *SubDecl : D->decls()) {
989 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
990 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000991 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000992 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000993 }
994
995 // Now sort the Decls so that they appear in lexical order.
996 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000997 [&SM](Decl *A, Decl *B) {
998 SourceLocation L_A = A->getLocStart();
999 SourceLocation L_B = B->getLocStart();
1000 assert(L_A.isValid() && L_B.isValid());
1001 return SM.isBeforeInTranslationUnit(L_A, L_B);
1002 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001003
1004 // Now visit the decls.
1005 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1006 E = DeclsInContainer.end(); I != E; ++I) {
1007 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001008 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001009 if (!V.hasValue())
1010 continue;
1011 if (!V.getValue())
1012 return false;
1013 if (Visit(Cursor, true))
1014 return true;
1015 }
1016 return false;
1017}
1018
1019bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1020 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1021 TU)))
1022 return true;
1023
1024 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1025 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1026 E = ND->protocol_end(); I != E; ++I, ++PL)
1027 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1028 return true;
1029
1030 return VisitObjCContainerDecl(ND);
1031}
1032
1033bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1034 if (!PID->isThisDeclarationADefinition())
1035 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1036
1037 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1038 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1039 E = PID->protocol_end(); I != E; ++I, ++PL)
1040 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1041 return true;
1042
1043 return VisitObjCContainerDecl(PID);
1044}
1045
1046bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1047 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1048 return true;
1049
1050 // FIXME: This implements a workaround with @property declarations also being
1051 // installed in the DeclContext for the @interface. Eventually this code
1052 // should be removed.
1053 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1054 if (!CDecl || !CDecl->IsClassExtension())
1055 return false;
1056
1057 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1058 if (!ID)
1059 return false;
1060
1061 IdentifierInfo *PropertyId = PD->getIdentifier();
1062 ObjCPropertyDecl *prevDecl =
1063 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1064
1065 if (!prevDecl)
1066 return false;
1067
1068 // Visit synthesized methods since they will be skipped when visiting
1069 // the @interface.
1070 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1071 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1072 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1073 return true;
1074
1075 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1076 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1077 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1078 return true;
1079
1080 return false;
1081}
1082
1083bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1084 if (!D->isThisDeclarationADefinition()) {
1085 // Forward declaration is treated like a reference.
1086 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1087 }
1088
1089 // Issue callbacks for super class.
1090 if (D->getSuperClass() &&
1091 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1092 D->getSuperClassLoc(),
1093 TU)))
1094 return true;
1095
1096 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1097 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1098 E = D->protocol_end(); I != E; ++I, ++PL)
1099 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1100 return true;
1101
1102 return VisitObjCContainerDecl(D);
1103}
1104
1105bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1106 return VisitObjCContainerDecl(D);
1107}
1108
1109bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1110 // 'ID' could be null when dealing with invalid code.
1111 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1112 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1113 return true;
1114
1115 return VisitObjCImplDecl(D);
1116}
1117
1118bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1119#if 0
1120 // Issue callbacks for super class.
1121 // FIXME: No source location information!
1122 if (D->getSuperClass() &&
1123 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1124 D->getSuperClassLoc(),
1125 TU)))
1126 return true;
1127#endif
1128
1129 return VisitObjCImplDecl(D);
1130}
1131
1132bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1133 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1134 if (PD->isIvarNameSpecified())
1135 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1136
1137 return false;
1138}
1139
1140bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1141 return VisitDeclContext(D);
1142}
1143
1144bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1145 // Visit nested-name-specifier.
1146 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1147 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1148 return true;
1149
1150 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1151 D->getTargetNameLoc(), TU));
1152}
1153
1154bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1155 // Visit nested-name-specifier.
1156 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1157 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1158 return true;
1159 }
1160
1161 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1162 return true;
1163
1164 return VisitDeclarationNameInfo(D->getNameInfo());
1165}
1166
1167bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1168 // Visit nested-name-specifier.
1169 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1170 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1171 return true;
1172
1173 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1174 D->getIdentLocation(), TU));
1175}
1176
1177bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1178 // Visit nested-name-specifier.
1179 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1180 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1181 return true;
1182 }
1183
1184 return VisitDeclarationNameInfo(D->getNameInfo());
1185}
1186
1187bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1188 UnresolvedUsingTypenameDecl *D) {
1189 // Visit nested-name-specifier.
1190 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1191 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1192 return true;
1193
1194 return false;
1195}
1196
1197bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1198 switch (Name.getName().getNameKind()) {
1199 case clang::DeclarationName::Identifier:
1200 case clang::DeclarationName::CXXLiteralOperatorName:
1201 case clang::DeclarationName::CXXOperatorName:
1202 case clang::DeclarationName::CXXUsingDirective:
1203 return false;
1204
1205 case clang::DeclarationName::CXXConstructorName:
1206 case clang::DeclarationName::CXXDestructorName:
1207 case clang::DeclarationName::CXXConversionFunctionName:
1208 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1209 return Visit(TSInfo->getTypeLoc());
1210 return false;
1211
1212 case clang::DeclarationName::ObjCZeroArgSelector:
1213 case clang::DeclarationName::ObjCOneArgSelector:
1214 case clang::DeclarationName::ObjCMultiArgSelector:
1215 // FIXME: Per-identifier location info?
1216 return false;
1217 }
1218
1219 llvm_unreachable("Invalid DeclarationName::Kind!");
1220}
1221
1222bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1223 SourceRange Range) {
1224 // FIXME: This whole routine is a hack to work around the lack of proper
1225 // source information in nested-name-specifiers (PR5791). Since we do have
1226 // a beginning source location, we can visit the first component of the
1227 // nested-name-specifier, if it's a single-token component.
1228 if (!NNS)
1229 return false;
1230
1231 // Get the first component in the nested-name-specifier.
1232 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1233 NNS = Prefix;
1234
1235 switch (NNS->getKind()) {
1236 case NestedNameSpecifier::Namespace:
1237 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1238 TU));
1239
1240 case NestedNameSpecifier::NamespaceAlias:
1241 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1242 Range.getBegin(), TU));
1243
1244 case NestedNameSpecifier::TypeSpec: {
1245 // If the type has a form where we know that the beginning of the source
1246 // range matches up with a reference cursor. Visit the appropriate reference
1247 // cursor.
1248 const Type *T = NNS->getAsType();
1249 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1250 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1251 if (const TagType *Tag = dyn_cast<TagType>(T))
1252 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1253 if (const TemplateSpecializationType *TST
1254 = dyn_cast<TemplateSpecializationType>(T))
1255 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1256 break;
1257 }
1258
1259 case NestedNameSpecifier::TypeSpecWithTemplate:
1260 case NestedNameSpecifier::Global:
1261 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001262 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001263 break;
1264 }
1265
1266 return false;
1267}
1268
1269bool
1270CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1271 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1272 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1273 Qualifiers.push_back(Qualifier);
1274
1275 while (!Qualifiers.empty()) {
1276 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1277 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1278 switch (NNS->getKind()) {
1279 case NestedNameSpecifier::Namespace:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::NamespaceAlias:
1288 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1289 Q.getLocalBeginLoc(),
1290 TU)))
1291 return true;
1292
1293 break;
1294
1295 case NestedNameSpecifier::TypeSpec:
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 if (Visit(Q.getTypeLoc()))
1298 return true;
1299
1300 break;
1301
1302 case NestedNameSpecifier::Global:
1303 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001304 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001305 break;
1306 }
1307 }
1308
1309 return false;
1310}
1311
1312bool CursorVisitor::VisitTemplateParameters(
1313 const TemplateParameterList *Params) {
1314 if (!Params)
1315 return false;
1316
1317 for (TemplateParameterList::const_iterator P = Params->begin(),
1318 PEnd = Params->end();
1319 P != PEnd; ++P) {
1320 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1321 return true;
1322 }
1323
1324 return false;
1325}
1326
1327bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1328 switch (Name.getKind()) {
1329 case TemplateName::Template:
1330 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1331
1332 case TemplateName::OverloadedTemplate:
1333 // Visit the overloaded template set.
1334 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1335 return true;
1336
1337 return false;
1338
1339 case TemplateName::DependentTemplate:
1340 // FIXME: Visit nested-name-specifier.
1341 return false;
1342
1343 case TemplateName::QualifiedTemplate:
1344 // FIXME: Visit nested-name-specifier.
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsQualifiedTemplateName()->getDecl(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParm:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1352 Loc, TU));
1353
1354 case TemplateName::SubstTemplateTemplateParmPack:
1355 return Visit(MakeCursorTemplateRef(
1356 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1357 Loc, TU));
1358 }
1359
1360 llvm_unreachable("Invalid TemplateName::Kind!");
1361}
1362
1363bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1364 switch (TAL.getArgument().getKind()) {
1365 case TemplateArgument::Null:
1366 case TemplateArgument::Integral:
1367 case TemplateArgument::Pack:
1368 return false;
1369
1370 case TemplateArgument::Type:
1371 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1372 return Visit(TSInfo->getTypeLoc());
1373 return false;
1374
1375 case TemplateArgument::Declaration:
1376 if (Expr *E = TAL.getSourceDeclExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::NullPtr:
1381 if (Expr *E = TAL.getSourceNullPtrExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Expression:
1386 if (Expr *E = TAL.getSourceExpression())
1387 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1388 return false;
1389
1390 case TemplateArgument::Template:
1391 case TemplateArgument::TemplateExpansion:
1392 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1393 return true;
1394
1395 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1396 TAL.getTemplateNameLoc());
1397 }
1398
1399 llvm_unreachable("Invalid TemplateArgument::Kind!");
1400}
1401
1402bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1403 return VisitDeclContext(D);
1404}
1405
1406bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1407 return Visit(TL.getUnqualifiedLoc());
1408}
1409
1410bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1411 ASTContext &Context = AU->getASTContext();
1412
1413 // Some builtin types (such as Objective-C's "id", "sel", and
1414 // "Class") have associated declarations. Create cursors for those.
1415 QualType VisitType;
1416 switch (TL.getTypePtr()->getKind()) {
1417
1418 case BuiltinType::Void:
1419 case BuiltinType::NullPtr:
1420 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001421 case BuiltinType::OCLImage1d:
1422 case BuiltinType::OCLImage1dArray:
1423 case BuiltinType::OCLImage1dBuffer:
1424 case BuiltinType::OCLImage2d:
1425 case BuiltinType::OCLImage2dArray:
1426 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001427 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001428 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001429#define BUILTIN_TYPE(Id, SingletonId)
1430#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1434#include "clang/AST/BuiltinTypes.def"
1435 break;
1436
1437 case BuiltinType::ObjCId:
1438 VisitType = Context.getObjCIdType();
1439 break;
1440
1441 case BuiltinType::ObjCClass:
1442 VisitType = Context.getObjCClassType();
1443 break;
1444
1445 case BuiltinType::ObjCSel:
1446 VisitType = Context.getObjCSelType();
1447 break;
1448 }
1449
1450 if (!VisitType.isNull()) {
1451 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1452 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1453 TU));
1454 }
1455
1456 return false;
1457}
1458
1459bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1460 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1468 if (TL.isDefinition())
1469 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1470
1471 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1472}
1473
1474bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1475 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1476}
1477
1478bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1479 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1480 return true;
1481
1482 return false;
1483}
1484
1485bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1486 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1487 return true;
1488
1489 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1490 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1491 TU)))
1492 return true;
1493 }
1494
1495 return false;
1496}
1497
1498bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1499 return Visit(TL.getPointeeLoc());
1500}
1501
1502bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1503 return Visit(TL.getInnerLoc());
1504}
1505
1506bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1507 return Visit(TL.getPointeeLoc());
1508}
1509
1510bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1511 return Visit(TL.getPointeeLoc());
1512}
1513
1514bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1515 return Visit(TL.getPointeeLoc());
1516}
1517
1518bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1519 return Visit(TL.getPointeeLoc());
1520}
1521
1522bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1523 return Visit(TL.getPointeeLoc());
1524}
1525
1526bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1527 return Visit(TL.getModifiedLoc());
1528}
1529
1530bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1531 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001532 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001533 return true;
1534
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001535 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1536 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001537 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1538 return true;
1539
1540 return false;
1541}
1542
1543bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1544 if (Visit(TL.getElementLoc()))
1545 return true;
1546
1547 if (Expr *Size = TL.getSizeExpr())
1548 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1549
1550 return false;
1551}
1552
Reid Kleckner8a365022013-06-24 17:51:48 +00001553bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1554 return Visit(TL.getOriginalLoc());
1555}
1556
Reid Kleckner0503a872013-12-05 01:23:43 +00001557bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1558 return Visit(TL.getOriginalLoc());
1559}
1560
Guy Benyei11169dd2012-12-18 14:30:41 +00001561bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1562 TemplateSpecializationTypeLoc TL) {
1563 // Visit the template name.
1564 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1565 TL.getTemplateNameLoc()))
1566 return true;
1567
1568 // Visit the template arguments.
1569 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1570 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1571 return true;
1572
1573 return false;
1574}
1575
1576bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1577 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1578}
1579
1580bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1581 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1582 return Visit(TSInfo->getTypeLoc());
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1588 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1589 return Visit(TSInfo->getTypeLoc());
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1595 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1596 return true;
1597
1598 return false;
1599}
1600
1601bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1602 DependentTemplateSpecializationTypeLoc TL) {
1603 // Visit the nested-name-specifier, if there is one.
1604 if (TL.getQualifierLoc() &&
1605 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1606 return true;
1607
1608 // Visit the template arguments.
1609 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1610 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1611 return true;
1612
1613 return false;
1614}
1615
1616bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1617 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1618 return true;
1619
1620 return Visit(TL.getNamedTypeLoc());
1621}
1622
1623bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1624 return Visit(TL.getPatternLoc());
1625}
1626
1627bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1628 if (Expr *E = TL.getUnderlyingExpr())
1629 return Visit(MakeCXCursor(E, StmtParent, TU));
1630
1631 return false;
1632}
1633
1634bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1635 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1636}
1637
1638bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1639 return Visit(TL.getValueLoc());
1640}
1641
1642#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1643bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1644 return Visit##PARENT##Loc(TL); \
1645}
1646
1647DEFAULT_TYPELOC_IMPL(Complex, Type)
1648DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1652DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1653DEFAULT_TYPELOC_IMPL(Vector, Type)
1654DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1655DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1656DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1657DEFAULT_TYPELOC_IMPL(Record, TagType)
1658DEFAULT_TYPELOC_IMPL(Enum, TagType)
1659DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1660DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1661DEFAULT_TYPELOC_IMPL(Auto, Type)
1662
1663bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1664 // Visit the nested-name-specifier, if present.
1665 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1666 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1667 return true;
1668
1669 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001670 for (const auto &I : D->bases()) {
1671 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001672 return true;
1673 }
1674 }
1675
1676 return VisitTagDecl(D);
1677}
1678
1679bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001680 for (const auto *I : D->attrs())
1681 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001682 return true;
1683
1684 return false;
1685}
1686
1687//===----------------------------------------------------------------------===//
1688// Data-recursive visitor methods.
1689//===----------------------------------------------------------------------===//
1690
1691namespace {
1692#define DEF_JOB(NAME, DATA, KIND)\
1693class NAME : public VisitorJob {\
1694public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001695 NAME(const DATA *d, CXCursor parent) : \
1696 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001697 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001698 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001699};
1700
1701DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1702DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1703DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1704DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1705DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1706 ExplicitTemplateArgsVisitKind)
1707DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1708DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1709DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1710#undef DEF_JOB
1711
1712class DeclVisit : public VisitorJob {
1713public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001714 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001715 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001716 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001717 static bool classof(const VisitorJob *VJ) {
1718 return VJ->getKind() == DeclVisitKind;
1719 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001720 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001721 bool isFirst() const { return data[1] ? true : false; }
1722};
1723class TypeLocVisit : public VisitorJob {
1724public:
1725 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1726 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1727 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1728
1729 static bool classof(const VisitorJob *VJ) {
1730 return VJ->getKind() == TypeLocVisitKind;
1731 }
1732
1733 TypeLoc get() const {
1734 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001735 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001736 }
1737};
1738
1739class LabelRefVisit : public VisitorJob {
1740public:
1741 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1742 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1743 labelLoc.getPtrEncoding()) {}
1744
1745 static bool classof(const VisitorJob *VJ) {
1746 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1747 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 const LabelDecl *get() const {
1749 return static_cast<const LabelDecl *>(data[0]);
1750 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001751 SourceLocation getLoc() const {
1752 return SourceLocation::getFromPtrEncoding(data[1]); }
1753};
1754
1755class NestedNameSpecifierLocVisit : public VisitorJob {
1756public:
1757 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1758 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1759 Qualifier.getNestedNameSpecifier(),
1760 Qualifier.getOpaqueData()) { }
1761
1762 static bool classof(const VisitorJob *VJ) {
1763 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1764 }
1765
1766 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 return NestedNameSpecifierLoc(
1768 const_cast<NestedNameSpecifier *>(
1769 static_cast<const NestedNameSpecifier *>(data[0])),
1770 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001771 }
1772};
1773
1774class DeclarationNameInfoVisit : public VisitorJob {
1775public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001776 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001777 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 static bool classof(const VisitorJob *VJ) {
1779 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1780 }
1781 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001782 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001783 switch (S->getStmtClass()) {
1784 default:
1785 llvm_unreachable("Unhandled Stmt");
1786 case clang::Stmt::MSDependentExistsStmtClass:
1787 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1788 case Stmt::CXXDependentScopeMemberExprClass:
1789 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1790 case Stmt::DependentScopeDeclRefExprClass:
1791 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001792 case Stmt::OMPCriticalDirectiveClass:
1793 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001794 }
1795 }
1796};
1797class MemberRefVisit : public VisitorJob {
1798public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001799 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1801 L.getPtrEncoding()) {}
1802 static bool classof(const VisitorJob *VJ) {
1803 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1804 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001805 const FieldDecl *get() const {
1806 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001807 }
1808 SourceLocation getLoc() const {
1809 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1810 }
1811};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001812class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001813 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001814 VisitorWorkList &WL;
1815 CXCursor Parent;
1816public:
1817 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1818 : WL(wl), Parent(parent) {}
1819
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001820 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1821 void VisitBlockExpr(const BlockExpr *B);
1822 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1823 void VisitCompoundStmt(const CompoundStmt *S);
1824 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1825 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1826 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1827 void VisitCXXNewExpr(const CXXNewExpr *E);
1828 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1829 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1830 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1831 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1832 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1833 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1834 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1835 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001836 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001837 void VisitDeclRefExpr(const DeclRefExpr *D);
1838 void VisitDeclStmt(const DeclStmt *S);
1839 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1840 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1841 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1842 void VisitForStmt(const ForStmt *FS);
1843 void VisitGotoStmt(const GotoStmt *GS);
1844 void VisitIfStmt(const IfStmt *If);
1845 void VisitInitListExpr(const InitListExpr *IE);
1846 void VisitMemberExpr(const MemberExpr *M);
1847 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1848 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1849 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1850 void VisitOverloadExpr(const OverloadExpr *E);
1851 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1852 void VisitStmt(const Stmt *S);
1853 void VisitSwitchStmt(const SwitchStmt *S);
1854 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1856 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1857 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1858 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1859 void VisitVAArgExpr(const VAArgExpr *E);
1860 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1861 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1862 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1863 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001865 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001867 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001868 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001869 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001870 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001871 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001872 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001873 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001874 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001875 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001876 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001877 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001878 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001879 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001880 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001881 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001882 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001883 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001884 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001885 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001886 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887
Guy Benyei11169dd2012-12-18 14:30:41 +00001888private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1891 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1893 void AddStmt(const Stmt *S);
1894 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001897 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001898};
1899} // end anonyous namespace
1900
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 // 'S' should always be non-null, since it comes from the
1903 // statement we are visiting.
1904 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1905}
1906
1907void
1908EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1909 if (Qualifier)
1910 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1911}
1912
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 if (S)
1915 WL.push_back(StmtVisit(S, Parent));
1916}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001918 if (D)
1919 WL.push_back(DeclVisit(D, Parent, isFirst));
1920}
1921void EnqueueVisitor::
1922 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1923 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001924 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001925}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001926void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001927 if (D)
1928 WL.push_back(MemberRefVisit(D, L, Parent));
1929}
1930void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1931 if (TI)
1932 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1933 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001934void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001935 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001936 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 AddStmt(*Child);
1938 }
1939 if (size == WL.size())
1940 return;
1941 // Now reverse the entries we just added. This will match the DFS
1942 // ordering performed by the worklist.
1943 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1944 std::reverse(I, E);
1945}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946namespace {
1947class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1948 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001949 /// \brief Process clauses with list of variables.
1950 template <typename T>
1951 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001952public:
1953 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1954#define OPENMP_CLAUSE(Name, Class) \
1955 void Visit##Class(const Class *C);
1956#include "clang/Basic/OpenMPKinds.def"
1957};
1958
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001959void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1960 Visitor->AddStmt(C->getCondition());
1961}
1962
Alexey Bataev3778b602014-07-17 07:32:53 +00001963void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1964 Visitor->AddStmt(C->getCondition());
1965}
1966
Alexey Bataev568a8332014-03-06 06:15:19 +00001967void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1968 Visitor->AddStmt(C->getNumThreads());
1969}
1970
Alexey Bataev62c87d22014-03-21 04:51:18 +00001971void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1972 Visitor->AddStmt(C->getSafelen());
1973}
1974
Alexander Musman8bd31e62014-05-27 15:12:19 +00001975void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1976 Visitor->AddStmt(C->getNumForLoops());
1977}
1978
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001979void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001980
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001981void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1982
Alexey Bataev56dafe82014-06-20 07:16:17 +00001983void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1984 Visitor->AddStmt(C->getChunkSize());
1985}
1986
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001987void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1988
Alexey Bataev236070f2014-06-20 11:19:47 +00001989void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1990
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001991void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1992
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001993void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1994
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001995void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1996
Alexey Bataevdea47612014-07-23 07:46:59 +00001997void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1998
Alexey Bataev67a4f222014-07-23 10:25:33 +00001999void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2000
Alexey Bataev459dec02014-07-24 06:46:57 +00002001void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2002
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002003void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2004
Alexey Bataev756c1962013-09-24 03:17:45 +00002005template<typename T>
2006void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002007 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002008 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002009 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002010}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002011
2012void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002013 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002014 for (const auto *E : C->private_copies()) {
2015 Visitor->AddStmt(E);
2016 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002017}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002018void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2019 const OMPFirstprivateClause *C) {
2020 VisitOMPClauseList(C);
2021}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002022void OMPClauseEnqueue::VisitOMPLastprivateClause(
2023 const OMPLastprivateClause *C) {
2024 VisitOMPClauseList(C);
2025}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002026void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002027 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002028}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002029void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2030 VisitOMPClauseList(C);
2031}
Alexander Musman8dba6642014-04-22 13:09:42 +00002032void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2033 VisitOMPClauseList(C);
2034 Visitor->AddStmt(C->getStep());
2035}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002036void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2037 VisitOMPClauseList(C);
2038 Visitor->AddStmt(C->getAlignment());
2039}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002040void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2041 VisitOMPClauseList(C);
2042}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002043void
2044OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2045 VisitOMPClauseList(C);
2046}
Alexey Bataev6125da92014-07-21 11:26:11 +00002047void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2048 VisitOMPClauseList(C);
2049}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002050}
Alexey Bataev756c1962013-09-24 03:17:45 +00002051
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002052void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2053 unsigned size = WL.size();
2054 OMPClauseEnqueue Visitor(this);
2055 Visitor.Visit(S);
2056 if (size == WL.size())
2057 return;
2058 // Now reverse the entries we just added. This will match the DFS
2059 // ordering performed by the worklist.
2060 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2061 std::reverse(I, E);
2062}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002063void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002064 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2065}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 AddDecl(B->getBlockDecl());
2068}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 EnqueueChildren(E);
2071 AddTypeLoc(E->getTypeSourceInfo());
2072}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2074 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002075 E = S->body_rend(); I != E; ++I) {
2076 AddStmt(*I);
2077 }
2078}
2079void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 AddStmt(S->getSubStmt());
2082 AddDeclarationNameInfo(S);
2083 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2084 AddNestedNameSpecifierLoc(QualifierLoc);
2085}
2086
2087void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2090 AddDeclarationNameInfo(E);
2091 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2092 AddNestedNameSpecifierLoc(QualifierLoc);
2093 if (!E->isImplicitAccess())
2094 AddStmt(E->getBase());
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 // Enqueue the initializer , if any.
2098 AddStmt(E->getInitializer());
2099 // Enqueue the array size, if any.
2100 AddStmt(E->getArraySize());
2101 // Enqueue the allocated type.
2102 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2103 // Enqueue the placement arguments.
2104 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2105 AddStmt(E->getPlacementArg(I-1));
2106}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002108 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2109 AddStmt(CE->getArg(I-1));
2110 AddStmt(CE->getCallee());
2111 AddStmt(CE->getArg(0));
2112}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002113void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2114 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002115 // Visit the name of the type being destroyed.
2116 AddTypeLoc(E->getDestroyedTypeInfo());
2117 // Visit the scope type that looks disturbingly like the nested-name-specifier
2118 // but isn't.
2119 AddTypeLoc(E->getScopeTypeInfo());
2120 // Visit the nested-name-specifier.
2121 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2122 AddNestedNameSpecifierLoc(QualifierLoc);
2123 // Visit base expression.
2124 AddStmt(E->getBase());
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2127 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 AddTypeLoc(E->getTypeSourceInfo());
2129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2131 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 EnqueueChildren(E);
2133 AddTypeLoc(E->getTypeSourceInfo());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 EnqueueChildren(E);
2137 if (E->isTypeOperand())
2138 AddTypeLoc(E->getTypeOperandSourceInfo());
2139}
2140
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2142 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 EnqueueChildren(E);
2144 AddTypeLoc(E->getTypeSourceInfo());
2145}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 EnqueueChildren(E);
2148 if (E->isTypeOperand())
2149 AddTypeLoc(E->getTypeOperandSourceInfo());
2150}
2151
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 EnqueueChildren(S);
2154 AddDecl(S->getExceptionDecl());
2155}
2156
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002157void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002158 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002159 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002160 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002161}
2162
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 if (DR->hasExplicitTemplateArgs()) {
2165 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2166 }
2167 WL.push_back(DeclRefExprParts(DR, Parent));
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2170 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002171 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2172 AddDeclarationNameInfo(E);
2173 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 unsigned size = WL.size();
2177 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002178 for (const auto *D : S->decls()) {
2179 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 isFirst = false;
2181 }
2182 if (size == WL.size())
2183 return;
2184 // Now reverse the entries we just added. This will match the DFS
2185 // ordering performed by the worklist.
2186 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2187 std::reverse(I, E);
2188}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 D = E->designators_rbegin(), DEnd = E->designators_rend();
2193 D != DEnd; ++D) {
2194 if (D->isFieldDesignator()) {
2195 if (FieldDecl *Field = D->getField())
2196 AddMemberRef(Field, D->getFieldLoc());
2197 continue;
2198 }
2199 if (D->isArrayDesignator()) {
2200 AddStmt(E->getArrayIndex(*D));
2201 continue;
2202 }
2203 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2204 AddStmt(E->getArrayRangeEnd(*D));
2205 AddStmt(E->getArrayRangeStart(*D));
2206 }
2207}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 EnqueueChildren(E);
2210 AddTypeLoc(E->getTypeInfoAsWritten());
2211}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 AddStmt(FS->getBody());
2214 AddStmt(FS->getInc());
2215 AddStmt(FS->getCond());
2216 AddDecl(FS->getConditionVariable());
2217 AddStmt(FS->getInit());
2218}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 AddStmt(If->getElse());
2224 AddStmt(If->getThen());
2225 AddStmt(If->getCond());
2226 AddDecl(If->getConditionVariable());
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 // We care about the syntactic form of the initializer list, only.
2230 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2231 IE = Syntactic;
2232 EnqueueChildren(IE);
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 WL.push_back(MemberExprParts(M, Parent));
2236
2237 // If the base of the member access expression is an implicit 'this', don't
2238 // visit it.
2239 // FIXME: If we ever want to show these implicit accesses, this will be
2240 // unfortunate. However, clang_getCursor() relies on this behavior.
2241 if (!M->isImplicitAccess())
2242 AddStmt(M->getBase());
2243}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 AddTypeLoc(E->getEncodedTypeSourceInfo());
2246}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 EnqueueChildren(M);
2249 AddTypeLoc(M->getClassReceiverTypeInfo());
2250}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 // Visit the components of the offsetof expression.
2253 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2254 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2255 const OffsetOfNode &Node = E->getComponent(I-1);
2256 switch (Node.getKind()) {
2257 case OffsetOfNode::Array:
2258 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2259 break;
2260 case OffsetOfNode::Field:
2261 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2262 break;
2263 case OffsetOfNode::Identifier:
2264 case OffsetOfNode::Base:
2265 continue;
2266 }
2267 }
2268 // Visit the type into which we're computing the offset.
2269 AddTypeLoc(E->getTypeSourceInfo());
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2273 WL.push_back(OverloadExprParts(E, Parent));
2274}
2275void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 EnqueueChildren(E);
2278 if (E->isArgumentType())
2279 AddTypeLoc(E->getArgumentTypeInfo());
2280}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002281void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002282 EnqueueChildren(S);
2283}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 AddStmt(S->getBody());
2286 AddStmt(S->getCond());
2287 AddDecl(S->getConditionVariable());
2288}
2289
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 AddStmt(W->getBody());
2292 AddStmt(W->getCond());
2293 AddDecl(W->getConditionVariable());
2294}
2295
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002296void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002297 for (unsigned I = E->getNumArgs(); I > 0; --I)
2298 AddTypeLoc(E->getArg(I-1));
2299}
2300
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002301void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002302 AddTypeLoc(E->getQueriedTypeSourceInfo());
2303}
2304
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002305void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002306 EnqueueChildren(E);
2307}
2308
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 VisitOverloadExpr(U);
2311 if (!U->isImplicitAccess())
2312 AddStmt(U->getBase());
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 AddStmt(E->getSubExpr());
2316 AddTypeLoc(E->getWrittenTypeInfo());
2317}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002319 WL.push_back(SizeOfPackExprParts(E, Parent));
2320}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002321void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002322 // If the opaque value has a source expression, just transparently
2323 // visit that. This is useful for (e.g.) pseudo-object expressions.
2324 if (Expr *SourceExpr = E->getSourceExpr())
2325 return Visit(SourceExpr);
2326}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002327void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002328 AddStmt(E->getBody());
2329 WL.push_back(LambdaExprParts(E, Parent));
2330}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 // Treat the expression like its syntactic form.
2333 Visit(E->getSyntacticForm());
2334}
2335
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002336void EnqueueVisitor::VisitOMPExecutableDirective(
2337 const OMPExecutableDirective *D) {
2338 EnqueueChildren(D);
2339 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2340 E = D->clauses().end();
2341 I != E; ++I)
2342 EnqueueChildren(*I);
2343}
2344
Alexander Musman3aaab662014-08-19 11:27:13 +00002345void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2346 VisitOMPExecutableDirective(D);
2347}
2348
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002349void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2350 VisitOMPExecutableDirective(D);
2351}
2352
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002353void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002354 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002355}
2356
Alexey Bataevf29276e2014-06-18 04:14:57 +00002357void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002358 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002359}
2360
Alexander Musmanf82886e2014-09-18 05:12:34 +00002361void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2362 VisitOMPLoopDirective(D);
2363}
2364
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002365void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2366 VisitOMPExecutableDirective(D);
2367}
2368
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002369void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2370 VisitOMPExecutableDirective(D);
2371}
2372
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002373void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2374 VisitOMPExecutableDirective(D);
2375}
2376
Alexander Musman80c22892014-07-17 08:54:58 +00002377void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2378 VisitOMPExecutableDirective(D);
2379}
2380
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002381void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2382 VisitOMPExecutableDirective(D);
2383 AddDeclarationNameInfo(D);
2384}
2385
Alexey Bataev4acb8592014-07-07 13:01:15 +00002386void
2387EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002388 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002389}
2390
Alexander Musmane4e893b2014-09-23 09:33:00 +00002391void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2392 const OMPParallelForSimdDirective *D) {
2393 VisitOMPLoopDirective(D);
2394}
2395
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002396void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2397 const OMPParallelSectionsDirective *D) {
2398 VisitOMPExecutableDirective(D);
2399}
2400
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002401void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2402 VisitOMPExecutableDirective(D);
2403}
2404
Alexey Bataev68446b72014-07-18 07:47:19 +00002405void
2406EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2407 VisitOMPExecutableDirective(D);
2408}
2409
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002410void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2411 VisitOMPExecutableDirective(D);
2412}
2413
Alexey Bataev2df347a2014-07-18 10:17:07 +00002414void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2415 VisitOMPExecutableDirective(D);
2416}
2417
Alexey Bataev6125da92014-07-21 11:26:11 +00002418void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2419 VisitOMPExecutableDirective(D);
2420}
2421
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002422void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2423 VisitOMPExecutableDirective(D);
2424}
2425
Alexey Bataev0162e452014-07-22 10:10:35 +00002426void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2427 VisitOMPExecutableDirective(D);
2428}
2429
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002430void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2431 VisitOMPExecutableDirective(D);
2432}
2433
Alexey Bataev13314bf2014-10-09 04:18:56 +00002434void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2435 VisitOMPExecutableDirective(D);
2436}
2437
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2440}
2441
2442bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2443 if (RegionOfInterest.isValid()) {
2444 SourceRange Range = getRawCursorExtent(C);
2445 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2446 return false;
2447 }
2448 return true;
2449}
2450
2451bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2452 while (!WL.empty()) {
2453 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002454 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002455
2456 // Set the Parent field, then back to its old value once we're done.
2457 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2458
2459 switch (LI.getKind()) {
2460 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002461 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002462 if (!D)
2463 continue;
2464
2465 // For now, perform default visitation for Decls.
2466 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2467 cast<DeclVisit>(&LI)->isFirst())))
2468 return true;
2469
2470 continue;
2471 }
2472 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2473 const ASTTemplateArgumentListInfo *ArgList =
2474 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2475 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2476 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2477 Arg != ArgEnd; ++Arg) {
2478 if (VisitTemplateArgumentLoc(*Arg))
2479 return true;
2480 }
2481 continue;
2482 }
2483 case VisitorJob::TypeLocVisitKind: {
2484 // Perform default visitation for TypeLocs.
2485 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2486 return true;
2487 continue;
2488 }
2489 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002490 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002491 if (LabelStmt *stmt = LS->getStmt()) {
2492 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2493 TU))) {
2494 return true;
2495 }
2496 }
2497 continue;
2498 }
2499
2500 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2501 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2502 if (VisitNestedNameSpecifierLoc(V->get()))
2503 return true;
2504 continue;
2505 }
2506
2507 case VisitorJob::DeclarationNameInfoVisitKind: {
2508 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2509 ->get()))
2510 return true;
2511 continue;
2512 }
2513 case VisitorJob::MemberRefVisitKind: {
2514 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2515 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2516 return true;
2517 continue;
2518 }
2519 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002520 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002521 if (!S)
2522 continue;
2523
2524 // Update the current cursor.
2525 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2526 if (!IsInRegionOfInterest(Cursor))
2527 continue;
2528 switch (Visitor(Cursor, Parent, ClientData)) {
2529 case CXChildVisit_Break: return true;
2530 case CXChildVisit_Continue: break;
2531 case CXChildVisit_Recurse:
2532 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002533 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002534 EnqueueWorkList(WL, S);
2535 break;
2536 }
2537 continue;
2538 }
2539 case VisitorJob::MemberExprPartsKind: {
2540 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002541 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002542
2543 // Visit the nested-name-specifier
2544 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2545 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2546 return true;
2547
2548 // Visit the declaration name.
2549 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2550 return true;
2551
2552 // Visit the explicitly-specified template arguments, if any.
2553 if (M->hasExplicitTemplateArgs()) {
2554 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2555 *ArgEnd = Arg + M->getNumTemplateArgs();
2556 Arg != ArgEnd; ++Arg) {
2557 if (VisitTemplateArgumentLoc(*Arg))
2558 return true;
2559 }
2560 }
2561 continue;
2562 }
2563 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002564 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002565 // Visit nested-name-specifier, if present.
2566 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2567 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2568 return true;
2569 // Visit declaration name.
2570 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2571 return true;
2572 continue;
2573 }
2574 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002575 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002576 // Visit the nested-name-specifier.
2577 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2578 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2579 return true;
2580 // Visit the declaration name.
2581 if (VisitDeclarationNameInfo(O->getNameInfo()))
2582 return true;
2583 // Visit the overloaded declaration reference.
2584 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2585 return true;
2586 continue;
2587 }
2588 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002589 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002590 NamedDecl *Pack = E->getPack();
2591 if (isa<TemplateTypeParmDecl>(Pack)) {
2592 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2593 E->getPackLoc(), TU)))
2594 return true;
2595
2596 continue;
2597 }
2598
2599 if (isa<TemplateTemplateParmDecl>(Pack)) {
2600 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2601 E->getPackLoc(), TU)))
2602 return true;
2603
2604 continue;
2605 }
2606
2607 // Non-type template parameter packs and function parameter packs are
2608 // treated like DeclRefExpr cursors.
2609 continue;
2610 }
2611
2612 case VisitorJob::LambdaExprPartsKind: {
2613 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002614 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002615 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2616 CEnd = E->explicit_capture_end();
2617 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002618 // FIXME: Lambda init-captures.
2619 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002620 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002621
Guy Benyei11169dd2012-12-18 14:30:41 +00002622 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2623 C->getLocation(),
2624 TU)))
2625 return true;
2626 }
2627
2628 // Visit parameters and return type, if present.
2629 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2630 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2631 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2632 // Visit the whole type.
2633 if (Visit(TL))
2634 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002635 } else if (FunctionProtoTypeLoc Proto =
2636 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002637 if (E->hasExplicitParameters()) {
2638 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002639 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2640 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002641 return true;
2642 } else {
2643 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002644 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002645 return true;
2646 }
2647 }
2648 }
2649 break;
2650 }
2651
2652 case VisitorJob::PostChildrenVisitKind:
2653 if (PostChildrenVisitor(Parent, ClientData))
2654 return true;
2655 break;
2656 }
2657 }
2658 return false;
2659}
2660
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002661bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002662 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002663 if (!WorkListFreeList.empty()) {
2664 WL = WorkListFreeList.back();
2665 WL->clear();
2666 WorkListFreeList.pop_back();
2667 }
2668 else {
2669 WL = new VisitorWorkList();
2670 WorkListCache.push_back(WL);
2671 }
2672 EnqueueWorkList(*WL, S);
2673 bool result = RunVisitorWorkList(*WL);
2674 WorkListFreeList.push_back(WL);
2675 return result;
2676}
2677
2678namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002679typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002680RefNamePieces
2681buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2682 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2683 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002684 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2685 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2686 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2687
2688 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2689
2690 RefNamePieces Pieces;
2691
2692 if (WantQualifier && QLoc.isValid())
2693 Pieces.push_back(QLoc);
2694
2695 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2696 Pieces.push_back(NI.getLoc());
2697
2698 if (WantTemplateArgs && TemplateArgs)
2699 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2700 TemplateArgs->RAngleLoc));
2701
2702 if (Kind == DeclarationName::CXXOperatorName) {
2703 Pieces.push_back(SourceLocation::getFromRawEncoding(
2704 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2705 Pieces.push_back(SourceLocation::getFromRawEncoding(
2706 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2707 }
2708
2709 if (WantSinglePiece) {
2710 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2711 Pieces.clear();
2712 Pieces.push_back(R);
2713 }
2714
2715 return Pieces;
2716}
2717}
2718
2719//===----------------------------------------------------------------------===//
2720// Misc. API hooks.
2721//===----------------------------------------------------------------------===//
2722
Chad Rosier05c71aa2013-03-27 18:28:23 +00002723static void fatal_error_handler(void *user_data, const std::string& reason,
2724 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002725 // Write the result out to stderr avoiding errs() because raw_ostreams can
2726 // call report_fatal_error.
2727 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2728 ::abort();
2729}
2730
Chandler Carruth66660742014-06-27 16:37:27 +00002731namespace {
2732struct RegisterFatalErrorHandler {
2733 RegisterFatalErrorHandler() {
2734 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2735 }
2736};
2737}
2738
2739static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2740
Guy Benyei11169dd2012-12-18 14:30:41 +00002741extern "C" {
2742CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2743 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002744 // We use crash recovery to make some of our APIs more reliable, implicitly
2745 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002746 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2747 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002748
Chandler Carruth66660742014-06-27 16:37:27 +00002749 // Look through the managed static to trigger construction of the managed
2750 // static which registers our fatal error handler. This ensures it is only
2751 // registered once.
2752 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002753
2754 CIndexer *CIdxr = new CIndexer();
2755 if (excludeDeclarationsFromPCH)
2756 CIdxr->setOnlyLocalDecls();
2757 if (displayDiagnostics)
2758 CIdxr->setDisplayDiagnostics();
2759
2760 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2761 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2762 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2763 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2764 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2765 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2766
2767 return CIdxr;
2768}
2769
2770void clang_disposeIndex(CXIndex CIdx) {
2771 if (CIdx)
2772 delete static_cast<CIndexer *>(CIdx);
2773}
2774
2775void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2776 if (CIdx)
2777 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2778}
2779
2780unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2781 if (CIdx)
2782 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2783 return 0;
2784}
2785
2786void clang_toggleCrashRecovery(unsigned isEnabled) {
2787 if (isEnabled)
2788 llvm::CrashRecoveryContext::Enable();
2789 else
2790 llvm::CrashRecoveryContext::Disable();
2791}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002792
Guy Benyei11169dd2012-12-18 14:30:41 +00002793CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2794 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002795 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002796 enum CXErrorCode Result =
2797 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002798 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002799 assert((TU && Result == CXError_Success) ||
2800 (!TU && Result != CXError_Success));
2801 return TU;
2802}
2803
2804enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2805 const char *ast_filename,
2806 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002807 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002808 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002809
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002810 if (!CIdx || !ast_filename || !out_TU)
2811 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002812
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002813 LOG_FUNC_SECTION {
2814 *Log << ast_filename;
2815 }
2816
Guy Benyei11169dd2012-12-18 14:30:41 +00002817 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2818 FileSystemOptions FileSystemOpts;
2819
Justin Bognerd512c1e2014-10-15 00:33:06 +00002820 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2821 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002822 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2823 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2824 /*CaptureDiagnostics=*/true,
2825 /*AllowPCHWithCompilerErrors=*/true,
2826 /*UserFilesAreVolatile=*/true);
2827 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002828 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002829}
2830
2831unsigned clang_defaultEditingTranslationUnitOptions() {
2832 return CXTranslationUnit_PrecompiledPreamble |
2833 CXTranslationUnit_CacheCompletionResults;
2834}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002835
Guy Benyei11169dd2012-12-18 14:30:41 +00002836CXTranslationUnit
2837clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2838 const char *source_filename,
2839 int num_command_line_args,
2840 const char * const *command_line_args,
2841 unsigned num_unsaved_files,
2842 struct CXUnsavedFile *unsaved_files) {
2843 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2844 return clang_parseTranslationUnit(CIdx, source_filename,
2845 command_line_args, num_command_line_args,
2846 unsaved_files, num_unsaved_files,
2847 Options);
2848}
2849
2850struct ParseTranslationUnitInfo {
2851 CXIndex CIdx;
2852 const char *source_filename;
2853 const char *const *command_line_args;
2854 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002855 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002857 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002858 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002859};
2860static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002861 const ParseTranslationUnitInfo *PTUI =
2862 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002863 CXIndex CIdx = PTUI->CIdx;
2864 const char *source_filename = PTUI->source_filename;
2865 const char * const *command_line_args = PTUI->command_line_args;
2866 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002867 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002868 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002869
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002870 // Set up the initial return values.
2871 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002872 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002873
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002874 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002875 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002876 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002877 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002878 }
2879
Guy Benyei11169dd2012-12-18 14:30:41 +00002880 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2881
2882 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2883 setThreadBackgroundPriority();
2884
2885 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2886 // FIXME: Add a flag for modules.
2887 TranslationUnitKind TUKind
2888 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002889 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002890 = options & CXTranslationUnit_CacheCompletionResults;
2891 bool IncludeBriefCommentsInCodeCompletion
2892 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2893 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2894 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2895
2896 // Configure the diagnostics.
2897 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002898 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002899
2900 // Recover resources if we crash before exiting this function.
2901 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2902 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002903 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002904
Ahmed Charlesb8984322014-03-07 20:03:18 +00002905 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2906 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002907
2908 // Recover resources if we crash before exiting this function.
2909 llvm::CrashRecoveryContextCleanupRegistrar<
2910 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2911
Alp Toker9d85b182014-07-07 01:23:14 +00002912 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002913 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002914 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002915 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002916 }
2917
Ahmed Charlesb8984322014-03-07 20:03:18 +00002918 std::unique_ptr<std::vector<const char *>> Args(
2919 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002920
2921 // Recover resources if we crash before exiting this method.
2922 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2923 ArgsCleanup(Args.get());
2924
2925 // Since the Clang C library is primarily used by batch tools dealing with
2926 // (often very broken) source code, where spell-checking can have a
2927 // significant negative impact on performance (particularly when
2928 // precompiled headers are involved), we disable it by default.
2929 // Only do this if we haven't found a spell-checking-related argument.
2930 bool FoundSpellCheckingArgument = false;
2931 for (int I = 0; I != num_command_line_args; ++I) {
2932 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2933 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2934 FoundSpellCheckingArgument = true;
2935 break;
2936 }
2937 }
2938 if (!FoundSpellCheckingArgument)
2939 Args->push_back("-fno-spell-checking");
2940
2941 Args->insert(Args->end(), command_line_args,
2942 command_line_args + num_command_line_args);
2943
2944 // The 'source_filename' argument is optional. If the caller does not
2945 // specify it then it is assumed that the source file is specified
2946 // in the actual argument list.
2947 // Put the source file after command_line_args otherwise if '-x' flag is
2948 // present it will be unused.
2949 if (source_filename)
2950 Args->push_back(source_filename);
2951
2952 // Do we need the detailed preprocessing record?
2953 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2954 Args->push_back("-Xclang");
2955 Args->push_back("-detailed-preprocessing-record");
2956 }
2957
2958 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002959 std::unique_ptr<ASTUnit> ErrUnit;
2960 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002961 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002962 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2963 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2964 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2965 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2966 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2967 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002968
2969 if (NumErrors != Diags->getClient()->getNumErrors()) {
2970 // Make sure to check that 'Unit' is non-NULL.
2971 if (CXXIdx->getDisplayDiagnostics())
2972 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2973 }
2974
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002975 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2976 PTUI->result = CXError_ASTReadError;
2977 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002978 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002979 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2980 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002981}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002982
2983CXTranslationUnit
2984clang_parseTranslationUnit(CXIndex CIdx,
2985 const char *source_filename,
2986 const char *const *command_line_args,
2987 int num_command_line_args,
2988 struct CXUnsavedFile *unsaved_files,
2989 unsigned num_unsaved_files,
2990 unsigned options) {
2991 CXTranslationUnit TU;
2992 enum CXErrorCode Result = clang_parseTranslationUnit2(
2993 CIdx, source_filename, command_line_args, num_command_line_args,
2994 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002995 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002996 assert((TU && Result == CXError_Success) ||
2997 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998 return TU;
2999}
3000
3001enum CXErrorCode clang_parseTranslationUnit2(
3002 CXIndex CIdx,
3003 const char *source_filename,
3004 const char *const *command_line_args,
3005 int num_command_line_args,
3006 struct CXUnsavedFile *unsaved_files,
3007 unsigned num_unsaved_files,
3008 unsigned options,
3009 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003010 LOG_FUNC_SECTION {
3011 *Log << source_filename << ": ";
3012 for (int i = 0; i != num_command_line_args; ++i)
3013 *Log << command_line_args[i] << " ";
3014 }
3015
Alp Toker9d85b182014-07-07 01:23:14 +00003016 if (num_unsaved_files && !unsaved_files)
3017 return CXError_InvalidArguments;
3018
Alp Toker5c532982014-07-07 22:42:03 +00003019 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003020 ParseTranslationUnitInfo PTUI = {
3021 CIdx,
3022 source_filename,
3023 command_line_args,
3024 num_command_line_args,
3025 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3026 options,
3027 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003028 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003029 llvm::CrashRecoveryContext CRC;
3030
3031 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3032 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3033 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3034 fprintf(stderr, " 'command_line_args' : [");
3035 for (int i = 0; i != num_command_line_args; ++i) {
3036 if (i)
3037 fprintf(stderr, ", ");
3038 fprintf(stderr, "'%s'", command_line_args[i]);
3039 }
3040 fprintf(stderr, "],\n");
3041 fprintf(stderr, " 'unsaved_files' : [");
3042 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3043 if (i)
3044 fprintf(stderr, ", ");
3045 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3046 unsaved_files[i].Length);
3047 }
3048 fprintf(stderr, "],\n");
3049 fprintf(stderr, " 'options' : %d,\n", options);
3050 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003051
3052 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003053 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003054 if (CXTranslationUnit *TU = PTUI.out_TU)
3055 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003056 }
Alp Toker5c532982014-07-07 22:42:03 +00003057
3058 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003059}
3060
3061unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3062 return CXSaveTranslationUnit_None;
3063}
3064
3065namespace {
3066
3067struct SaveTranslationUnitInfo {
3068 CXTranslationUnit TU;
3069 const char *FileName;
3070 unsigned options;
3071 CXSaveError result;
3072};
3073
3074}
3075
3076static void clang_saveTranslationUnit_Impl(void *UserData) {
3077 SaveTranslationUnitInfo *STUI =
3078 static_cast<SaveTranslationUnitInfo*>(UserData);
3079
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003080 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003081 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3082 setThreadBackgroundPriority();
3083
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003084 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003085 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3086}
3087
3088int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3089 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003090 LOG_FUNC_SECTION {
3091 *Log << TU << ' ' << FileName;
3092 }
3093
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003094 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003095 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003096 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003097 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003098
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003099 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003100 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3101 if (!CXXUnit->hasSema())
3102 return CXSaveError_InvalidTU;
3103
3104 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3105
3106 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3107 getenv("LIBCLANG_NOTHREADS")) {
3108 clang_saveTranslationUnit_Impl(&STUI);
3109
3110 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3111 PrintLibclangResourceUsage(TU);
3112
3113 return STUI.result;
3114 }
3115
3116 // We have an AST that has invalid nodes due to compiler errors.
3117 // Use a crash recovery thread for protection.
3118
3119 llvm::CrashRecoveryContext CRC;
3120
3121 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3122 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3123 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3124 fprintf(stderr, " 'options' : %d,\n", options);
3125 fprintf(stderr, "}\n");
3126
3127 return CXSaveError_Unknown;
3128
3129 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3130 PrintLibclangResourceUsage(TU);
3131 }
3132
3133 return STUI.result;
3134}
3135
3136void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3137 if (CTUnit) {
3138 // If the translation unit has been marked as unsafe to free, just discard
3139 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003140 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3141 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003142 return;
3143
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003144 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003145 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003146 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3147 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003148 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 delete CTUnit;
3150 }
3151}
3152
3153unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3154 return CXReparse_None;
3155}
3156
3157struct ReparseTranslationUnitInfo {
3158 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003159 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003160 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003161 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003162};
3163
3164static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003165 const ReparseTranslationUnitInfo *RTUI =
3166 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003168 unsigned options = RTUI->options;
3169 (void) options;
3170
3171 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003172 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003173 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003174 RTUI->result = CXError_InvalidArguments;
3175 return;
3176 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003177
3178 // Reset the associated diagnostics.
3179 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003180 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003181
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003182 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3184 setThreadBackgroundPriority();
3185
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003186 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003188
3189 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3190 new std::vector<ASTUnit::RemappedFile>());
3191
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 // Recover resources if we crash before exiting this function.
3193 llvm::CrashRecoveryContextCleanupRegistrar<
3194 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003195
3196 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003197 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003198 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003199 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003201
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003202 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003203 RTUI->result = CXError_Success;
3204 else if (isASTReadError(CXXUnit))
3205 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003206}
3207
3208int clang_reparseTranslationUnit(CXTranslationUnit TU,
3209 unsigned num_unsaved_files,
3210 struct CXUnsavedFile *unsaved_files,
3211 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003212 LOG_FUNC_SECTION {
3213 *Log << TU;
3214 }
3215
Alp Toker9d85b182014-07-07 01:23:14 +00003216 if (num_unsaved_files && !unsaved_files)
3217 return CXError_InvalidArguments;
3218
Alp Toker5c532982014-07-07 22:42:03 +00003219 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003220 ReparseTranslationUnitInfo RTUI = {
3221 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003222 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003223
3224 if (getenv("LIBCLANG_NOTHREADS")) {
3225 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003226 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 }
3228
3229 llvm::CrashRecoveryContext CRC;
3230
3231 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3232 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003233 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003234 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3236 PrintLibclangResourceUsage(TU);
3237
Alp Toker5c532982014-07-07 22:42:03 +00003238 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003239}
3240
3241
3242CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003243 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003244 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003245 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003246 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003247
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003248 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003249 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003250}
3251
3252CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003253 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003254 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003255 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003256 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003257
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003258 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3260}
3261
3262} // end: extern "C"
3263
3264//===----------------------------------------------------------------------===//
3265// CXFile Operations.
3266//===----------------------------------------------------------------------===//
3267
3268extern "C" {
3269CXString clang_getFileName(CXFile SFile) {
3270 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003271 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003272
3273 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003274 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003275}
3276
3277time_t clang_getFileTime(CXFile SFile) {
3278 if (!SFile)
3279 return 0;
3280
3281 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3282 return FEnt->getModificationTime();
3283}
3284
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003285CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003286 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003287 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003288 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003289 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003290
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003291 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003292
3293 FileManager &FMgr = CXXUnit->getFileManager();
3294 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3295}
3296
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003297unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3298 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003299 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003300 LOG_BAD_TU(TU);
3301 return 0;
3302 }
3303
3304 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 return 0;
3306
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003307 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 FileEntry *FEnt = static_cast<FileEntry *>(file);
3309 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3310 .isFileMultipleIncludeGuarded(FEnt);
3311}
3312
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003313int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3314 if (!file || !outID)
3315 return 1;
3316
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003317 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003318 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3319 outID->data[0] = ID.getDevice();
3320 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003321 outID->data[2] = FEnt->getModificationTime();
3322 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003323}
3324
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003325int clang_File_isEqual(CXFile file1, CXFile file2) {
3326 if (file1 == file2)
3327 return true;
3328
3329 if (!file1 || !file2)
3330 return false;
3331
3332 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3333 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3334 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3335}
3336
Guy Benyei11169dd2012-12-18 14:30:41 +00003337} // end: extern "C"
3338
3339//===----------------------------------------------------------------------===//
3340// CXCursor Operations.
3341//===----------------------------------------------------------------------===//
3342
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003343static const Decl *getDeclFromExpr(const Stmt *E) {
3344 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 return getDeclFromExpr(CE->getSubExpr());
3346
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003347 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003349 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003351 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003353 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 if (PRE->isExplicitProperty())
3355 return PRE->getExplicitProperty();
3356 // It could be messaging both getter and setter as in:
3357 // ++myobj.myprop;
3358 // in which case prefer to associate the setter since it is less obvious
3359 // from inspecting the source that the setter is going to get called.
3360 if (PRE->isMessagingSetter())
3361 return PRE->getImplicitPropertySetter();
3362 return PRE->getImplicitPropertyGetter();
3363 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003364 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003366 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 if (Expr *Src = OVE->getSourceExpr())
3368 return getDeclFromExpr(Src);
3369
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003370 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003372 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 if (!CE->isElidable())
3374 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003375 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 return OME->getMethodDecl();
3377
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003378 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003380 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3382 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003383 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3385 isa<ParmVarDecl>(SizeOfPack->getPack()))
3386 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003387
3388 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003389}
3390
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003391static SourceLocation getLocationFromExpr(const Expr *E) {
3392 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 return getLocationFromExpr(CE->getSubExpr());
3394
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003395 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003397 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003398 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003399 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003401 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003402 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003403 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003405 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003406 return PropRef->getLocation();
3407
3408 return E->getLocStart();
3409}
3410
3411extern "C" {
3412
3413unsigned clang_visitChildren(CXCursor parent,
3414 CXCursorVisitor visitor,
3415 CXClientData client_data) {
3416 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3417 /*VisitPreprocessorLast=*/false);
3418 return CursorVis.VisitChildren(parent);
3419}
3420
3421#ifndef __has_feature
3422#define __has_feature(x) 0
3423#endif
3424#if __has_feature(blocks)
3425typedef enum CXChildVisitResult
3426 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3427
3428static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3429 CXClientData client_data) {
3430 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3431 return block(cursor, parent);
3432}
3433#else
3434// If we are compiled with a compiler that doesn't have native blocks support,
3435// define and call the block manually, so the
3436typedef struct _CXChildVisitResult
3437{
3438 void *isa;
3439 int flags;
3440 int reserved;
3441 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3442 CXCursor);
3443} *CXCursorVisitorBlock;
3444
3445static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3446 CXClientData client_data) {
3447 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3448 return block->invoke(block, cursor, parent);
3449}
3450#endif
3451
3452
3453unsigned clang_visitChildrenWithBlock(CXCursor parent,
3454 CXCursorVisitorBlock block) {
3455 return clang_visitChildren(parent, visitWithBlock, block);
3456}
3457
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003458static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003460 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003461
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003462 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003464 if (const ObjCPropertyImplDecl *PropImpl =
3465 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003467 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003468
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003469 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003471 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003472
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003473 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 }
3475
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003476 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003477 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003478
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003479 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3481 // and returns different names. NamedDecl returns the class name and
3482 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003483 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003484
3485 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003486 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003487
3488 SmallString<1024> S;
3489 llvm::raw_svector_ostream os(S);
3490 ND->printName(os);
3491
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003492 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003493}
3494
3495CXString clang_getCursorSpelling(CXCursor C) {
3496 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003497 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003498
3499 if (clang_isReference(C.kind)) {
3500 switch (C.kind) {
3501 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003502 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003503 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 }
3505 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003506 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003507 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 }
3509 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003510 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003512 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003513 }
3514 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003515 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003516 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 }
3518 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003519 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 assert(Type && "Missing type decl");
3521
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003522 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 getAsString());
3524 }
3525 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003526 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 assert(Template && "Missing template decl");
3528
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003529 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 }
3531
3532 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003533 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 assert(NS && "Missing namespace decl");
3535
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003536 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 }
3538
3539 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003540 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 assert(Field && "Missing member decl");
3542
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003543 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 }
3545
3546 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003547 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 assert(Label && "Missing label");
3549
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003550 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 }
3552
3553 case CXCursor_OverloadedDeclRef: {
3554 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003555 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3556 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003557 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003558 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003560 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003561 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 OverloadedTemplateStorage *Ovl
3563 = Storage.get<OverloadedTemplateStorage*>();
3564 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003565 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003566 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 }
3568
3569 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003570 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 assert(Var && "Missing variable decl");
3572
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003573 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 }
3575
3576 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003577 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 }
3579 }
3580
3581 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003582 const Expr *E = getCursorExpr(C);
3583
3584 if (C.kind == CXCursor_ObjCStringLiteral ||
3585 C.kind == CXCursor_StringLiteral) {
3586 const StringLiteral *SLit;
3587 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3588 SLit = OSL->getString();
3589 } else {
3590 SLit = cast<StringLiteral>(E);
3591 }
3592 SmallString<256> Buf;
3593 llvm::raw_svector_ostream OS(Buf);
3594 SLit->outputString(OS);
3595 return cxstring::createDup(OS.str());
3596 }
3597
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003598 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 if (D)
3600 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003601 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 }
3603
3604 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003605 const Stmt *S = getCursorStmt(C);
3606 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003607 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003608
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003609 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 }
3611
3612 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003613 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 ->getNameStart());
3615
3616 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003617 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 ->getNameStart());
3619
3620 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003621 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003622
3623 if (clang_isDeclaration(C.kind))
3624 return getDeclSpelling(getCursorDecl(C));
3625
3626 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003627 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003628 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 }
3630
3631 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003632 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003633 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 }
3635
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003636 if (C.kind == CXCursor_PackedAttr) {
3637 return cxstring::createRef("packed");
3638 }
3639
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003640 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003641}
3642
3643CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3644 unsigned pieceIndex,
3645 unsigned options) {
3646 if (clang_Cursor_isNull(C))
3647 return clang_getNullRange();
3648
3649 ASTContext &Ctx = getCursorContext(C);
3650
3651 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003652 const Stmt *S = getCursorStmt(C);
3653 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 if (pieceIndex > 0)
3655 return clang_getNullRange();
3656 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3657 }
3658
3659 return clang_getNullRange();
3660 }
3661
3662 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003663 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3665 if (pieceIndex >= ME->getNumSelectorLocs())
3666 return clang_getNullRange();
3667 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3668 }
3669 }
3670
3671 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3672 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003673 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3675 if (pieceIndex >= MD->getNumSelectorLocs())
3676 return clang_getNullRange();
3677 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3678 }
3679 }
3680
3681 if (C.kind == CXCursor_ObjCCategoryDecl ||
3682 C.kind == CXCursor_ObjCCategoryImplDecl) {
3683 if (pieceIndex > 0)
3684 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003685 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3687 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003688 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3690 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3691 }
3692
3693 if (C.kind == CXCursor_ModuleImportDecl) {
3694 if (pieceIndex > 0)
3695 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003696 if (const ImportDecl *ImportD =
3697 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3699 if (!Locs.empty())
3700 return cxloc::translateSourceRange(Ctx,
3701 SourceRange(Locs.front(), Locs.back()));
3702 }
3703 return clang_getNullRange();
3704 }
3705
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003706 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3707 C.kind == CXCursor_ConversionFunction) {
3708 if (pieceIndex > 0)
3709 return clang_getNullRange();
3710 if (const FunctionDecl *FD =
3711 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3712 DeclarationNameInfo FunctionName = FD->getNameInfo();
3713 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3714 }
3715 return clang_getNullRange();
3716 }
3717
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 // FIXME: A CXCursor_InclusionDirective should give the location of the
3719 // filename, but we don't keep track of this.
3720
3721 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3722 // but we don't keep track of this.
3723
3724 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3725 // but we don't keep track of this.
3726
3727 // Default handling, give the location of the cursor.
3728
3729 if (pieceIndex > 0)
3730 return clang_getNullRange();
3731
3732 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3733 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3734 return cxloc::translateSourceRange(Ctx, Loc);
3735}
3736
Eli Bendersky44a206f2014-07-31 18:04:56 +00003737CXString clang_Cursor_getMangling(CXCursor C) {
3738 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3739 return cxstring::createEmpty();
3740
Eli Bendersky44a206f2014-07-31 18:04:56 +00003741 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003742 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003743 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3744 return cxstring::createEmpty();
3745
Eli Bendersky79759592014-08-01 15:01:10 +00003746 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003747 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003748 ASTContext &Ctx = ND->getASTContext();
3749 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003750
Eli Bendersky79759592014-08-01 15:01:10 +00003751 std::string FrontendBuf;
3752 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3753 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003754
Eli Bendersky79759592014-08-01 15:01:10 +00003755 // Now apply backend mangling.
3756 std::unique_ptr<llvm::DataLayout> DL(
3757 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3758 llvm::Mangler BackendMangler(DL.get());
3759
3760 std::string FinalBuf;
3761 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3762 BackendMangler.getNameWithPrefix(FinalBufOS,
3763 llvm::Twine(FrontendBufOS.str()));
3764
3765 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003766}
3767
Guy Benyei11169dd2012-12-18 14:30:41 +00003768CXString clang_getCursorDisplayName(CXCursor C) {
3769 if (!clang_isDeclaration(C.kind))
3770 return clang_getCursorSpelling(C);
3771
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003772 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003774 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003775
3776 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003777 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 D = FunTmpl->getTemplatedDecl();
3779
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003780 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 SmallString<64> Str;
3782 llvm::raw_svector_ostream OS(Str);
3783 OS << *Function;
3784 if (Function->getPrimaryTemplate())
3785 OS << "<>";
3786 OS << "(";
3787 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3788 if (I)
3789 OS << ", ";
3790 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3791 }
3792
3793 if (Function->isVariadic()) {
3794 if (Function->getNumParams())
3795 OS << ", ";
3796 OS << "...";
3797 }
3798 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003799 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 }
3801
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003802 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 SmallString<64> Str;
3804 llvm::raw_svector_ostream OS(Str);
3805 OS << *ClassTemplate;
3806 OS << "<";
3807 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3808 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3809 if (I)
3810 OS << ", ";
3811
3812 NamedDecl *Param = Params->getParam(I);
3813 if (Param->getIdentifier()) {
3814 OS << Param->getIdentifier()->getName();
3815 continue;
3816 }
3817
3818 // There is no parameter name, which makes this tricky. Try to come up
3819 // with something useful that isn't too long.
3820 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3821 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3822 else if (NonTypeTemplateParmDecl *NTTP
3823 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3824 OS << NTTP->getType().getAsString(Policy);
3825 else
3826 OS << "template<...> class";
3827 }
3828
3829 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003830 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 }
3832
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003833 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3835 // If the type was explicitly written, use that.
3836 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003837 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003838
Benjamin Kramer9170e912013-02-22 15:46:01 +00003839 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 llvm::raw_svector_ostream OS(Str);
3841 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003842 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 ClassSpec->getTemplateArgs().data(),
3844 ClassSpec->getTemplateArgs().size(),
3845 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003846 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 }
3848
3849 return clang_getCursorSpelling(C);
3850}
3851
3852CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3853 switch (Kind) {
3854 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003982 case CXCursor_ObjCSelfExpr:
3983 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004072 case CXCursor_SEHLeaveStmt:
4073 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004102 case CXCursor_PackedAttr:
4103 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004104 case CXCursor_PureAttr:
4105 return cxstring::createRef("attribute(pure)");
4106 case CXCursor_ConstAttr:
4107 return cxstring::createRef("attribute(const)");
4108 case CXCursor_NoDuplicateAttr:
4109 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004110 case CXCursor_CUDAConstantAttr:
4111 return cxstring::createRef("attribute(constant)");
4112 case CXCursor_CUDADeviceAttr:
4113 return cxstring::createRef("attribute(device)");
4114 case CXCursor_CUDAGlobalAttr:
4115 return cxstring::createRef("attribute(global)");
4116 case CXCursor_CUDAHostAttr:
4117 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004118 case CXCursor_CUDASharedAttr:
4119 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004168 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004169 return cxstring::createRef("OMPParallelDirective");
4170 case CXCursor_OMPSimdDirective:
4171 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004172 case CXCursor_OMPForDirective:
4173 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004174 case CXCursor_OMPForSimdDirective:
4175 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004176 case CXCursor_OMPSectionsDirective:
4177 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004178 case CXCursor_OMPSectionDirective:
4179 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004180 case CXCursor_OMPSingleDirective:
4181 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004182 case CXCursor_OMPMasterDirective:
4183 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004184 case CXCursor_OMPCriticalDirective:
4185 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004186 case CXCursor_OMPParallelForDirective:
4187 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004188 case CXCursor_OMPParallelForSimdDirective:
4189 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004190 case CXCursor_OMPParallelSectionsDirective:
4191 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004192 case CXCursor_OMPTaskDirective:
4193 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004194 case CXCursor_OMPTaskyieldDirective:
4195 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004196 case CXCursor_OMPBarrierDirective:
4197 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004198 case CXCursor_OMPTaskwaitDirective:
4199 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004200 case CXCursor_OMPFlushDirective:
4201 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004202 case CXCursor_OMPOrderedDirective:
4203 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004204 case CXCursor_OMPAtomicDirective:
4205 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004206 case CXCursor_OMPTargetDirective:
4207 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004208 case CXCursor_OMPTeamsDirective:
4209 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004210 case CXCursor_OverloadCandidate:
4211 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 }
4213
4214 llvm_unreachable("Unhandled CXCursorKind");
4215}
4216
4217struct GetCursorData {
4218 SourceLocation TokenBeginLoc;
4219 bool PointsAtMacroArgExpansion;
4220 bool VisitedObjCPropertyImplDecl;
4221 SourceLocation VisitedDeclaratorDeclStartLoc;
4222 CXCursor &BestCursor;
4223
4224 GetCursorData(SourceManager &SM,
4225 SourceLocation tokenBegin, CXCursor &outputCursor)
4226 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4227 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4228 VisitedObjCPropertyImplDecl = false;
4229 }
4230};
4231
4232static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4233 CXCursor parent,
4234 CXClientData client_data) {
4235 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4236 CXCursor *BestCursor = &Data->BestCursor;
4237
4238 // If we point inside a macro argument we should provide info of what the
4239 // token is so use the actual cursor, don't replace it with a macro expansion
4240 // cursor.
4241 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4242 return CXChildVisit_Recurse;
4243
4244 if (clang_isDeclaration(cursor.kind)) {
4245 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004246 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4248 if (MD->isImplicit())
4249 return CXChildVisit_Break;
4250
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004251 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4253 // Check that when we have multiple @class references in the same line,
4254 // that later ones do not override the previous ones.
4255 // If we have:
4256 // @class Foo, Bar;
4257 // source ranges for both start at '@', so 'Bar' will end up overriding
4258 // 'Foo' even though the cursor location was at 'Foo'.
4259 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4260 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004261 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4263 if (PrevID != ID &&
4264 !PrevID->isThisDeclarationADefinition() &&
4265 !ID->isThisDeclarationADefinition())
4266 return CXChildVisit_Break;
4267 }
4268
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004269 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4271 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4272 // Check that when we have multiple declarators in the same line,
4273 // that later ones do not override the previous ones.
4274 // If we have:
4275 // int Foo, Bar;
4276 // source ranges for both start at 'int', so 'Bar' will end up overriding
4277 // 'Foo' even though the cursor location was at 'Foo'.
4278 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4279 return CXChildVisit_Break;
4280 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4281
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004282 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4284 (void)PropImp;
4285 // Check that when we have multiple @synthesize in the same line,
4286 // that later ones do not override the previous ones.
4287 // If we have:
4288 // @synthesize Foo, Bar;
4289 // source ranges for both start at '@', so 'Bar' will end up overriding
4290 // 'Foo' even though the cursor location was at 'Foo'.
4291 if (Data->VisitedObjCPropertyImplDecl)
4292 return CXChildVisit_Break;
4293 Data->VisitedObjCPropertyImplDecl = true;
4294 }
4295 }
4296
4297 if (clang_isExpression(cursor.kind) &&
4298 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004299 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 // Avoid having the cursor of an expression replace the declaration cursor
4301 // when the expression source range overlaps the declaration range.
4302 // This can happen for C++ constructor expressions whose range generally
4303 // include the variable declaration, e.g.:
4304 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4305 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4306 D->getLocation() == Data->TokenBeginLoc)
4307 return CXChildVisit_Break;
4308 }
4309 }
4310
4311 // If our current best cursor is the construction of a temporary object,
4312 // don't replace that cursor with a type reference, because we want
4313 // clang_getCursor() to point at the constructor.
4314 if (clang_isExpression(BestCursor->kind) &&
4315 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4316 cursor.kind == CXCursor_TypeRef) {
4317 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4318 // as having the actual point on the type reference.
4319 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4320 return CXChildVisit_Recurse;
4321 }
4322
4323 *BestCursor = cursor;
4324 return CXChildVisit_Recurse;
4325}
4326
4327CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004328 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004329 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004331 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004332
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004333 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4335
4336 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4337 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4338
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004339 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 CXFile SearchFile;
4341 unsigned SearchLine, SearchColumn;
4342 CXFile ResultFile;
4343 unsigned ResultLine, ResultColumn;
4344 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4345 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4346 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004347
4348 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4349 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004350 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004351 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 SearchFileName = clang_getFileName(SearchFile);
4353 ResultFileName = clang_getFileName(ResultFile);
4354 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4355 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004356 *Log << llvm::format("(%s:%d:%d) = %s",
4357 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4358 clang_getCString(KindSpelling))
4359 << llvm::format("(%s:%d:%d):%s%s",
4360 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4361 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 clang_disposeString(SearchFileName);
4363 clang_disposeString(ResultFileName);
4364 clang_disposeString(KindSpelling);
4365 clang_disposeString(USR);
4366
4367 CXCursor Definition = clang_getCursorDefinition(Result);
4368 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4369 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4370 CXString DefinitionKindSpelling
4371 = clang_getCursorKindSpelling(Definition.kind);
4372 CXFile DefinitionFile;
4373 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004374 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004375 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004377 *Log << llvm::format(" -> %s(%s:%d:%d)",
4378 clang_getCString(DefinitionKindSpelling),
4379 clang_getCString(DefinitionFileName),
4380 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004381 clang_disposeString(DefinitionFileName);
4382 clang_disposeString(DefinitionKindSpelling);
4383 }
4384 }
4385
4386 return Result;
4387}
4388
4389CXCursor clang_getNullCursor(void) {
4390 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4391}
4392
4393unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004394 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4395 // can't set consistently. For example, when visiting a DeclStmt we will set
4396 // it but we don't set it on the result of clang_getCursorDefinition for
4397 // a reference of the same declaration.
4398 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4399 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4400 // to provide that kind of info.
4401 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004402 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004403 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004404 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004405
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 return X == Y;
4407}
4408
4409unsigned clang_hashCursor(CXCursor C) {
4410 unsigned Index = 0;
4411 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4412 Index = 1;
4413
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004414 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 std::make_pair(C.kind, C.data[Index]));
4416}
4417
4418unsigned clang_isInvalid(enum CXCursorKind K) {
4419 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4420}
4421
4422unsigned clang_isDeclaration(enum CXCursorKind K) {
4423 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4424 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4425}
4426
4427unsigned clang_isReference(enum CXCursorKind K) {
4428 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4429}
4430
4431unsigned clang_isExpression(enum CXCursorKind K) {
4432 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4433}
4434
4435unsigned clang_isStatement(enum CXCursorKind K) {
4436 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4437}
4438
4439unsigned clang_isAttribute(enum CXCursorKind K) {
4440 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4441}
4442
4443unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4444 return K == CXCursor_TranslationUnit;
4445}
4446
4447unsigned clang_isPreprocessing(enum CXCursorKind K) {
4448 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4449}
4450
4451unsigned clang_isUnexposed(enum CXCursorKind K) {
4452 switch (K) {
4453 case CXCursor_UnexposedDecl:
4454 case CXCursor_UnexposedExpr:
4455 case CXCursor_UnexposedStmt:
4456 case CXCursor_UnexposedAttr:
4457 return true;
4458 default:
4459 return false;
4460 }
4461}
4462
4463CXCursorKind clang_getCursorKind(CXCursor C) {
4464 return C.kind;
4465}
4466
4467CXSourceLocation clang_getCursorLocation(CXCursor C) {
4468 if (clang_isReference(C.kind)) {
4469 switch (C.kind) {
4470 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004471 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 = getCursorObjCSuperClassRef(C);
4473 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4474 }
4475
4476 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004477 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004478 = getCursorObjCProtocolRef(C);
4479 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4480 }
4481
4482 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004483 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 = getCursorObjCClassRef(C);
4485 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4486 }
4487
4488 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004489 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4491 }
4492
4493 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004494 std::pair<const TemplateDecl *, SourceLocation> P =
4495 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4497 }
4498
4499 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004500 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4502 }
4503
4504 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004505 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4507 }
4508
4509 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004510 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4512 }
4513
4514 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004515 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 if (!BaseSpec)
4517 return clang_getNullLocation();
4518
4519 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4520 return cxloc::translateSourceLocation(getCursorContext(C),
4521 TSInfo->getTypeLoc().getBeginLoc());
4522
4523 return cxloc::translateSourceLocation(getCursorContext(C),
4524 BaseSpec->getLocStart());
4525 }
4526
4527 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004528 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4530 }
4531
4532 case CXCursor_OverloadedDeclRef:
4533 return cxloc::translateSourceLocation(getCursorContext(C),
4534 getCursorOverloadedDeclRef(C).second);
4535
4536 default:
4537 // FIXME: Need a way to enumerate all non-reference cases.
4538 llvm_unreachable("Missed a reference kind");
4539 }
4540 }
4541
4542 if (clang_isExpression(C.kind))
4543 return cxloc::translateSourceLocation(getCursorContext(C),
4544 getLocationFromExpr(getCursorExpr(C)));
4545
4546 if (clang_isStatement(C.kind))
4547 return cxloc::translateSourceLocation(getCursorContext(C),
4548 getCursorStmt(C)->getLocStart());
4549
4550 if (C.kind == CXCursor_PreprocessingDirective) {
4551 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4552 return cxloc::translateSourceLocation(getCursorContext(C), L);
4553 }
4554
4555 if (C.kind == CXCursor_MacroExpansion) {
4556 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004557 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 return cxloc::translateSourceLocation(getCursorContext(C), L);
4559 }
4560
4561 if (C.kind == CXCursor_MacroDefinition) {
4562 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4563 return cxloc::translateSourceLocation(getCursorContext(C), L);
4564 }
4565
4566 if (C.kind == CXCursor_InclusionDirective) {
4567 SourceLocation L
4568 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4569 return cxloc::translateSourceLocation(getCursorContext(C), L);
4570 }
4571
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004572 if (clang_isAttribute(C.kind)) {
4573 SourceLocation L
4574 = cxcursor::getCursorAttr(C)->getLocation();
4575 return cxloc::translateSourceLocation(getCursorContext(C), L);
4576 }
4577
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 if (!clang_isDeclaration(C.kind))
4579 return clang_getNullLocation();
4580
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004581 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 if (!D)
4583 return clang_getNullLocation();
4584
4585 SourceLocation Loc = D->getLocation();
4586 // FIXME: Multiple variables declared in a single declaration
4587 // currently lack the information needed to correctly determine their
4588 // ranges when accounting for the type-specifier. We use context
4589 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4590 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004591 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 if (!cxcursor::isFirstInDeclGroup(C))
4593 Loc = VD->getLocation();
4594 }
4595
4596 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004597 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 Loc = MD->getSelectorStartLoc();
4599
4600 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4601}
4602
4603} // end extern "C"
4604
4605CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4606 assert(TU);
4607
4608 // Guard against an invalid SourceLocation, or we may assert in one
4609 // of the following calls.
4610 if (SLoc.isInvalid())
4611 return clang_getNullCursor();
4612
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004613 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004614
4615 // Translate the given source location to make it point at the beginning of
4616 // the token under the cursor.
4617 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4618 CXXUnit->getASTContext().getLangOpts());
4619
4620 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4621 if (SLoc.isValid()) {
4622 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4623 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4624 /*VisitPreprocessorLast=*/true,
4625 /*VisitIncludedEntities=*/false,
4626 SourceLocation(SLoc));
4627 CursorVis.visitFileRegion();
4628 }
4629
4630 return Result;
4631}
4632
4633static SourceRange getRawCursorExtent(CXCursor C) {
4634 if (clang_isReference(C.kind)) {
4635 switch (C.kind) {
4636 case CXCursor_ObjCSuperClassRef:
4637 return getCursorObjCSuperClassRef(C).second;
4638
4639 case CXCursor_ObjCProtocolRef:
4640 return getCursorObjCProtocolRef(C).second;
4641
4642 case CXCursor_ObjCClassRef:
4643 return getCursorObjCClassRef(C).second;
4644
4645 case CXCursor_TypeRef:
4646 return getCursorTypeRef(C).second;
4647
4648 case CXCursor_TemplateRef:
4649 return getCursorTemplateRef(C).second;
4650
4651 case CXCursor_NamespaceRef:
4652 return getCursorNamespaceRef(C).second;
4653
4654 case CXCursor_MemberRef:
4655 return getCursorMemberRef(C).second;
4656
4657 case CXCursor_CXXBaseSpecifier:
4658 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4659
4660 case CXCursor_LabelRef:
4661 return getCursorLabelRef(C).second;
4662
4663 case CXCursor_OverloadedDeclRef:
4664 return getCursorOverloadedDeclRef(C).second;
4665
4666 case CXCursor_VariableRef:
4667 return getCursorVariableRef(C).second;
4668
4669 default:
4670 // FIXME: Need a way to enumerate all non-reference cases.
4671 llvm_unreachable("Missed a reference kind");
4672 }
4673 }
4674
4675 if (clang_isExpression(C.kind))
4676 return getCursorExpr(C)->getSourceRange();
4677
4678 if (clang_isStatement(C.kind))
4679 return getCursorStmt(C)->getSourceRange();
4680
4681 if (clang_isAttribute(C.kind))
4682 return getCursorAttr(C)->getRange();
4683
4684 if (C.kind == CXCursor_PreprocessingDirective)
4685 return cxcursor::getCursorPreprocessingDirective(C);
4686
4687 if (C.kind == CXCursor_MacroExpansion) {
4688 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004689 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 return TU->mapRangeFromPreamble(Range);
4691 }
4692
4693 if (C.kind == CXCursor_MacroDefinition) {
4694 ASTUnit *TU = getCursorASTUnit(C);
4695 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4696 return TU->mapRangeFromPreamble(Range);
4697 }
4698
4699 if (C.kind == CXCursor_InclusionDirective) {
4700 ASTUnit *TU = getCursorASTUnit(C);
4701 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4702 return TU->mapRangeFromPreamble(Range);
4703 }
4704
4705 if (C.kind == CXCursor_TranslationUnit) {
4706 ASTUnit *TU = getCursorASTUnit(C);
4707 FileID MainID = TU->getSourceManager().getMainFileID();
4708 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4709 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4710 return SourceRange(Start, End);
4711 }
4712
4713 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004714 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 if (!D)
4716 return SourceRange();
4717
4718 SourceRange R = D->getSourceRange();
4719 // FIXME: Multiple variables declared in a single declaration
4720 // currently lack the information needed to correctly determine their
4721 // ranges when accounting for the type-specifier. We use context
4722 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4723 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004724 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 if (!cxcursor::isFirstInDeclGroup(C))
4726 R.setBegin(VD->getLocation());
4727 }
4728 return R;
4729 }
4730 return SourceRange();
4731}
4732
4733/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4734/// the decl-specifier-seq for declarations.
4735static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4736 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004737 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 if (!D)
4739 return SourceRange();
4740
4741 SourceRange R = D->getSourceRange();
4742
4743 // Adjust the start of the location for declarations preceded by
4744 // declaration specifiers.
4745 SourceLocation StartLoc;
4746 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4747 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4748 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004749 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4751 StartLoc = TI->getTypeLoc().getLocStart();
4752 }
4753
4754 if (StartLoc.isValid() && R.getBegin().isValid() &&
4755 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4756 R.setBegin(StartLoc);
4757
4758 // FIXME: Multiple variables declared in a single declaration
4759 // currently lack the information needed to correctly determine their
4760 // ranges when accounting for the type-specifier. We use context
4761 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4762 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004763 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 if (!cxcursor::isFirstInDeclGroup(C))
4765 R.setBegin(VD->getLocation());
4766 }
4767
4768 return R;
4769 }
4770
4771 return getRawCursorExtent(C);
4772}
4773
4774extern "C" {
4775
4776CXSourceRange clang_getCursorExtent(CXCursor C) {
4777 SourceRange R = getRawCursorExtent(C);
4778 if (R.isInvalid())
4779 return clang_getNullRange();
4780
4781 return cxloc::translateSourceRange(getCursorContext(C), R);
4782}
4783
4784CXCursor clang_getCursorReferenced(CXCursor C) {
4785 if (clang_isInvalid(C.kind))
4786 return clang_getNullCursor();
4787
4788 CXTranslationUnit tu = getCursorTU(C);
4789 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004790 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 if (!D)
4792 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004793 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004795 if (const ObjCPropertyImplDecl *PropImpl =
4796 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4798 return MakeCXCursor(Property, tu);
4799
4800 return C;
4801 }
4802
4803 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004804 const Expr *E = getCursorExpr(C);
4805 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004806 if (D) {
4807 CXCursor declCursor = MakeCXCursor(D, tu);
4808 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4809 declCursor);
4810 return declCursor;
4811 }
4812
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004813 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 return MakeCursorOverloadedDeclRef(Ovl, tu);
4815
4816 return clang_getNullCursor();
4817 }
4818
4819 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004820 const Stmt *S = getCursorStmt(C);
4821 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 if (LabelDecl *label = Goto->getLabel())
4823 if (LabelStmt *labelS = label->getStmt())
4824 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4825
4826 return clang_getNullCursor();
4827 }
4828
4829 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004830 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004831 return MakeMacroDefinitionCursor(Def, tu);
4832 }
4833
4834 if (!clang_isReference(C.kind))
4835 return clang_getNullCursor();
4836
4837 switch (C.kind) {
4838 case CXCursor_ObjCSuperClassRef:
4839 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4840
4841 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004842 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4843 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 return MakeCXCursor(Def, tu);
4845
4846 return MakeCXCursor(Prot, tu);
4847 }
4848
4849 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004850 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4851 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004852 return MakeCXCursor(Def, tu);
4853
4854 return MakeCXCursor(Class, tu);
4855 }
4856
4857 case CXCursor_TypeRef:
4858 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4859
4860 case CXCursor_TemplateRef:
4861 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4862
4863 case CXCursor_NamespaceRef:
4864 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4865
4866 case CXCursor_MemberRef:
4867 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4868
4869 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004870 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004871 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4872 tu ));
4873 }
4874
4875 case CXCursor_LabelRef:
4876 // FIXME: We end up faking the "parent" declaration here because we
4877 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004878 return MakeCXCursor(getCursorLabelRef(C).first,
4879 cxtu::getASTUnit(tu)->getASTContext()
4880 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004881 tu);
4882
4883 case CXCursor_OverloadedDeclRef:
4884 return C;
4885
4886 case CXCursor_VariableRef:
4887 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4888
4889 default:
4890 // We would prefer to enumerate all non-reference cursor kinds here.
4891 llvm_unreachable("Unhandled reference cursor kind");
4892 }
4893}
4894
4895CXCursor clang_getCursorDefinition(CXCursor C) {
4896 if (clang_isInvalid(C.kind))
4897 return clang_getNullCursor();
4898
4899 CXTranslationUnit TU = getCursorTU(C);
4900
4901 bool WasReference = false;
4902 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4903 C = clang_getCursorReferenced(C);
4904 WasReference = true;
4905 }
4906
4907 if (C.kind == CXCursor_MacroExpansion)
4908 return clang_getCursorReferenced(C);
4909
4910 if (!clang_isDeclaration(C.kind))
4911 return clang_getNullCursor();
4912
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004913 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 if (!D)
4915 return clang_getNullCursor();
4916
4917 switch (D->getKind()) {
4918 // Declaration kinds that don't really separate the notions of
4919 // declaration and definition.
4920 case Decl::Namespace:
4921 case Decl::Typedef:
4922 case Decl::TypeAlias:
4923 case Decl::TypeAliasTemplate:
4924 case Decl::TemplateTypeParm:
4925 case Decl::EnumConstant:
4926 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004927 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004928 case Decl::IndirectField:
4929 case Decl::ObjCIvar:
4930 case Decl::ObjCAtDefsField:
4931 case Decl::ImplicitParam:
4932 case Decl::ParmVar:
4933 case Decl::NonTypeTemplateParm:
4934 case Decl::TemplateTemplateParm:
4935 case Decl::ObjCCategoryImpl:
4936 case Decl::ObjCImplementation:
4937 case Decl::AccessSpec:
4938 case Decl::LinkageSpec:
4939 case Decl::ObjCPropertyImpl:
4940 case Decl::FileScopeAsm:
4941 case Decl::StaticAssert:
4942 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004943 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004944 case Decl::Label: // FIXME: Is this right??
4945 case Decl::ClassScopeFunctionSpecialization:
4946 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004947 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 return C;
4949
4950 // Declaration kinds that don't make any sense here, but are
4951 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004952 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00004954 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 break;
4956
4957 // Declaration kinds for which the definition is not resolvable.
4958 case Decl::UnresolvedUsingTypename:
4959 case Decl::UnresolvedUsingValue:
4960 break;
4961
4962 case Decl::UsingDirective:
4963 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4964 TU);
4965
4966 case Decl::NamespaceAlias:
4967 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4968
4969 case Decl::Enum:
4970 case Decl::Record:
4971 case Decl::CXXRecord:
4972 case Decl::ClassTemplateSpecialization:
4973 case Decl::ClassTemplatePartialSpecialization:
4974 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4975 return MakeCXCursor(Def, TU);
4976 return clang_getNullCursor();
4977
4978 case Decl::Function:
4979 case Decl::CXXMethod:
4980 case Decl::CXXConstructor:
4981 case Decl::CXXDestructor:
4982 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004983 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004984 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004985 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004986 return clang_getNullCursor();
4987 }
4988
Larisse Voufo39a1e502013-08-06 01:03:05 +00004989 case Decl::Var:
4990 case Decl::VarTemplateSpecialization:
4991 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004993 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 return MakeCXCursor(Def, TU);
4995 return clang_getNullCursor();
4996 }
4997
4998 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004999 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5001 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5002 return clang_getNullCursor();
5003 }
5004
5005 case Decl::ClassTemplate: {
5006 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5007 ->getDefinition())
5008 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5009 TU);
5010 return clang_getNullCursor();
5011 }
5012
Larisse Voufo39a1e502013-08-06 01:03:05 +00005013 case Decl::VarTemplate: {
5014 if (VarDecl *Def =
5015 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5016 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5017 return clang_getNullCursor();
5018 }
5019
Guy Benyei11169dd2012-12-18 14:30:41 +00005020 case Decl::Using:
5021 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5022 D->getLocation(), TU);
5023
5024 case Decl::UsingShadow:
5025 return clang_getCursorDefinition(
5026 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5027 TU));
5028
5029 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005030 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005031 if (Method->isThisDeclarationADefinition())
5032 return C;
5033
5034 // Dig out the method definition in the associated
5035 // @implementation, if we have it.
5036 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005037 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005038 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5039 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5040 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5041 Method->isInstanceMethod()))
5042 if (Def->isThisDeclarationADefinition())
5043 return MakeCXCursor(Def, TU);
5044
5045 return clang_getNullCursor();
5046 }
5047
5048 case Decl::ObjCCategory:
5049 if (ObjCCategoryImplDecl *Impl
5050 = cast<ObjCCategoryDecl>(D)->getImplementation())
5051 return MakeCXCursor(Impl, TU);
5052 return clang_getNullCursor();
5053
5054 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005055 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 return MakeCXCursor(Def, TU);
5057 return clang_getNullCursor();
5058
5059 case Decl::ObjCInterface: {
5060 // There are two notions of a "definition" for an Objective-C
5061 // class: the interface and its implementation. When we resolved a
5062 // reference to an Objective-C class, produce the @interface as
5063 // the definition; when we were provided with the interface,
5064 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005065 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005066 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005067 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005068 return MakeCXCursor(Def, TU);
5069 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5070 return MakeCXCursor(Impl, TU);
5071 return clang_getNullCursor();
5072 }
5073
5074 case Decl::ObjCProperty:
5075 // FIXME: We don't really know where to find the
5076 // ObjCPropertyImplDecls that implement this property.
5077 return clang_getNullCursor();
5078
5079 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005080 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005082 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 return MakeCXCursor(Def, TU);
5084
5085 return clang_getNullCursor();
5086
5087 case Decl::Friend:
5088 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5089 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5090 return clang_getNullCursor();
5091
5092 case Decl::FriendTemplate:
5093 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5094 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5095 return clang_getNullCursor();
5096 }
5097
5098 return clang_getNullCursor();
5099}
5100
5101unsigned clang_isCursorDefinition(CXCursor C) {
5102 if (!clang_isDeclaration(C.kind))
5103 return 0;
5104
5105 return clang_getCursorDefinition(C) == C;
5106}
5107
5108CXCursor clang_getCanonicalCursor(CXCursor C) {
5109 if (!clang_isDeclaration(C.kind))
5110 return C;
5111
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005112 if (const Decl *D = getCursorDecl(C)) {
5113 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5115 return MakeCXCursor(CatD, getCursorTU(C));
5116
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005117 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5118 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 return MakeCXCursor(IFD, getCursorTU(C));
5120
5121 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5122 }
5123
5124 return C;
5125}
5126
5127int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5128 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5129}
5130
5131unsigned clang_getNumOverloadedDecls(CXCursor C) {
5132 if (C.kind != CXCursor_OverloadedDeclRef)
5133 return 0;
5134
5135 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005136 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005137 return E->getNumDecls();
5138
5139 if (OverloadedTemplateStorage *S
5140 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5141 return S->size();
5142
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005143 const Decl *D = Storage.get<const Decl *>();
5144 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 return Using->shadow_size();
5146
5147 return 0;
5148}
5149
5150CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5151 if (cursor.kind != CXCursor_OverloadedDeclRef)
5152 return clang_getNullCursor();
5153
5154 if (index >= clang_getNumOverloadedDecls(cursor))
5155 return clang_getNullCursor();
5156
5157 CXTranslationUnit TU = getCursorTU(cursor);
5158 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005159 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 return MakeCXCursor(E->decls_begin()[index], TU);
5161
5162 if (OverloadedTemplateStorage *S
5163 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5164 return MakeCXCursor(S->begin()[index], TU);
5165
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005166 const Decl *D = Storage.get<const Decl *>();
5167 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005168 // FIXME: This is, unfortunately, linear time.
5169 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5170 std::advance(Pos, index);
5171 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5172 }
5173
5174 return clang_getNullCursor();
5175}
5176
5177void clang_getDefinitionSpellingAndExtent(CXCursor C,
5178 const char **startBuf,
5179 const char **endBuf,
5180 unsigned *startLine,
5181 unsigned *startColumn,
5182 unsigned *endLine,
5183 unsigned *endColumn) {
5184 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005185 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5187
5188 SourceManager &SM = FD->getASTContext().getSourceManager();
5189 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5190 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5191 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5192 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5193 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5194 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5195}
5196
5197
5198CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5199 unsigned PieceIndex) {
5200 RefNamePieces Pieces;
5201
5202 switch (C.kind) {
5203 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005204 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5206 E->getQualifierLoc().getSourceRange());
5207 break;
5208
5209 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005210 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5212 E->getQualifierLoc().getSourceRange(),
5213 E->getOptionalExplicitTemplateArgs());
5214 break;
5215
5216 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005217 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005219 const Expr *Callee = OCE->getCallee();
5220 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 Callee = ICE->getSubExpr();
5222
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005223 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5225 DRE->getQualifierLoc().getSourceRange());
5226 }
5227 break;
5228
5229 default:
5230 break;
5231 }
5232
5233 if (Pieces.empty()) {
5234 if (PieceIndex == 0)
5235 return clang_getCursorExtent(C);
5236 } else if (PieceIndex < Pieces.size()) {
5237 SourceRange R = Pieces[PieceIndex];
5238 if (R.isValid())
5239 return cxloc::translateSourceRange(getCursorContext(C), R);
5240 }
5241
5242 return clang_getNullRange();
5243}
5244
5245void clang_enableStackTraces(void) {
5246 llvm::sys::PrintStackTraceOnErrorSignal();
5247}
5248
5249void clang_executeOnThread(void (*fn)(void*), void *user_data,
5250 unsigned stack_size) {
5251 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5252}
5253
5254} // end: extern "C"
5255
5256//===----------------------------------------------------------------------===//
5257// Token-based Operations.
5258//===----------------------------------------------------------------------===//
5259
5260/* CXToken layout:
5261 * int_data[0]: a CXTokenKind
5262 * int_data[1]: starting token location
5263 * int_data[2]: token length
5264 * int_data[3]: reserved
5265 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5266 * otherwise unused.
5267 */
5268extern "C" {
5269
5270CXTokenKind clang_getTokenKind(CXToken CXTok) {
5271 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5272}
5273
5274CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5275 switch (clang_getTokenKind(CXTok)) {
5276 case CXToken_Identifier:
5277 case CXToken_Keyword:
5278 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005279 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 ->getNameStart());
5281
5282 case CXToken_Literal: {
5283 // We have stashed the starting pointer in the ptr_data field. Use it.
5284 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005285 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 }
5287
5288 case CXToken_Punctuation:
5289 case CXToken_Comment:
5290 break;
5291 }
5292
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005293 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005294 LOG_BAD_TU(TU);
5295 return cxstring::createEmpty();
5296 }
5297
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 // We have to find the starting buffer pointer the hard way, by
5299 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005300 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005301 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005302 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005303
5304 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5305 std::pair<FileID, unsigned> LocInfo
5306 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5307 bool Invalid = false;
5308 StringRef Buffer
5309 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5310 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005311 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005312
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005313 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005314}
5315
5316CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005317 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005318 LOG_BAD_TU(TU);
5319 return clang_getNullLocation();
5320 }
5321
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005322 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005323 if (!CXXUnit)
5324 return clang_getNullLocation();
5325
5326 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5327 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5328}
5329
5330CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005331 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005332 LOG_BAD_TU(TU);
5333 return clang_getNullRange();
5334 }
5335
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005336 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005337 if (!CXXUnit)
5338 return clang_getNullRange();
5339
5340 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5341 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5342}
5343
5344static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5345 SmallVectorImpl<CXToken> &CXTokens) {
5346 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5347 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005348 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005350 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005351
5352 // Cannot tokenize across files.
5353 if (BeginLocInfo.first != EndLocInfo.first)
5354 return;
5355
5356 // Create a lexer
5357 bool Invalid = false;
5358 StringRef Buffer
5359 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5360 if (Invalid)
5361 return;
5362
5363 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5364 CXXUnit->getASTContext().getLangOpts(),
5365 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5366 Lex.SetCommentRetentionState(true);
5367
5368 // Lex tokens until we hit the end of the range.
5369 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5370 Token Tok;
5371 bool previousWasAt = false;
5372 do {
5373 // Lex the next token
5374 Lex.LexFromRawLexer(Tok);
5375 if (Tok.is(tok::eof))
5376 break;
5377
5378 // Initialize the CXToken.
5379 CXToken CXTok;
5380
5381 // - Common fields
5382 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5383 CXTok.int_data[2] = Tok.getLength();
5384 CXTok.int_data[3] = 0;
5385
5386 // - Kind-specific fields
5387 if (Tok.isLiteral()) {
5388 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005389 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005390 } else if (Tok.is(tok::raw_identifier)) {
5391 // Lookup the identifier to determine whether we have a keyword.
5392 IdentifierInfo *II
5393 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5394
5395 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5396 CXTok.int_data[0] = CXToken_Keyword;
5397 }
5398 else {
5399 CXTok.int_data[0] = Tok.is(tok::identifier)
5400 ? CXToken_Identifier
5401 : CXToken_Keyword;
5402 }
5403 CXTok.ptr_data = II;
5404 } else if (Tok.is(tok::comment)) {
5405 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005406 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005407 } else {
5408 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005409 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005410 }
5411 CXTokens.push_back(CXTok);
5412 previousWasAt = Tok.is(tok::at);
5413 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5414}
5415
5416void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5417 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005418 LOG_FUNC_SECTION {
5419 *Log << TU << ' ' << Range;
5420 }
5421
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005423 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005424 if (NumTokens)
5425 *NumTokens = 0;
5426
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005427 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005428 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005429 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005430 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005431
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005432 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 if (!CXXUnit || !Tokens || !NumTokens)
5434 return;
5435
5436 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5437
5438 SourceRange R = cxloc::translateCXSourceRange(Range);
5439 if (R.isInvalid())
5440 return;
5441
5442 SmallVector<CXToken, 32> CXTokens;
5443 getTokens(CXXUnit, R, CXTokens);
5444
5445 if (CXTokens.empty())
5446 return;
5447
5448 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5449 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5450 *NumTokens = CXTokens.size();
5451}
5452
5453void clang_disposeTokens(CXTranslationUnit TU,
5454 CXToken *Tokens, unsigned NumTokens) {
5455 free(Tokens);
5456}
5457
5458} // end: extern "C"
5459
5460//===----------------------------------------------------------------------===//
5461// Token annotation APIs.
5462//===----------------------------------------------------------------------===//
5463
Guy Benyei11169dd2012-12-18 14:30:41 +00005464static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5465 CXCursor parent,
5466 CXClientData client_data);
5467static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5468 CXClientData client_data);
5469
5470namespace {
5471class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005472 CXToken *Tokens;
5473 CXCursor *Cursors;
5474 unsigned NumTokens;
5475 unsigned TokIdx;
5476 unsigned PreprocessingTokIdx;
5477 CursorVisitor AnnotateVis;
5478 SourceManager &SrcMgr;
5479 bool HasContextSensitiveKeywords;
5480
5481 struct PostChildrenInfo {
5482 CXCursor Cursor;
5483 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005484 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 unsigned BeforeChildrenTokenIdx;
5486 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005487 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005488
5489 CXToken &getTok(unsigned Idx) {
5490 assert(Idx < NumTokens);
5491 return Tokens[Idx];
5492 }
5493 const CXToken &getTok(unsigned Idx) const {
5494 assert(Idx < NumTokens);
5495 return Tokens[Idx];
5496 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 bool MoreTokens() const { return TokIdx < NumTokens; }
5498 unsigned NextToken() const { return TokIdx; }
5499 void AdvanceToken() { ++TokIdx; }
5500 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005501 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005502 }
5503 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005504 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005505 }
5506 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005507 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005508 }
5509
5510 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005511 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 SourceRange);
5513
5514public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005515 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005516 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005517 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005518 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005519 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005520 AnnotateTokensVisitor, this,
5521 /*VisitPreprocessorLast=*/true,
5522 /*VisitIncludedEntities=*/false,
5523 RegionOfInterest,
5524 /*VisitDeclsOnly=*/false,
5525 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005526 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005527 HasContextSensitiveKeywords(false) { }
5528
5529 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5530 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5531 bool postVisitChildren(CXCursor cursor);
5532 void AnnotateTokens();
5533
5534 /// \brief Determine whether the annotator saw any cursors that have
5535 /// context-sensitive keywords.
5536 bool hasContextSensitiveKeywords() const {
5537 return HasContextSensitiveKeywords;
5538 }
5539
5540 ~AnnotateTokensWorker() {
5541 assert(PostChildrenInfos.empty());
5542 }
5543};
5544}
5545
5546void AnnotateTokensWorker::AnnotateTokens() {
5547 // Walk the AST within the region of interest, annotating tokens
5548 // along the way.
5549 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005550}
Guy Benyei11169dd2012-12-18 14:30:41 +00005551
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005552static inline void updateCursorAnnotation(CXCursor &Cursor,
5553 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005554 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005555 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005556 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005557}
5558
5559/// \brief It annotates and advances tokens with a cursor until the comparison
5560//// between the cursor location and the source range is the same as
5561/// \arg compResult.
5562///
5563/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5564/// Pass RangeOverlap to annotate tokens inside a range.
5565void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5566 RangeComparisonResult compResult,
5567 SourceRange range) {
5568 while (MoreTokens()) {
5569 const unsigned I = NextToken();
5570 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005571 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5572 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005573
5574 SourceLocation TokLoc = GetTokenLoc(I);
5575 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005576 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005577 AdvanceToken();
5578 continue;
5579 }
5580 break;
5581 }
5582}
5583
5584/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005585/// \returns true if it advanced beyond all macro tokens, false otherwise.
5586bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005587 CXCursor updateC,
5588 RangeComparisonResult compResult,
5589 SourceRange range) {
5590 assert(MoreTokens());
5591 assert(isFunctionMacroToken(NextToken()) &&
5592 "Should be called only for macro arg tokens");
5593
5594 // This works differently than annotateAndAdvanceTokens; because expanded
5595 // macro arguments can have arbitrary translation-unit source order, we do not
5596 // advance the token index one by one until a token fails the range test.
5597 // We only advance once past all of the macro arg tokens if all of them
5598 // pass the range test. If one of them fails we keep the token index pointing
5599 // at the start of the macro arg tokens so that the failing token will be
5600 // annotated by a subsequent annotation try.
5601
5602 bool atLeastOneCompFail = false;
5603
5604 unsigned I = NextToken();
5605 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5606 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5607 if (TokLoc.isFileID())
5608 continue; // not macro arg token, it's parens or comma.
5609 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5610 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5611 Cursors[I] = updateC;
5612 } else
5613 atLeastOneCompFail = true;
5614 }
5615
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005616 if (atLeastOneCompFail)
5617 return false;
5618
5619 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5620 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005621}
5622
5623enum CXChildVisitResult
5624AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 SourceRange cursorRange = getRawCursorExtent(cursor);
5626 if (cursorRange.isInvalid())
5627 return CXChildVisit_Recurse;
5628
5629 if (!HasContextSensitiveKeywords) {
5630 // Objective-C properties can have context-sensitive keywords.
5631 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005632 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5634 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5635 }
5636 // Objective-C methods can have context-sensitive keywords.
5637 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5638 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005639 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5641 if (Method->getObjCDeclQualifier())
5642 HasContextSensitiveKeywords = true;
5643 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005644 for (const auto *P : Method->params()) {
5645 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 HasContextSensitiveKeywords = true;
5647 break;
5648 }
5649 }
5650 }
5651 }
5652 }
5653 // C++ methods can have context-sensitive keywords.
5654 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005655 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005656 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5657 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5658 HasContextSensitiveKeywords = true;
5659 }
5660 }
5661 // C++ classes can have context-sensitive keywords.
5662 else if (cursor.kind == CXCursor_StructDecl ||
5663 cursor.kind == CXCursor_ClassDecl ||
5664 cursor.kind == CXCursor_ClassTemplate ||
5665 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005666 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 if (D->hasAttr<FinalAttr>())
5668 HasContextSensitiveKeywords = true;
5669 }
5670 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005671
5672 // Don't override a property annotation with its getter/setter method.
5673 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5674 parent.kind == CXCursor_ObjCPropertyDecl)
5675 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005676
5677 if (clang_isPreprocessing(cursor.kind)) {
5678 // Items in the preprocessing record are kept separate from items in
5679 // declarations, so we keep a separate token index.
5680 unsigned SavedTokIdx = TokIdx;
5681 TokIdx = PreprocessingTokIdx;
5682
5683 // Skip tokens up until we catch up to the beginning of the preprocessing
5684 // entry.
5685 while (MoreTokens()) {
5686 const unsigned I = NextToken();
5687 SourceLocation TokLoc = GetTokenLoc(I);
5688 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5689 case RangeBefore:
5690 AdvanceToken();
5691 continue;
5692 case RangeAfter:
5693 case RangeOverlap:
5694 break;
5695 }
5696 break;
5697 }
5698
5699 // Look at all of the tokens within this range.
5700 while (MoreTokens()) {
5701 const unsigned I = NextToken();
5702 SourceLocation TokLoc = GetTokenLoc(I);
5703 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5704 case RangeBefore:
5705 llvm_unreachable("Infeasible");
5706 case RangeAfter:
5707 break;
5708 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005709 // For macro expansions, just note where the beginning of the macro
5710 // expansion occurs.
5711 if (cursor.kind == CXCursor_MacroExpansion) {
5712 if (TokLoc == cursorRange.getBegin())
5713 Cursors[I] = cursor;
5714 AdvanceToken();
5715 break;
5716 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005717 // We may have already annotated macro names inside macro definitions.
5718 if (Cursors[I].kind != CXCursor_MacroExpansion)
5719 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005721 continue;
5722 }
5723 break;
5724 }
5725
5726 // Save the preprocessing token index; restore the non-preprocessing
5727 // token index.
5728 PreprocessingTokIdx = TokIdx;
5729 TokIdx = SavedTokIdx;
5730 return CXChildVisit_Recurse;
5731 }
5732
5733 if (cursorRange.isInvalid())
5734 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005735
5736 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005737 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005738 const enum CXCursorKind K = clang_getCursorKind(parent);
5739 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005740 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5741 // Attributes are annotated out-of-order, skip tokens until we reach it.
5742 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005743 ? clang_getNullCursor() : parent;
5744
5745 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5746
5747 // Avoid having the cursor of an expression "overwrite" the annotation of the
5748 // variable declaration that it belongs to.
5749 // This can happen for C++ constructor expressions whose range generally
5750 // include the variable declaration, e.g.:
5751 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005752 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005753 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005754 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005755 const unsigned I = NextToken();
5756 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5757 E->getLocStart() == D->getLocation() &&
5758 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005759 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005760 AdvanceToken();
5761 }
5762 }
5763 }
5764
5765 // Before recursing into the children keep some state that we are going
5766 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5767 // extra work after the child nodes are visited.
5768 // Note that we don't call VisitChildren here to avoid traversing statements
5769 // code-recursively which can blow the stack.
5770
5771 PostChildrenInfo Info;
5772 Info.Cursor = cursor;
5773 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005774 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005775 Info.BeforeChildrenTokenIdx = NextToken();
5776 PostChildrenInfos.push_back(Info);
5777
5778 return CXChildVisit_Recurse;
5779}
5780
5781bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5782 if (PostChildrenInfos.empty())
5783 return false;
5784 const PostChildrenInfo &Info = PostChildrenInfos.back();
5785 if (!clang_equalCursors(Info.Cursor, cursor))
5786 return false;
5787
5788 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5789 const unsigned AfterChildren = NextToken();
5790 SourceRange cursorRange = Info.CursorRange;
5791
5792 // Scan the tokens that are at the end of the cursor, but are not captured
5793 // but the child cursors.
5794 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5795
5796 // Scan the tokens that are at the beginning of the cursor, but are not
5797 // capture by the child cursors.
5798 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5799 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5800 break;
5801
5802 Cursors[I] = cursor;
5803 }
5804
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005805 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5806 // encountered the attribute cursor.
5807 if (clang_isAttribute(cursor.kind))
5808 TokIdx = Info.BeforeReachingCursorIdx;
5809
Guy Benyei11169dd2012-12-18 14:30:41 +00005810 PostChildrenInfos.pop_back();
5811 return false;
5812}
5813
5814static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5815 CXCursor parent,
5816 CXClientData client_data) {
5817 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5818}
5819
5820static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5821 CXClientData client_data) {
5822 return static_cast<AnnotateTokensWorker*>(client_data)->
5823 postVisitChildren(cursor);
5824}
5825
5826namespace {
5827
5828/// \brief Uses the macro expansions in the preprocessing record to find
5829/// and mark tokens that are macro arguments. This info is used by the
5830/// AnnotateTokensWorker.
5831class MarkMacroArgTokensVisitor {
5832 SourceManager &SM;
5833 CXToken *Tokens;
5834 unsigned NumTokens;
5835 unsigned CurIdx;
5836
5837public:
5838 MarkMacroArgTokensVisitor(SourceManager &SM,
5839 CXToken *tokens, unsigned numTokens)
5840 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5841
5842 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5843 if (cursor.kind != CXCursor_MacroExpansion)
5844 return CXChildVisit_Continue;
5845
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005846 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005847 if (macroRange.getBegin() == macroRange.getEnd())
5848 return CXChildVisit_Continue; // it's not a function macro.
5849
5850 for (; CurIdx < NumTokens; ++CurIdx) {
5851 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5852 macroRange.getBegin()))
5853 break;
5854 }
5855
5856 if (CurIdx == NumTokens)
5857 return CXChildVisit_Break;
5858
5859 for (; CurIdx < NumTokens; ++CurIdx) {
5860 SourceLocation tokLoc = getTokenLoc(CurIdx);
5861 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5862 break;
5863
5864 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5865 }
5866
5867 if (CurIdx == NumTokens)
5868 return CXChildVisit_Break;
5869
5870 return CXChildVisit_Continue;
5871 }
5872
5873private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005874 CXToken &getTok(unsigned Idx) {
5875 assert(Idx < NumTokens);
5876 return Tokens[Idx];
5877 }
5878 const CXToken &getTok(unsigned Idx) const {
5879 assert(Idx < NumTokens);
5880 return Tokens[Idx];
5881 }
5882
Guy Benyei11169dd2012-12-18 14:30:41 +00005883 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005884 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 }
5886
5887 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5888 // The third field is reserved and currently not used. Use it here
5889 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005890 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 }
5892};
5893
5894} // end anonymous namespace
5895
5896static CXChildVisitResult
5897MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5898 CXClientData client_data) {
5899 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5900 parent);
5901}
5902
5903namespace {
5904 struct clang_annotateTokens_Data {
5905 CXTranslationUnit TU;
5906 ASTUnit *CXXUnit;
5907 CXToken *Tokens;
5908 unsigned NumTokens;
5909 CXCursor *Cursors;
5910 };
5911}
5912
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005913/// \brief Used by \c annotatePreprocessorTokens.
5914/// \returns true if lexing was finished, false otherwise.
5915static bool lexNext(Lexer &Lex, Token &Tok,
5916 unsigned &NextIdx, unsigned NumTokens) {
5917 if (NextIdx >= NumTokens)
5918 return true;
5919
5920 ++NextIdx;
5921 Lex.LexFromRawLexer(Tok);
5922 if (Tok.is(tok::eof))
5923 return true;
5924
5925 return false;
5926}
5927
Guy Benyei11169dd2012-12-18 14:30:41 +00005928static void annotatePreprocessorTokens(CXTranslationUnit TU,
5929 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005930 CXCursor *Cursors,
5931 CXToken *Tokens,
5932 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005933 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005934
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005935 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005936 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5937 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005938 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005939 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005940 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005941
5942 if (BeginLocInfo.first != EndLocInfo.first)
5943 return;
5944
5945 StringRef Buffer;
5946 bool Invalid = false;
5947 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5948 if (Buffer.empty() || Invalid)
5949 return;
5950
5951 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5952 CXXUnit->getASTContext().getLangOpts(),
5953 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5954 Buffer.end());
5955 Lex.SetCommentRetentionState(true);
5956
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005957 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005958 // Lex tokens in raw mode until we hit the end of the range, to avoid
5959 // entering #includes or expanding macros.
5960 while (true) {
5961 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005962 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5963 break;
5964 unsigned TokIdx = NextIdx-1;
5965 assert(Tok.getLocation() ==
5966 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005967
5968 reprocess:
5969 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005970 // We have found a preprocessing directive. Annotate the tokens
5971 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005972 //
5973 // FIXME: Some simple tests here could identify macro definitions and
5974 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005975
5976 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005977 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5978 break;
5979
Craig Topper69186e72014-06-08 08:38:04 +00005980 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005981 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005982 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5983 break;
5984
5985 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005986 IdentifierInfo &II =
5987 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005988 SourceLocation MappedTokLoc =
5989 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5990 MI = getMacroInfo(II, MappedTokLoc, TU);
5991 }
5992 }
5993
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005994 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005995 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005996 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5997 finished = true;
5998 break;
5999 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006000 // If we are in a macro definition, check if the token was ever a
6001 // macro name and annotate it if that's the case.
6002 if (MI) {
6003 SourceLocation SaveLoc = Tok.getLocation();
6004 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6005 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
6006 Tok.setLocation(SaveLoc);
6007 if (MacroDef)
6008 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6009 Tok.getLocation(), TU);
6010 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006011 } while (!Tok.isAtStartOfLine());
6012
6013 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6014 assert(TokIdx <= LastIdx);
6015 SourceLocation EndLoc =
6016 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6017 CXCursor Cursor =
6018 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6019
6020 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006021 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006022
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006023 if (finished)
6024 break;
6025 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006026 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006027 }
6028}
6029
6030// This gets run a separate thread to avoid stack blowout.
6031static void clang_annotateTokensImpl(void *UserData) {
6032 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6033 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6034 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6035 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6036 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6037
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006038 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006039 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6040 setThreadBackgroundPriority();
6041
6042 // Determine the region of interest, which contains all of the tokens.
6043 SourceRange RegionOfInterest;
6044 RegionOfInterest.setBegin(
6045 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6046 RegionOfInterest.setEnd(
6047 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6048 Tokens[NumTokens-1])));
6049
Guy Benyei11169dd2012-12-18 14:30:41 +00006050 // Relex the tokens within the source range to look for preprocessing
6051 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006052 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006053
6054 // If begin location points inside a macro argument, set it to the expansion
6055 // location so we can have the full context when annotating semantically.
6056 {
6057 SourceManager &SM = CXXUnit->getSourceManager();
6058 SourceLocation Loc =
6059 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6060 if (Loc.isMacroID())
6061 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6062 }
6063
Guy Benyei11169dd2012-12-18 14:30:41 +00006064 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6065 // Search and mark tokens that are macro argument expansions.
6066 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6067 Tokens, NumTokens);
6068 CursorVisitor MacroArgMarker(TU,
6069 MarkMacroArgTokensVisitorDelegate, &Visitor,
6070 /*VisitPreprocessorLast=*/true,
6071 /*VisitIncludedEntities=*/false,
6072 RegionOfInterest);
6073 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6074 }
6075
6076 // Annotate all of the source locations in the region of interest that map to
6077 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006078 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006079
6080 // FIXME: We use a ridiculous stack size here because the data-recursion
6081 // algorithm uses a large stack frame than the non-data recursive version,
6082 // and AnnotationTokensWorker currently transforms the data-recursion
6083 // algorithm back into a traditional recursion by explicitly calling
6084 // VisitChildren(). We will need to remove this explicit recursive call.
6085 W.AnnotateTokens();
6086
6087 // If we ran into any entities that involve context-sensitive keywords,
6088 // take another pass through the tokens to mark them as such.
6089 if (W.hasContextSensitiveKeywords()) {
6090 for (unsigned I = 0; I != NumTokens; ++I) {
6091 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6092 continue;
6093
6094 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6095 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006096 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006097 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6098 if (Property->getPropertyAttributesAsWritten() != 0 &&
6099 llvm::StringSwitch<bool>(II->getName())
6100 .Case("readonly", true)
6101 .Case("assign", true)
6102 .Case("unsafe_unretained", true)
6103 .Case("readwrite", true)
6104 .Case("retain", true)
6105 .Case("copy", true)
6106 .Case("nonatomic", true)
6107 .Case("atomic", true)
6108 .Case("getter", true)
6109 .Case("setter", true)
6110 .Case("strong", true)
6111 .Case("weak", true)
6112 .Default(false))
6113 Tokens[I].int_data[0] = CXToken_Keyword;
6114 }
6115 continue;
6116 }
6117
6118 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6119 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6120 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6121 if (llvm::StringSwitch<bool>(II->getName())
6122 .Case("in", true)
6123 .Case("out", true)
6124 .Case("inout", true)
6125 .Case("oneway", true)
6126 .Case("bycopy", true)
6127 .Case("byref", true)
6128 .Default(false))
6129 Tokens[I].int_data[0] = CXToken_Keyword;
6130 continue;
6131 }
6132
6133 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6134 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6135 Tokens[I].int_data[0] = CXToken_Keyword;
6136 continue;
6137 }
6138 }
6139 }
6140}
6141
6142extern "C" {
6143
6144void clang_annotateTokens(CXTranslationUnit TU,
6145 CXToken *Tokens, unsigned NumTokens,
6146 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006147 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006148 LOG_BAD_TU(TU);
6149 return;
6150 }
6151 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006152 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006154 }
6155
6156 LOG_FUNC_SECTION {
6157 *Log << TU << ' ';
6158 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6159 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6160 *Log << clang_getRange(bloc, eloc);
6161 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006162
6163 // Any token we don't specifically annotate will have a NULL cursor.
6164 CXCursor C = clang_getNullCursor();
6165 for (unsigned I = 0; I != NumTokens; ++I)
6166 Cursors[I] = C;
6167
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006168 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006169 if (!CXXUnit)
6170 return;
6171
6172 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6173
6174 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6175 llvm::CrashRecoveryContext CRC;
6176 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6177 GetSafetyThreadStackSize() * 2)) {
6178 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6179 }
6180}
6181
6182} // end: extern "C"
6183
6184//===----------------------------------------------------------------------===//
6185// Operations for querying linkage of a cursor.
6186//===----------------------------------------------------------------------===//
6187
6188extern "C" {
6189CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6190 if (!clang_isDeclaration(cursor.kind))
6191 return CXLinkage_Invalid;
6192
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006193 const Decl *D = cxcursor::getCursorDecl(cursor);
6194 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006195 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006196 case NoLinkage:
6197 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006198 case InternalLinkage: return CXLinkage_Internal;
6199 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6200 case ExternalLinkage: return CXLinkage_External;
6201 };
6202
6203 return CXLinkage_Invalid;
6204}
6205} // end: extern "C"
6206
6207//===----------------------------------------------------------------------===//
6208// Operations for querying language of a cursor.
6209//===----------------------------------------------------------------------===//
6210
6211static CXLanguageKind getDeclLanguage(const Decl *D) {
6212 if (!D)
6213 return CXLanguage_C;
6214
6215 switch (D->getKind()) {
6216 default:
6217 break;
6218 case Decl::ImplicitParam:
6219 case Decl::ObjCAtDefsField:
6220 case Decl::ObjCCategory:
6221 case Decl::ObjCCategoryImpl:
6222 case Decl::ObjCCompatibleAlias:
6223 case Decl::ObjCImplementation:
6224 case Decl::ObjCInterface:
6225 case Decl::ObjCIvar:
6226 case Decl::ObjCMethod:
6227 case Decl::ObjCProperty:
6228 case Decl::ObjCPropertyImpl:
6229 case Decl::ObjCProtocol:
6230 return CXLanguage_ObjC;
6231 case Decl::CXXConstructor:
6232 case Decl::CXXConversion:
6233 case Decl::CXXDestructor:
6234 case Decl::CXXMethod:
6235 case Decl::CXXRecord:
6236 case Decl::ClassTemplate:
6237 case Decl::ClassTemplatePartialSpecialization:
6238 case Decl::ClassTemplateSpecialization:
6239 case Decl::Friend:
6240 case Decl::FriendTemplate:
6241 case Decl::FunctionTemplate:
6242 case Decl::LinkageSpec:
6243 case Decl::Namespace:
6244 case Decl::NamespaceAlias:
6245 case Decl::NonTypeTemplateParm:
6246 case Decl::StaticAssert:
6247 case Decl::TemplateTemplateParm:
6248 case Decl::TemplateTypeParm:
6249 case Decl::UnresolvedUsingTypename:
6250 case Decl::UnresolvedUsingValue:
6251 case Decl::Using:
6252 case Decl::UsingDirective:
6253 case Decl::UsingShadow:
6254 return CXLanguage_CPlusPlus;
6255 }
6256
6257 return CXLanguage_C;
6258}
6259
6260extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006261
6262static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6263 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6264 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006265
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006266 switch (D->getAvailability()) {
6267 case AR_Available:
6268 case AR_NotYetIntroduced:
6269 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006270 return getCursorAvailabilityForDecl(
6271 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006272 return CXAvailability_Available;
6273
6274 case AR_Deprecated:
6275 return CXAvailability_Deprecated;
6276
6277 case AR_Unavailable:
6278 return CXAvailability_NotAvailable;
6279 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006280
6281 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006282}
6283
Guy Benyei11169dd2012-12-18 14:30:41 +00006284enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6285 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006286 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6287 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006288
6289 return CXAvailability_Available;
6290}
6291
6292static CXVersion convertVersion(VersionTuple In) {
6293 CXVersion Out = { -1, -1, -1 };
6294 if (In.empty())
6295 return Out;
6296
6297 Out.Major = In.getMajor();
6298
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006299 Optional<unsigned> Minor = In.getMinor();
6300 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006301 Out.Minor = *Minor;
6302 else
6303 return Out;
6304
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006305 Optional<unsigned> Subminor = In.getSubminor();
6306 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006307 Out.Subminor = *Subminor;
6308
6309 return Out;
6310}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006311
6312static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6313 int *always_deprecated,
6314 CXString *deprecated_message,
6315 int *always_unavailable,
6316 CXString *unavailable_message,
6317 CXPlatformAvailability *availability,
6318 int availability_size) {
6319 bool HadAvailAttr = false;
6320 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006321 for (auto A : D->attrs()) {
6322 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006323 HadAvailAttr = true;
6324 if (always_deprecated)
6325 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006326 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006327 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006328 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006329 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006330 continue;
6331 }
6332
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006333 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006334 HadAvailAttr = true;
6335 if (always_unavailable)
6336 *always_unavailable = 1;
6337 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006338 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006339 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6340 }
6341 continue;
6342 }
6343
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006344 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006345 HadAvailAttr = true;
6346 if (N < availability_size) {
6347 availability[N].Platform
6348 = cxstring::createDup(Avail->getPlatform()->getName());
6349 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6350 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6351 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6352 availability[N].Unavailable = Avail->getUnavailable();
6353 availability[N].Message = cxstring::createDup(Avail->getMessage());
6354 }
6355 ++N;
6356 }
6357 }
6358
6359 if (!HadAvailAttr)
6360 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6361 return getCursorPlatformAvailabilityForDecl(
6362 cast<Decl>(EnumConst->getDeclContext()),
6363 always_deprecated,
6364 deprecated_message,
6365 always_unavailable,
6366 unavailable_message,
6367 availability,
6368 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006369
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006370 return N;
6371}
6372
Guy Benyei11169dd2012-12-18 14:30:41 +00006373int clang_getCursorPlatformAvailability(CXCursor cursor,
6374 int *always_deprecated,
6375 CXString *deprecated_message,
6376 int *always_unavailable,
6377 CXString *unavailable_message,
6378 CXPlatformAvailability *availability,
6379 int availability_size) {
6380 if (always_deprecated)
6381 *always_deprecated = 0;
6382 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006383 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006384 if (always_unavailable)
6385 *always_unavailable = 0;
6386 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006387 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006388
Guy Benyei11169dd2012-12-18 14:30:41 +00006389 if (!clang_isDeclaration(cursor.kind))
6390 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006391
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006392 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006393 if (!D)
6394 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006395
6396 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6397 deprecated_message,
6398 always_unavailable,
6399 unavailable_message,
6400 availability,
6401 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006402}
6403
6404void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6405 clang_disposeString(availability->Platform);
6406 clang_disposeString(availability->Message);
6407}
6408
6409CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6410 if (clang_isDeclaration(cursor.kind))
6411 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6412
6413 return CXLanguage_Invalid;
6414}
6415
6416 /// \brief If the given cursor is the "templated" declaration
6417 /// descibing a class or function template, return the class or
6418 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006419static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006420 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006421 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006423 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006424 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6425 return FunTmpl;
6426
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006427 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006428 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6429 return ClassTmpl;
6430
6431 return D;
6432}
6433
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006434
6435enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6436 StorageClass sc = SC_None;
6437 const Decl *D = getCursorDecl(C);
6438 if (D) {
6439 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6440 sc = FD->getStorageClass();
6441 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6442 sc = VD->getStorageClass();
6443 } else {
6444 return CX_SC_Invalid;
6445 }
6446 } else {
6447 return CX_SC_Invalid;
6448 }
6449 switch (sc) {
6450 case SC_None:
6451 return CX_SC_None;
6452 case SC_Extern:
6453 return CX_SC_Extern;
6454 case SC_Static:
6455 return CX_SC_Static;
6456 case SC_PrivateExtern:
6457 return CX_SC_PrivateExtern;
6458 case SC_OpenCLWorkGroupLocal:
6459 return CX_SC_OpenCLWorkGroupLocal;
6460 case SC_Auto:
6461 return CX_SC_Auto;
6462 case SC_Register:
6463 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006464 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006465 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006466}
6467
Guy Benyei11169dd2012-12-18 14:30:41 +00006468CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6469 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006470 if (const Decl *D = getCursorDecl(cursor)) {
6471 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006472 if (!DC)
6473 return clang_getNullCursor();
6474
6475 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6476 getCursorTU(cursor));
6477 }
6478 }
6479
6480 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006481 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006482 return MakeCXCursor(D, getCursorTU(cursor));
6483 }
6484
6485 return clang_getNullCursor();
6486}
6487
6488CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6489 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006490 if (const Decl *D = getCursorDecl(cursor)) {
6491 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006492 if (!DC)
6493 return clang_getNullCursor();
6494
6495 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6496 getCursorTU(cursor));
6497 }
6498 }
6499
6500 // FIXME: Note that we can't easily compute the lexical context of a
6501 // statement or expression, so we return nothing.
6502 return clang_getNullCursor();
6503}
6504
6505CXFile clang_getIncludedFile(CXCursor cursor) {
6506 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006507 return nullptr;
6508
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006509 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006510 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006511}
6512
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006513unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6514 if (C.kind != CXCursor_ObjCPropertyDecl)
6515 return CXObjCPropertyAttr_noattr;
6516
6517 unsigned Result = CXObjCPropertyAttr_noattr;
6518 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6519 ObjCPropertyDecl::PropertyAttributeKind Attr =
6520 PD->getPropertyAttributesAsWritten();
6521
6522#define SET_CXOBJCPROP_ATTR(A) \
6523 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6524 Result |= CXObjCPropertyAttr_##A
6525 SET_CXOBJCPROP_ATTR(readonly);
6526 SET_CXOBJCPROP_ATTR(getter);
6527 SET_CXOBJCPROP_ATTR(assign);
6528 SET_CXOBJCPROP_ATTR(readwrite);
6529 SET_CXOBJCPROP_ATTR(retain);
6530 SET_CXOBJCPROP_ATTR(copy);
6531 SET_CXOBJCPROP_ATTR(nonatomic);
6532 SET_CXOBJCPROP_ATTR(setter);
6533 SET_CXOBJCPROP_ATTR(atomic);
6534 SET_CXOBJCPROP_ATTR(weak);
6535 SET_CXOBJCPROP_ATTR(strong);
6536 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6537#undef SET_CXOBJCPROP_ATTR
6538
6539 return Result;
6540}
6541
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006542unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6543 if (!clang_isDeclaration(C.kind))
6544 return CXObjCDeclQualifier_None;
6545
6546 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6547 const Decl *D = getCursorDecl(C);
6548 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6549 QT = MD->getObjCDeclQualifier();
6550 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6551 QT = PD->getObjCDeclQualifier();
6552 if (QT == Decl::OBJC_TQ_None)
6553 return CXObjCDeclQualifier_None;
6554
6555 unsigned Result = CXObjCDeclQualifier_None;
6556 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6557 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6558 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6559 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6560 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6561 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6562
6563 return Result;
6564}
6565
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006566unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6567 if (!clang_isDeclaration(C.kind))
6568 return 0;
6569
6570 const Decl *D = getCursorDecl(C);
6571 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6572 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6573 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6574 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6575
6576 return 0;
6577}
6578
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006579unsigned clang_Cursor_isVariadic(CXCursor C) {
6580 if (!clang_isDeclaration(C.kind))
6581 return 0;
6582
6583 const Decl *D = getCursorDecl(C);
6584 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6585 return FD->isVariadic();
6586 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6587 return MD->isVariadic();
6588
6589 return 0;
6590}
6591
Guy Benyei11169dd2012-12-18 14:30:41 +00006592CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6593 if (!clang_isDeclaration(C.kind))
6594 return clang_getNullRange();
6595
6596 const Decl *D = getCursorDecl(C);
6597 ASTContext &Context = getCursorContext(C);
6598 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6599 if (!RC)
6600 return clang_getNullRange();
6601
6602 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6603}
6604
6605CXString clang_Cursor_getRawCommentText(CXCursor C) {
6606 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006607 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006608
6609 const Decl *D = getCursorDecl(C);
6610 ASTContext &Context = getCursorContext(C);
6611 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6612 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6613 StringRef();
6614
6615 // Don't duplicate the string because RawText points directly into source
6616 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006617 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006618}
6619
6620CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6621 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006622 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006623
6624 const Decl *D = getCursorDecl(C);
6625 const ASTContext &Context = getCursorContext(C);
6626 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6627
6628 if (RC) {
6629 StringRef BriefText = RC->getBriefText(Context);
6630
6631 // Don't duplicate the string because RawComment ensures that this memory
6632 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006633 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006634 }
6635
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006636 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006637}
6638
Guy Benyei11169dd2012-12-18 14:30:41 +00006639CXModule clang_Cursor_getModule(CXCursor C) {
6640 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006641 if (const ImportDecl *ImportD =
6642 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006643 return ImportD->getImportedModule();
6644 }
6645
Craig Topper69186e72014-06-08 08:38:04 +00006646 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006647}
6648
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006649CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6650 if (isNotUsableTU(TU)) {
6651 LOG_BAD_TU(TU);
6652 return nullptr;
6653 }
6654 if (!File)
6655 return nullptr;
6656 FileEntry *FE = static_cast<FileEntry *>(File);
6657
6658 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6659 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6660 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6661
Richard Smithfeb54b62014-10-23 02:01:19 +00006662 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006663}
6664
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006665CXFile clang_Module_getASTFile(CXModule CXMod) {
6666 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006667 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006668 Module *Mod = static_cast<Module*>(CXMod);
6669 return const_cast<FileEntry *>(Mod->getASTFile());
6670}
6671
Guy Benyei11169dd2012-12-18 14:30:41 +00006672CXModule clang_Module_getParent(CXModule CXMod) {
6673 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006674 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006675 Module *Mod = static_cast<Module*>(CXMod);
6676 return Mod->Parent;
6677}
6678
6679CXString clang_Module_getName(CXModule CXMod) {
6680 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006681 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006682 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006683 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006684}
6685
6686CXString clang_Module_getFullName(CXModule CXMod) {
6687 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006688 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006689 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006690 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006691}
6692
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006693int clang_Module_isSystem(CXModule CXMod) {
6694 if (!CXMod)
6695 return 0;
6696 Module *Mod = static_cast<Module*>(CXMod);
6697 return Mod->IsSystem;
6698}
6699
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006700unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6701 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006702 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006703 LOG_BAD_TU(TU);
6704 return 0;
6705 }
6706 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006707 return 0;
6708 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006709 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6710 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6711 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006712}
6713
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006714CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6715 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006716 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006717 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006718 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006719 }
6720 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006721 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006722 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006723 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006724
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006725 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6726 if (Index < TopHeaders.size())
6727 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006728
Craig Topper69186e72014-06-08 08:38:04 +00006729 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006730}
6731
6732} // end: extern "C"
6733
6734//===----------------------------------------------------------------------===//
6735// C++ AST instrospection.
6736//===----------------------------------------------------------------------===//
6737
6738extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006739unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6740 if (!clang_isDeclaration(C.kind))
6741 return 0;
6742
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006743 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006744 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006745 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006746 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6747}
6748
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006749unsigned clang_CXXMethod_isConst(CXCursor C) {
6750 if (!clang_isDeclaration(C.kind))
6751 return 0;
6752
6753 const Decl *D = cxcursor::getCursorDecl(C);
6754 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006755 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006756 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6757}
6758
Guy Benyei11169dd2012-12-18 14:30:41 +00006759unsigned clang_CXXMethod_isStatic(CXCursor C) {
6760 if (!clang_isDeclaration(C.kind))
6761 return 0;
6762
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006763 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006764 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006765 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006766 return (Method && Method->isStatic()) ? 1 : 0;
6767}
6768
6769unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6770 if (!clang_isDeclaration(C.kind))
6771 return 0;
6772
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006773 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006774 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006775 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006776 return (Method && Method->isVirtual()) ? 1 : 0;
6777}
6778} // end: extern "C"
6779
6780//===----------------------------------------------------------------------===//
6781// Attribute introspection.
6782//===----------------------------------------------------------------------===//
6783
6784extern "C" {
6785CXType clang_getIBOutletCollectionType(CXCursor C) {
6786 if (C.kind != CXCursor_IBOutletCollectionAttr)
6787 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6788
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006789 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006790 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6791
6792 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6793}
6794} // end: extern "C"
6795
6796//===----------------------------------------------------------------------===//
6797// Inspecting memory usage.
6798//===----------------------------------------------------------------------===//
6799
6800typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6801
6802static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6803 enum CXTUResourceUsageKind k,
6804 unsigned long amount) {
6805 CXTUResourceUsageEntry entry = { k, amount };
6806 entries.push_back(entry);
6807}
6808
6809extern "C" {
6810
6811const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6812 const char *str = "";
6813 switch (kind) {
6814 case CXTUResourceUsage_AST:
6815 str = "ASTContext: expressions, declarations, and types";
6816 break;
6817 case CXTUResourceUsage_Identifiers:
6818 str = "ASTContext: identifiers";
6819 break;
6820 case CXTUResourceUsage_Selectors:
6821 str = "ASTContext: selectors";
6822 break;
6823 case CXTUResourceUsage_GlobalCompletionResults:
6824 str = "Code completion: cached global results";
6825 break;
6826 case CXTUResourceUsage_SourceManagerContentCache:
6827 str = "SourceManager: content cache allocator";
6828 break;
6829 case CXTUResourceUsage_AST_SideTables:
6830 str = "ASTContext: side tables";
6831 break;
6832 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6833 str = "SourceManager: malloc'ed memory buffers";
6834 break;
6835 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6836 str = "SourceManager: mmap'ed memory buffers";
6837 break;
6838 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6839 str = "ExternalASTSource: malloc'ed memory buffers";
6840 break;
6841 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6842 str = "ExternalASTSource: mmap'ed memory buffers";
6843 break;
6844 case CXTUResourceUsage_Preprocessor:
6845 str = "Preprocessor: malloc'ed memory";
6846 break;
6847 case CXTUResourceUsage_PreprocessingRecord:
6848 str = "Preprocessor: PreprocessingRecord";
6849 break;
6850 case CXTUResourceUsage_SourceManager_DataStructures:
6851 str = "SourceManager: data structures and tables";
6852 break;
6853 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6854 str = "Preprocessor: header search tables";
6855 break;
6856 }
6857 return str;
6858}
6859
6860CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006861 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006862 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006863 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006864 return usage;
6865 }
6866
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006867 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006868 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006869 ASTContext &astContext = astUnit->getASTContext();
6870
6871 // How much memory is used by AST nodes and types?
6872 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6873 (unsigned long) astContext.getASTAllocatedMemory());
6874
6875 // How much memory is used by identifiers?
6876 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6877 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6878
6879 // How much memory is used for selectors?
6880 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6881 (unsigned long) astContext.Selectors.getTotalMemory());
6882
6883 // How much memory is used by ASTContext's side tables?
6884 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6885 (unsigned long) astContext.getSideTableAllocatedMemory());
6886
6887 // How much memory is used for caching global code completion results?
6888 unsigned long completionBytes = 0;
6889 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006890 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006891 completionBytes = completionAllocator->getTotalMemory();
6892 }
6893 createCXTUResourceUsageEntry(*entries,
6894 CXTUResourceUsage_GlobalCompletionResults,
6895 completionBytes);
6896
6897 // How much memory is being used by SourceManager's content cache?
6898 createCXTUResourceUsageEntry(*entries,
6899 CXTUResourceUsage_SourceManagerContentCache,
6900 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6901
6902 // How much memory is being used by the MemoryBuffer's in SourceManager?
6903 const SourceManager::MemoryBufferSizes &srcBufs =
6904 astUnit->getSourceManager().getMemoryBufferSizes();
6905
6906 createCXTUResourceUsageEntry(*entries,
6907 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6908 (unsigned long) srcBufs.malloc_bytes);
6909 createCXTUResourceUsageEntry(*entries,
6910 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6911 (unsigned long) srcBufs.mmap_bytes);
6912 createCXTUResourceUsageEntry(*entries,
6913 CXTUResourceUsage_SourceManager_DataStructures,
6914 (unsigned long) astContext.getSourceManager()
6915 .getDataStructureSizes());
6916
6917 // How much memory is being used by the ExternalASTSource?
6918 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6919 const ExternalASTSource::MemoryBufferSizes &sizes =
6920 esrc->getMemoryBufferSizes();
6921
6922 createCXTUResourceUsageEntry(*entries,
6923 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6924 (unsigned long) sizes.malloc_bytes);
6925 createCXTUResourceUsageEntry(*entries,
6926 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6927 (unsigned long) sizes.mmap_bytes);
6928 }
6929
6930 // How much memory is being used by the Preprocessor?
6931 Preprocessor &pp = astUnit->getPreprocessor();
6932 createCXTUResourceUsageEntry(*entries,
6933 CXTUResourceUsage_Preprocessor,
6934 pp.getTotalMemory());
6935
6936 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6937 createCXTUResourceUsageEntry(*entries,
6938 CXTUResourceUsage_PreprocessingRecord,
6939 pRec->getTotalMemory());
6940 }
6941
6942 createCXTUResourceUsageEntry(*entries,
6943 CXTUResourceUsage_Preprocessor_HeaderSearch,
6944 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006945
Guy Benyei11169dd2012-12-18 14:30:41 +00006946 CXTUResourceUsage usage = { (void*) entries.get(),
6947 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00006948 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006949 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006950 return usage;
6951}
6952
6953void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6954 if (usage.data)
6955 delete (MemUsageEntries*) usage.data;
6956}
6957
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006958CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6959 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006960 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006961 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006962
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006963 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006964 LOG_BAD_TU(TU);
6965 return skipped;
6966 }
6967
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006968 if (!file)
6969 return skipped;
6970
6971 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6972 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6973 if (!ppRec)
6974 return skipped;
6975
6976 ASTContext &Ctx = astUnit->getASTContext();
6977 SourceManager &sm = Ctx.getSourceManager();
6978 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6979 FileID wantedFileID = sm.translateFile(fileEntry);
6980
6981 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6982 std::vector<SourceRange> wantedRanges;
6983 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6984 i != ei; ++i) {
6985 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6986 wantedRanges.push_back(*i);
6987 }
6988
6989 skipped->count = wantedRanges.size();
6990 skipped->ranges = new CXSourceRange[skipped->count];
6991 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6992 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6993
6994 return skipped;
6995}
6996
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006997void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6998 if (ranges) {
6999 delete[] ranges->ranges;
7000 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007001 }
7002}
7003
Guy Benyei11169dd2012-12-18 14:30:41 +00007004} // end extern "C"
7005
7006void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7007 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7008 for (unsigned I = 0; I != Usage.numEntries; ++I)
7009 fprintf(stderr, " %s: %lu\n",
7010 clang_getTUResourceUsageName(Usage.entries[I].kind),
7011 Usage.entries[I].amount);
7012
7013 clang_disposeCXTUResourceUsage(Usage);
7014}
7015
7016//===----------------------------------------------------------------------===//
7017// Misc. utility functions.
7018//===----------------------------------------------------------------------===//
7019
7020/// Default to using an 8 MB stack size on "safety" threads.
7021static unsigned SafetyStackThreadSize = 8 << 20;
7022
7023namespace clang {
7024
7025bool RunSafely(llvm::CrashRecoveryContext &CRC,
7026 void (*Fn)(void*), void *UserData,
7027 unsigned Size) {
7028 if (!Size)
7029 Size = GetSafetyThreadStackSize();
7030 if (Size)
7031 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7032 return CRC.RunSafely(Fn, UserData);
7033}
7034
7035unsigned GetSafetyThreadStackSize() {
7036 return SafetyStackThreadSize;
7037}
7038
7039void SetSafetyThreadStackSize(unsigned Value) {
7040 SafetyStackThreadSize = Value;
7041}
7042
7043}
7044
7045void clang::setThreadBackgroundPriority() {
7046 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7047 return;
7048
Alp Toker1a86ad22014-07-06 06:24:00 +00007049#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007050 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7051#endif
7052}
7053
7054void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7055 if (!Unit)
7056 return;
7057
7058 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7059 DEnd = Unit->stored_diag_end();
7060 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007061 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007062 CXString Msg = clang_formatDiagnostic(&Diag,
7063 clang_defaultDiagnosticDisplayOptions());
7064 fprintf(stderr, "%s\n", clang_getCString(Msg));
7065 clang_disposeString(Msg);
7066 }
7067#ifdef LLVM_ON_WIN32
7068 // On Windows, force a flush, since there may be multiple copies of
7069 // stderr and stdout in the file system, all with different buffers
7070 // but writing to the same device.
7071 fflush(stderr);
7072#endif
7073}
7074
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007075MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7076 SourceLocation MacroDefLoc,
7077 CXTranslationUnit TU){
7078 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007079 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007080 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007081 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007082
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007083 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007084 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007085 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007086 if (MD) {
7087 for (MacroDirective::DefInfo
7088 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7089 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7090 return Def.getMacroInfo();
7091 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007092 }
7093
Craig Topper69186e72014-06-08 08:38:04 +00007094 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007095}
7096
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007097const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7098 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007099 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007100 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007101 const IdentifierInfo *II = MacroDef->getName();
7102 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007103 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007104
7105 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7106}
7107
7108MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7109 const Token &Tok,
7110 CXTranslationUnit TU) {
7111 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007112 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007113 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007114 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007115
7116 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007117 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007118 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7119 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007120 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007121
7122 // Check that the token is inside the definition and not its argument list.
7123 SourceManager &SM = Unit->getSourceManager();
7124 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007125 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007126 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007127 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007128
7129 Preprocessor &PP = Unit->getPreprocessor();
7130 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7131 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007132 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007133
Alp Toker2d57cea2014-05-17 04:53:25 +00007134 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007135 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007136 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007137
7138 // Check that the identifier is not one of the macro arguments.
7139 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007140 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007141
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007142 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7143 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007144 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007145
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007146 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007147}
7148
7149MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7150 SourceLocation Loc,
7151 CXTranslationUnit TU) {
7152 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007153 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007154
7155 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007156 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007157 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007158 Preprocessor &PP = Unit->getPreprocessor();
7159 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007160 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007161 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7162 Token Tok;
7163 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007164 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007165
7166 return checkForMacroInMacroDefinition(MI, Tok, TU);
7167}
7168
Guy Benyei11169dd2012-12-18 14:30:41 +00007169extern "C" {
7170
7171CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007172 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007173}
7174
7175} // end: extern "C"
7176
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007177Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7178 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007179 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007180 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007181 if (Unit->isMainFileAST())
7182 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007183 return *this;
7184 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007185 } else {
7186 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007187 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007188 return *this;
7189}
7190
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007191Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7192 *this << FE->getName();
7193 return *this;
7194}
7195
7196Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7197 CXString cursorName = clang_getCursorDisplayName(cursor);
7198 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7199 clang_disposeString(cursorName);
7200 return *this;
7201}
7202
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007203Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7204 CXFile File;
7205 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007206 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007207 CXString FileName = clang_getFileName(File);
7208 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7209 clang_disposeString(FileName);
7210 return *this;
7211}
7212
7213Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7214 CXSourceLocation BLoc = clang_getRangeStart(range);
7215 CXSourceLocation ELoc = clang_getRangeEnd(range);
7216
7217 CXFile BFile;
7218 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007219 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007220
7221 CXFile EFile;
7222 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007223 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007224
7225 CXString BFileName = clang_getFileName(BFile);
7226 if (BFile == EFile) {
7227 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7228 BLine, BColumn, ELine, EColumn);
7229 } else {
7230 CXString EFileName = clang_getFileName(EFile);
7231 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7232 BLine, BColumn)
7233 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7234 ELine, EColumn);
7235 clang_disposeString(EFileName);
7236 }
7237 clang_disposeString(BFileName);
7238 return *this;
7239}
7240
7241Logger &cxindex::Logger::operator<<(CXString Str) {
7242 *this << clang_getCString(Str);
7243 return *this;
7244}
7245
7246Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7247 LogOS << Fmt;
7248 return *this;
7249}
7250
Chandler Carruth37ad2582014-06-27 15:14:39 +00007251static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7252
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007253cxindex::Logger::~Logger() {
7254 LogOS.flush();
7255
Chandler Carruth37ad2582014-06-27 15:14:39 +00007256 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007257
7258 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7259
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007260 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007261 OS << "[libclang:" << Name << ':';
7262
Alp Toker1a86ad22014-07-06 06:24:00 +00007263#ifdef USE_DARWIN_THREADS
7264 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007265 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7266 OS << tid << ':';
7267#endif
7268
7269 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7270 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007271 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007272
7273 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007274 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007275 OS << "--------------------------------------------------\n";
7276 }
7277}