blob: b8e44a2124c7fc48c8c06989c3b27542c84f0907 [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
243 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
244 Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
458
459 continue;
460 }
461
462 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
465
466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000572 if (MacroDefinition *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
667bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669 return Visit(TSInfo->getTypeLoc());
670
671 return false;
672}
673
674bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682 return VisitDeclContext(D);
683}
684
685bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686 ClassTemplateSpecializationDecl *D) {
687 bool ShouldVisitBody = false;
688 switch (D->getSpecializationKind()) {
689 case TSK_Undeclared:
690 case TSK_ImplicitInstantiation:
691 // Nothing to visit
692 return false;
693
694 case TSK_ExplicitInstantiationDeclaration:
695 case TSK_ExplicitInstantiationDefinition:
696 break;
697
698 case TSK_ExplicitSpecialization:
699 ShouldVisitBody = true;
700 break;
701 }
702
703 // Visit the template arguments used in the specialization.
704 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000706 if (TemplateSpecializationTypeLoc TSTLoc =
707 TL.getAs<TemplateSpecializationTypeLoc>()) {
708 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000710 return true;
711 }
712 }
713
714 if (ShouldVisitBody && VisitCXXRecordDecl(D))
715 return true;
716
717 return false;
718}
719
720bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721 ClassTemplatePartialSpecializationDecl *D) {
722 // FIXME: Visit the "outer" template parameter lists on the TagDecl
723 // before visiting these template parameters.
724 if (VisitTemplateParameters(D->getTemplateParameters()))
725 return true;
726
727 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000728 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732 return true;
733
734 return VisitCXXRecordDecl(D);
735}
736
737bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738 // Visit the default argument.
739 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741 if (Visit(DefArg->getTypeLoc()))
742 return true;
743
744 return false;
745}
746
747bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748 if (Expr *Init = D->getInitExpr())
749 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750 return false;
751}
752
753bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000754 unsigned NumParamList = DD->getNumTemplateParameterLists();
755 for (unsigned i = 0; i < NumParamList; i++) {
756 TemplateParameterList* Params = DD->getTemplateParameterList(i);
757 if (VisitTemplateParameters(Params))
758 return true;
759 }
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762 if (Visit(TSInfo->getTypeLoc()))
763 return true;
764
765 // Visit the nested-name-specifier, if present.
766 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
768 return true;
769
770 return false;
771}
772
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000773/// \brief Compare two base or member initializers based on their source order.
774static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775 CXXCtorInitializer *const *Y) {
776 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777}
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 unsigned NumParamList = ND->getNumTemplateParameterLists();
781 for (unsigned i = 0; i < NumParamList; i++) {
782 TemplateParameterList* Params = ND->getTemplateParameterList(i);
783 if (VisitTemplateParameters(Params))
784 return true;
785 }
786
Guy Benyei11169dd2012-12-18 14:30:41 +0000787 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788 // Visit the function declaration's syntactic components in the order
789 // written. This requires a bit of work.
790 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000791 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000792
793 // If we have a function declared directly (without the use of a typedef),
794 // visit just the return type. Otherwise, just visit the function's type
795 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000796 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000797 (!FTL && Visit(TL)))
798 return true;
799
800 // Visit the nested-name-specifier, if present.
801 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
803 return true;
804
805 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000806 if (!isa<CXXDestructorDecl>(ND))
807 if (VisitDeclarationNameInfo(ND->getNameInfo()))
808 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000809
810 // FIXME: Visit explicitly-specified template arguments!
811
812 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000813 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 return true;
815
Bill Wendling44426052012-12-20 19:22:21 +0000816 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 }
818
819 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821 // Find the initializers that were written in the source.
822 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 for (auto *I : Constructor->inits()) {
824 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 continue;
826
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 }
829
830 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000831 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832 &CompareCXXCtorInitializers);
833
Guy Benyei11169dd2012-12-18 14:30:41 +0000834 // Visit the initializers in source order
835 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836 CXXCtorInitializer *Init = WrittenInits[I];
837 if (Init->isAnyMemberInitializer()) {
838 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839 Init->getMemberLocation(), TU)))
840 return true;
841 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842 if (Visit(TInfo->getTypeLoc()))
843 return true;
844 }
845
846 // Visit the initializer value.
847 if (Expr *Initializer = Init->getInit())
848 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849 return true;
850 }
851 }
852
853 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854 return true;
855 }
856
857 return false;
858}
859
860bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861 if (VisitDeclaratorDecl(D))
862 return true;
863
864 if (Expr *BitWidth = D->getBitWidth())
865 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871 if (VisitDeclaratorDecl(D))
872 return true;
873
874 if (Expr *Init = D->getInit())
875 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876
877 return false;
878}
879
880bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881 if (VisitDeclaratorDecl(D))
882 return true;
883
884 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885 if (Expr *DefArg = D->getDefaultArgument())
886 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887
888 return false;
889}
890
891bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitFunctionDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901 // FIXME: Visit the "outer" template parameter lists on the TagDecl
902 // before visiting these template parameters.
903 if (VisitTemplateParameters(D->getTemplateParameters()))
904 return true;
905
906 return VisitCXXRecordDecl(D->getTemplatedDecl());
907}
908
909bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914 VisitTemplateArgumentLoc(D->getDefaultArgument()))
915 return true;
916
917 return false;
918}
919
920bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000921 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000922 if (Visit(TSInfo->getTypeLoc()))
923 return true;
924
Aaron Ballman43b68be2014-03-07 17:50:17 +0000925 for (const auto *P : ND->params()) {
926 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000927 return true;
928 }
929
930 if (ND->isThisDeclarationADefinition() &&
931 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
932 return true;
933
934 return false;
935}
936
937template <typename DeclIt>
938static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
939 SourceManager &SM, SourceLocation EndLoc,
940 SmallVectorImpl<Decl *> &Decls) {
941 DeclIt next = *DI_current;
942 while (++next != DE_current) {
943 Decl *D_next = *next;
944 if (!D_next)
945 break;
946 SourceLocation L = D_next->getLocStart();
947 if (!L.isValid())
948 break;
949 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
950 *DI_current = next;
951 Decls.push_back(D_next);
952 continue;
953 }
954 break;
955 }
956}
957
Guy Benyei11169dd2012-12-18 14:30:41 +0000958bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
959 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
960 // an @implementation can lexically contain Decls that are not properly
961 // nested in the AST. When we identify such cases, we need to retrofit
962 // this nesting here.
963 if (!DI_current && !FileDI_current)
964 return VisitDeclContext(D);
965
966 // Scan the Decls that immediately come after the container
967 // in the current DeclContext. If any fall within the
968 // container's lexical region, stash them into a vector
969 // for later processing.
970 SmallVector<Decl *, 24> DeclsInContainer;
971 SourceLocation EndLoc = D->getSourceRange().getEnd();
972 SourceManager &SM = AU->getSourceManager();
973 if (EndLoc.isValid()) {
974 if (DI_current) {
975 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
976 DeclsInContainer);
977 } else {
978 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
979 DeclsInContainer);
980 }
981 }
982
983 // The common case.
984 if (DeclsInContainer.empty())
985 return VisitDeclContext(D);
986
987 // Get all the Decls in the DeclContext, and sort them with the
988 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 for (auto *SubDecl : D->decls()) {
990 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
991 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000992 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000993 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000994 }
995
996 // Now sort the Decls so that they appear in lexical order.
997 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000998 [&SM](Decl *A, Decl *B) {
999 SourceLocation L_A = A->getLocStart();
1000 SourceLocation L_B = B->getLocStart();
1001 assert(L_A.isValid() && L_B.isValid());
1002 return SM.isBeforeInTranslationUnit(L_A, L_B);
1003 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001004
1005 // Now visit the decls.
1006 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1007 E = DeclsInContainer.end(); I != E; ++I) {
1008 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001009 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001010 if (!V.hasValue())
1011 continue;
1012 if (!V.getValue())
1013 return false;
1014 if (Visit(Cursor, true))
1015 return true;
1016 }
1017 return false;
1018}
1019
1020bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1021 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1022 TU)))
1023 return true;
1024
1025 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1026 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1027 E = ND->protocol_end(); I != E; ++I, ++PL)
1028 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1029 return true;
1030
1031 return VisitObjCContainerDecl(ND);
1032}
1033
1034bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1035 if (!PID->isThisDeclarationADefinition())
1036 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1037
1038 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1039 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1040 E = PID->protocol_end(); I != E; ++I, ++PL)
1041 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042 return true;
1043
1044 return VisitObjCContainerDecl(PID);
1045}
1046
1047bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1048 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1049 return true;
1050
1051 // FIXME: This implements a workaround with @property declarations also being
1052 // installed in the DeclContext for the @interface. Eventually this code
1053 // should be removed.
1054 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1055 if (!CDecl || !CDecl->IsClassExtension())
1056 return false;
1057
1058 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1059 if (!ID)
1060 return false;
1061
1062 IdentifierInfo *PropertyId = PD->getIdentifier();
1063 ObjCPropertyDecl *prevDecl =
1064 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1065
1066 if (!prevDecl)
1067 return false;
1068
1069 // Visit synthesized methods since they will be skipped when visiting
1070 // the @interface.
1071 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1072 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1073 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1074 return true;
1075
1076 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1077 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1078 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1079 return true;
1080
1081 return false;
1082}
1083
1084bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1085 if (!D->isThisDeclarationADefinition()) {
1086 // Forward declaration is treated like a reference.
1087 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1088 }
1089
1090 // Issue callbacks for super class.
1091 if (D->getSuperClass() &&
1092 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1093 D->getSuperClassLoc(),
1094 TU)))
1095 return true;
1096
1097 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1098 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1099 E = D->protocol_end(); I != E; ++I, ++PL)
1100 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1101 return true;
1102
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1107 return VisitObjCContainerDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1111 // 'ID' could be null when dealing with invalid code.
1112 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1113 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1114 return true;
1115
1116 return VisitObjCImplDecl(D);
1117}
1118
1119bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1120#if 0
1121 // Issue callbacks for super class.
1122 // FIXME: No source location information!
1123 if (D->getSuperClass() &&
1124 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125 D->getSuperClassLoc(),
1126 TU)))
1127 return true;
1128#endif
1129
1130 return VisitObjCImplDecl(D);
1131}
1132
1133bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1134 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1135 if (PD->isIvarNameSpecified())
1136 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1137
1138 return false;
1139}
1140
1141bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1142 return VisitDeclContext(D);
1143}
1144
1145bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1146 // Visit nested-name-specifier.
1147 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1148 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149 return true;
1150
1151 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1152 D->getTargetNameLoc(), TU));
1153}
1154
1155bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1156 // Visit nested-name-specifier.
1157 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1158 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1159 return true;
1160 }
1161
1162 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1163 return true;
1164
1165 return VisitDeclarationNameInfo(D->getNameInfo());
1166}
1167
1168bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1169 // Visit nested-name-specifier.
1170 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172 return true;
1173
1174 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1175 D->getIdentLocation(), TU));
1176}
1177
1178bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1179 // Visit nested-name-specifier.
1180 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1181 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1182 return true;
1183 }
1184
1185 return VisitDeclarationNameInfo(D->getNameInfo());
1186}
1187
1188bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1189 UnresolvedUsingTypenameDecl *D) {
1190 // Visit nested-name-specifier.
1191 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1192 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1193 return true;
1194
1195 return false;
1196}
1197
1198bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1199 switch (Name.getName().getNameKind()) {
1200 case clang::DeclarationName::Identifier:
1201 case clang::DeclarationName::CXXLiteralOperatorName:
1202 case clang::DeclarationName::CXXOperatorName:
1203 case clang::DeclarationName::CXXUsingDirective:
1204 return false;
1205
1206 case clang::DeclarationName::CXXConstructorName:
1207 case clang::DeclarationName::CXXDestructorName:
1208 case clang::DeclarationName::CXXConversionFunctionName:
1209 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1210 return Visit(TSInfo->getTypeLoc());
1211 return false;
1212
1213 case clang::DeclarationName::ObjCZeroArgSelector:
1214 case clang::DeclarationName::ObjCOneArgSelector:
1215 case clang::DeclarationName::ObjCMultiArgSelector:
1216 // FIXME: Per-identifier location info?
1217 return false;
1218 }
1219
1220 llvm_unreachable("Invalid DeclarationName::Kind!");
1221}
1222
1223bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1224 SourceRange Range) {
1225 // FIXME: This whole routine is a hack to work around the lack of proper
1226 // source information in nested-name-specifiers (PR5791). Since we do have
1227 // a beginning source location, we can visit the first component of the
1228 // nested-name-specifier, if it's a single-token component.
1229 if (!NNS)
1230 return false;
1231
1232 // Get the first component in the nested-name-specifier.
1233 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1234 NNS = Prefix;
1235
1236 switch (NNS->getKind()) {
1237 case NestedNameSpecifier::Namespace:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1239 TU));
1240
1241 case NestedNameSpecifier::NamespaceAlias:
1242 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1243 Range.getBegin(), TU));
1244
1245 case NestedNameSpecifier::TypeSpec: {
1246 // If the type has a form where we know that the beginning of the source
1247 // range matches up with a reference cursor. Visit the appropriate reference
1248 // cursor.
1249 const Type *T = NNS->getAsType();
1250 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1251 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1252 if (const TagType *Tag = dyn_cast<TagType>(T))
1253 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1254 if (const TemplateSpecializationType *TST
1255 = dyn_cast<TemplateSpecializationType>(T))
1256 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1257 break;
1258 }
1259
1260 case NestedNameSpecifier::TypeSpecWithTemplate:
1261 case NestedNameSpecifier::Global:
1262 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001263 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001264 break;
1265 }
1266
1267 return false;
1268}
1269
1270bool
1271CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1272 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1273 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1274 Qualifiers.push_back(Qualifier);
1275
1276 while (!Qualifiers.empty()) {
1277 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1278 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1279 switch (NNS->getKind()) {
1280 case NestedNameSpecifier::Namespace:
1281 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1282 Q.getLocalBeginLoc(),
1283 TU)))
1284 return true;
1285
1286 break;
1287
1288 case NestedNameSpecifier::NamespaceAlias:
1289 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1290 Q.getLocalBeginLoc(),
1291 TU)))
1292 return true;
1293
1294 break;
1295
1296 case NestedNameSpecifier::TypeSpec:
1297 case NestedNameSpecifier::TypeSpecWithTemplate:
1298 if (Visit(Q.getTypeLoc()))
1299 return true;
1300
1301 break;
1302
1303 case NestedNameSpecifier::Global:
1304 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001305 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001306 break;
1307 }
1308 }
1309
1310 return false;
1311}
1312
1313bool CursorVisitor::VisitTemplateParameters(
1314 const TemplateParameterList *Params) {
1315 if (!Params)
1316 return false;
1317
1318 for (TemplateParameterList::const_iterator P = Params->begin(),
1319 PEnd = Params->end();
1320 P != PEnd; ++P) {
1321 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1322 return true;
1323 }
1324
1325 return false;
1326}
1327
1328bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1329 switch (Name.getKind()) {
1330 case TemplateName::Template:
1331 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1332
1333 case TemplateName::OverloadedTemplate:
1334 // Visit the overloaded template set.
1335 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1336 return true;
1337
1338 return false;
1339
1340 case TemplateName::DependentTemplate:
1341 // FIXME: Visit nested-name-specifier.
1342 return false;
1343
1344 case TemplateName::QualifiedTemplate:
1345 // FIXME: Visit nested-name-specifier.
1346 return Visit(MakeCursorTemplateRef(
1347 Name.getAsQualifiedTemplateName()->getDecl(),
1348 Loc, TU));
1349
1350 case TemplateName::SubstTemplateTemplateParm:
1351 return Visit(MakeCursorTemplateRef(
1352 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1353 Loc, TU));
1354
1355 case TemplateName::SubstTemplateTemplateParmPack:
1356 return Visit(MakeCursorTemplateRef(
1357 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1358 Loc, TU));
1359 }
1360
1361 llvm_unreachable("Invalid TemplateName::Kind!");
1362}
1363
1364bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1365 switch (TAL.getArgument().getKind()) {
1366 case TemplateArgument::Null:
1367 case TemplateArgument::Integral:
1368 case TemplateArgument::Pack:
1369 return false;
1370
1371 case TemplateArgument::Type:
1372 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1373 return Visit(TSInfo->getTypeLoc());
1374 return false;
1375
1376 case TemplateArgument::Declaration:
1377 if (Expr *E = TAL.getSourceDeclExpression())
1378 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379 return false;
1380
1381 case TemplateArgument::NullPtr:
1382 if (Expr *E = TAL.getSourceNullPtrExpression())
1383 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1384 return false;
1385
1386 case TemplateArgument::Expression:
1387 if (Expr *E = TAL.getSourceExpression())
1388 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1389 return false;
1390
1391 case TemplateArgument::Template:
1392 case TemplateArgument::TemplateExpansion:
1393 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1394 return true;
1395
1396 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1397 TAL.getTemplateNameLoc());
1398 }
1399
1400 llvm_unreachable("Invalid TemplateArgument::Kind!");
1401}
1402
1403bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1404 return VisitDeclContext(D);
1405}
1406
1407bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1408 return Visit(TL.getUnqualifiedLoc());
1409}
1410
1411bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1412 ASTContext &Context = AU->getASTContext();
1413
1414 // Some builtin types (such as Objective-C's "id", "sel", and
1415 // "Class") have associated declarations. Create cursors for those.
1416 QualType VisitType;
1417 switch (TL.getTypePtr()->getKind()) {
1418
1419 case BuiltinType::Void:
1420 case BuiltinType::NullPtr:
1421 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001422 case BuiltinType::OCLImage1d:
1423 case BuiltinType::OCLImage1dArray:
1424 case BuiltinType::OCLImage1dBuffer:
1425 case BuiltinType::OCLImage2d:
1426 case BuiltinType::OCLImage2dArray:
1427 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001428 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001429 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001430#define BUILTIN_TYPE(Id, SingletonId)
1431#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1434#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1435#include "clang/AST/BuiltinTypes.def"
1436 break;
1437
1438 case BuiltinType::ObjCId:
1439 VisitType = Context.getObjCIdType();
1440 break;
1441
1442 case BuiltinType::ObjCClass:
1443 VisitType = Context.getObjCClassType();
1444 break;
1445
1446 case BuiltinType::ObjCSel:
1447 VisitType = Context.getObjCSelType();
1448 break;
1449 }
1450
1451 if (!VisitType.isNull()) {
1452 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1453 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1454 TU));
1455 }
1456
1457 return false;
1458}
1459
1460bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1461 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1465 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1466}
1467
1468bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1469 if (TL.isDefinition())
1470 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1471
1472 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1473}
1474
1475bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1476 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1477}
1478
1479bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1480 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1481 return true;
1482
1483 return false;
1484}
1485
1486bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1487 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1488 return true;
1489
1490 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1491 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1492 TU)))
1493 return true;
1494 }
1495
1496 return false;
1497}
1498
1499bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1500 return Visit(TL.getPointeeLoc());
1501}
1502
1503bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1504 return Visit(TL.getInnerLoc());
1505}
1506
1507bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1520 return Visit(TL.getPointeeLoc());
1521}
1522
1523bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1524 return Visit(TL.getPointeeLoc());
1525}
1526
1527bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1528 return Visit(TL.getModifiedLoc());
1529}
1530
1531bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1532 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001533 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001534 return true;
1535
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001536 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1537 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001538 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1539 return true;
1540
1541 return false;
1542}
1543
1544bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1545 if (Visit(TL.getElementLoc()))
1546 return true;
1547
1548 if (Expr *Size = TL.getSizeExpr())
1549 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1550
1551 return false;
1552}
1553
Reid Kleckner8a365022013-06-24 17:51:48 +00001554bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1555 return Visit(TL.getOriginalLoc());
1556}
1557
Reid Kleckner0503a872013-12-05 01:23:43 +00001558bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1559 return Visit(TL.getOriginalLoc());
1560}
1561
Guy Benyei11169dd2012-12-18 14:30:41 +00001562bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1563 TemplateSpecializationTypeLoc TL) {
1564 // Visit the template name.
1565 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1566 TL.getTemplateNameLoc()))
1567 return true;
1568
1569 // Visit the template arguments.
1570 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1571 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1572 return true;
1573
1574 return false;
1575}
1576
1577bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1578 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1579}
1580
1581bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1582 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1583 return Visit(TSInfo->getTypeLoc());
1584
1585 return false;
1586}
1587
1588bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1589 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1590 return Visit(TSInfo->getTypeLoc());
1591
1592 return false;
1593}
1594
1595bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1596 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1597 return true;
1598
1599 return false;
1600}
1601
1602bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1603 DependentTemplateSpecializationTypeLoc TL) {
1604 // Visit the nested-name-specifier, if there is one.
1605 if (TL.getQualifierLoc() &&
1606 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1607 return true;
1608
1609 // Visit the template arguments.
1610 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1611 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1612 return true;
1613
1614 return false;
1615}
1616
1617bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1618 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1619 return true;
1620
1621 return Visit(TL.getNamedTypeLoc());
1622}
1623
1624bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1625 return Visit(TL.getPatternLoc());
1626}
1627
1628bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1629 if (Expr *E = TL.getUnderlyingExpr())
1630 return Visit(MakeCXCursor(E, StmtParent, TU));
1631
1632 return false;
1633}
1634
1635bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1636 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1637}
1638
1639bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1640 return Visit(TL.getValueLoc());
1641}
1642
1643#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1644bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1645 return Visit##PARENT##Loc(TL); \
1646}
1647
1648DEFAULT_TYPELOC_IMPL(Complex, Type)
1649DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1652DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1653DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1654DEFAULT_TYPELOC_IMPL(Vector, Type)
1655DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1656DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1657DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1658DEFAULT_TYPELOC_IMPL(Record, TagType)
1659DEFAULT_TYPELOC_IMPL(Enum, TagType)
1660DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1661DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1662DEFAULT_TYPELOC_IMPL(Auto, Type)
1663
1664bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1665 // Visit the nested-name-specifier, if present.
1666 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1667 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1668 return true;
1669
1670 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001671 for (const auto &I : D->bases()) {
1672 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001673 return true;
1674 }
1675 }
1676
1677 return VisitTagDecl(D);
1678}
1679
1680bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001681 for (const auto *I : D->attrs())
1682 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001683 return true;
1684
1685 return false;
1686}
1687
1688//===----------------------------------------------------------------------===//
1689// Data-recursive visitor methods.
1690//===----------------------------------------------------------------------===//
1691
1692namespace {
1693#define DEF_JOB(NAME, DATA, KIND)\
1694class NAME : public VisitorJob {\
1695public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001696 NAME(const DATA *d, CXCursor parent) : \
1697 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001698 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001699 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001700};
1701
1702DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1703DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1704DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1705DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1706DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1707 ExplicitTemplateArgsVisitKind)
1708DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1709DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1710DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1711#undef DEF_JOB
1712
1713class DeclVisit : public VisitorJob {
1714public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001717 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001718 static bool classof(const VisitorJob *VJ) {
1719 return VJ->getKind() == DeclVisitKind;
1720 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001721 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001722 bool isFirst() const { return data[1] ? true : false; }
1723};
1724class TypeLocVisit : public VisitorJob {
1725public:
1726 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1727 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1728 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1729
1730 static bool classof(const VisitorJob *VJ) {
1731 return VJ->getKind() == TypeLocVisitKind;
1732 }
1733
1734 TypeLoc get() const {
1735 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001736 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001737 }
1738};
1739
1740class LabelRefVisit : public VisitorJob {
1741public:
1742 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1743 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1744 labelLoc.getPtrEncoding()) {}
1745
1746 static bool classof(const VisitorJob *VJ) {
1747 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1748 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001749 const LabelDecl *get() const {
1750 return static_cast<const LabelDecl *>(data[0]);
1751 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001752 SourceLocation getLoc() const {
1753 return SourceLocation::getFromPtrEncoding(data[1]); }
1754};
1755
1756class NestedNameSpecifierLocVisit : public VisitorJob {
1757public:
1758 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1759 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1760 Qualifier.getNestedNameSpecifier(),
1761 Qualifier.getOpaqueData()) { }
1762
1763 static bool classof(const VisitorJob *VJ) {
1764 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1765 }
1766
1767 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001768 return NestedNameSpecifierLoc(
1769 const_cast<NestedNameSpecifier *>(
1770 static_cast<const NestedNameSpecifier *>(data[0])),
1771 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001772 }
1773};
1774
1775class DeclarationNameInfoVisit : public VisitorJob {
1776public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001778 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001779 static bool classof(const VisitorJob *VJ) {
1780 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1781 }
1782 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001783 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001784 switch (S->getStmtClass()) {
1785 default:
1786 llvm_unreachable("Unhandled Stmt");
1787 case clang::Stmt::MSDependentExistsStmtClass:
1788 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1789 case Stmt::CXXDependentScopeMemberExprClass:
1790 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1791 case Stmt::DependentScopeDeclRefExprClass:
1792 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001793 case Stmt::OMPCriticalDirectiveClass:
1794 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 }
1796 }
1797};
1798class MemberRefVisit : public VisitorJob {
1799public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001801 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1802 L.getPtrEncoding()) {}
1803 static bool classof(const VisitorJob *VJ) {
1804 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1805 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001806 const FieldDecl *get() const {
1807 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001808 }
1809 SourceLocation getLoc() const {
1810 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1811 }
1812};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001814 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001815 VisitorWorkList &WL;
1816 CXCursor Parent;
1817public:
1818 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1819 : WL(wl), Parent(parent) {}
1820
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001821 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1822 void VisitBlockExpr(const BlockExpr *B);
1823 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1824 void VisitCompoundStmt(const CompoundStmt *S);
1825 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1826 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1827 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1828 void VisitCXXNewExpr(const CXXNewExpr *E);
1829 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1830 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1831 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1832 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1833 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1834 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1835 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1836 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001837 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001838 void VisitDeclRefExpr(const DeclRefExpr *D);
1839 void VisitDeclStmt(const DeclStmt *S);
1840 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1841 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1842 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1843 void VisitForStmt(const ForStmt *FS);
1844 void VisitGotoStmt(const GotoStmt *GS);
1845 void VisitIfStmt(const IfStmt *If);
1846 void VisitInitListExpr(const InitListExpr *IE);
1847 void VisitMemberExpr(const MemberExpr *M);
1848 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1849 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1850 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1851 void VisitOverloadExpr(const OverloadExpr *E);
1852 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1853 void VisitStmt(const Stmt *S);
1854 void VisitSwitchStmt(const SwitchStmt *S);
1855 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001856 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1857 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1858 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1859 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1860 void VisitVAArgExpr(const VAArgExpr *E);
1861 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1862 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1863 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1864 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001865 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001866 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001867 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001868 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001869 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001870 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001871 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001872 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001873 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001874 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001875 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001876 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001877 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001878 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001879 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001880 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001881 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001882 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001883 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001884 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001885 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001886 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001887 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888
Guy Benyei11169dd2012-12-18 14:30:41 +00001889private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1892 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1894 void AddStmt(const Stmt *S);
1895 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001896 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001898 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001899};
1900} // end anonyous namespace
1901
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 // 'S' should always be non-null, since it comes from the
1904 // statement we are visiting.
1905 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1906}
1907
1908void
1909EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1910 if (Qualifier)
1911 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1912}
1913
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001914void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001915 if (S)
1916 WL.push_back(StmtVisit(S, Parent));
1917}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001918void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001919 if (D)
1920 WL.push_back(DeclVisit(D, Parent, isFirst));
1921}
1922void EnqueueVisitor::
1923 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1924 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001925 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001926}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001927void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001928 if (D)
1929 WL.push_back(MemberRefVisit(D, L, Parent));
1930}
1931void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1932 if (TI)
1933 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1934 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001935void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001936 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001937 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001938 AddStmt(*Child);
1939 }
1940 if (size == WL.size())
1941 return;
1942 // Now reverse the entries we just added. This will match the DFS
1943 // ordering performed by the worklist.
1944 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1945 std::reverse(I, E);
1946}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947namespace {
1948class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1949 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001950 /// \brief Process clauses with list of variables.
1951 template <typename T>
1952 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001953public:
1954 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1955#define OPENMP_CLAUSE(Name, Class) \
1956 void Visit##Class(const Class *C);
1957#include "clang/Basic/OpenMPKinds.def"
1958};
1959
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001960void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1961 Visitor->AddStmt(C->getCondition());
1962}
1963
Alexey Bataev3778b602014-07-17 07:32:53 +00001964void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1965 Visitor->AddStmt(C->getCondition());
1966}
1967
Alexey Bataev568a8332014-03-06 06:15:19 +00001968void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1969 Visitor->AddStmt(C->getNumThreads());
1970}
1971
Alexey Bataev62c87d22014-03-21 04:51:18 +00001972void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1973 Visitor->AddStmt(C->getSafelen());
1974}
1975
Alexander Musman8bd31e62014-05-27 15:12:19 +00001976void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1977 Visitor->AddStmt(C->getNumForLoops());
1978}
1979
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001980void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001981
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001982void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1983
Alexey Bataev56dafe82014-06-20 07:16:17 +00001984void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1985 Visitor->AddStmt(C->getChunkSize());
1986}
1987
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001988void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1989
Alexey Bataev236070f2014-06-20 11:19:47 +00001990void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1991
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001992void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1993
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001994void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1995
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001996void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1997
Alexey Bataevdea47612014-07-23 07:46:59 +00001998void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1999
Alexey Bataev67a4f222014-07-23 10:25:33 +00002000void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2001
Alexey Bataev459dec02014-07-24 06:46:57 +00002002void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2003
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002004void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2005
Alexey Bataev756c1962013-09-24 03:17:45 +00002006template<typename T>
2007void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002008 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002009 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002010 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002011}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002012
2013void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002014 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002015 for (const auto *E : C->private_copies()) {
2016 Visitor->AddStmt(E);
2017 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002018}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002019void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2020 const OMPFirstprivateClause *C) {
2021 VisitOMPClauseList(C);
2022}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002023void OMPClauseEnqueue::VisitOMPLastprivateClause(
2024 const OMPLastprivateClause *C) {
2025 VisitOMPClauseList(C);
2026}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002027void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002028 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002029}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002030void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2031 VisitOMPClauseList(C);
2032}
Alexander Musman8dba6642014-04-22 13:09:42 +00002033void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2034 VisitOMPClauseList(C);
2035 Visitor->AddStmt(C->getStep());
2036}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002037void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2038 VisitOMPClauseList(C);
2039 Visitor->AddStmt(C->getAlignment());
2040}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002041void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2042 VisitOMPClauseList(C);
2043}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002044void
2045OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2046 VisitOMPClauseList(C);
2047}
Alexey Bataev6125da92014-07-21 11:26:11 +00002048void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2049 VisitOMPClauseList(C);
2050}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002051}
Alexey Bataev756c1962013-09-24 03:17:45 +00002052
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002053void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2054 unsigned size = WL.size();
2055 OMPClauseEnqueue Visitor(this);
2056 Visitor.Visit(S);
2057 if (size == WL.size())
2058 return;
2059 // Now reverse the entries we just added. This will match the DFS
2060 // ordering performed by the worklist.
2061 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2062 std::reverse(I, E);
2063}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002065 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2066}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002067void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 AddDecl(B->getBlockDecl());
2069}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002070void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002071 EnqueueChildren(E);
2072 AddTypeLoc(E->getTypeSourceInfo());
2073}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002074void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2075 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002076 E = S->body_rend(); I != E; ++I) {
2077 AddStmt(*I);
2078 }
2079}
2080void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 AddStmt(S->getSubStmt());
2083 AddDeclarationNameInfo(S);
2084 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2085 AddNestedNameSpecifierLoc(QualifierLoc);
2086}
2087
2088void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002089VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002090 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2091 AddDeclarationNameInfo(E);
2092 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2093 AddNestedNameSpecifierLoc(QualifierLoc);
2094 if (!E->isImplicitAccess())
2095 AddStmt(E->getBase());
2096}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 // Enqueue the initializer , if any.
2099 AddStmt(E->getInitializer());
2100 // Enqueue the array size, if any.
2101 AddStmt(E->getArraySize());
2102 // Enqueue the allocated type.
2103 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2104 // Enqueue the placement arguments.
2105 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2106 AddStmt(E->getPlacementArg(I-1));
2107}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002109 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2110 AddStmt(CE->getArg(I-1));
2111 AddStmt(CE->getCallee());
2112 AddStmt(CE->getArg(0));
2113}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002114void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2115 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 // Visit the name of the type being destroyed.
2117 AddTypeLoc(E->getDestroyedTypeInfo());
2118 // Visit the scope type that looks disturbingly like the nested-name-specifier
2119 // but isn't.
2120 AddTypeLoc(E->getScopeTypeInfo());
2121 // Visit the nested-name-specifier.
2122 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2123 AddNestedNameSpecifierLoc(QualifierLoc);
2124 // Visit base expression.
2125 AddStmt(E->getBase());
2126}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002127void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2128 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002129 AddTypeLoc(E->getTypeSourceInfo());
2130}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2132 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 EnqueueChildren(E);
2134 AddTypeLoc(E->getTypeSourceInfo());
2135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 EnqueueChildren(E);
2138 if (E->isTypeOperand())
2139 AddTypeLoc(E->getTypeOperandSourceInfo());
2140}
2141
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2143 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002144 EnqueueChildren(E);
2145 AddTypeLoc(E->getTypeSourceInfo());
2146}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 EnqueueChildren(E);
2149 if (E->isTypeOperand())
2150 AddTypeLoc(E->getTypeOperandSourceInfo());
2151}
2152
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 EnqueueChildren(S);
2155 AddDecl(S->getExceptionDecl());
2156}
2157
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002158void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002159 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002160 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002161 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002162}
2163
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 if (DR->hasExplicitTemplateArgs()) {
2166 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2167 }
2168 WL.push_back(DeclRefExprParts(DR, Parent));
2169}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002170void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2171 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2173 AddDeclarationNameInfo(E);
2174 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2175}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002176void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002177 unsigned size = WL.size();
2178 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002179 for (const auto *D : S->decls()) {
2180 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 isFirst = false;
2182 }
2183 if (size == WL.size())
2184 return;
2185 // Now reverse the entries we just added. This will match the DFS
2186 // ordering performed by the worklist.
2187 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2188 std::reverse(I, E);
2189}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 D = E->designators_rbegin(), DEnd = E->designators_rend();
2194 D != DEnd; ++D) {
2195 if (D->isFieldDesignator()) {
2196 if (FieldDecl *Field = D->getField())
2197 AddMemberRef(Field, D->getFieldLoc());
2198 continue;
2199 }
2200 if (D->isArrayDesignator()) {
2201 AddStmt(E->getArrayIndex(*D));
2202 continue;
2203 }
2204 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2205 AddStmt(E->getArrayRangeEnd(*D));
2206 AddStmt(E->getArrayRangeStart(*D));
2207 }
2208}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 EnqueueChildren(E);
2211 AddTypeLoc(E->getTypeInfoAsWritten());
2212}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 AddStmt(FS->getBody());
2215 AddStmt(FS->getInc());
2216 AddStmt(FS->getCond());
2217 AddDecl(FS->getConditionVariable());
2218 AddStmt(FS->getInit());
2219}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2222}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002223void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002224 AddStmt(If->getElse());
2225 AddStmt(If->getThen());
2226 AddStmt(If->getCond());
2227 AddDecl(If->getConditionVariable());
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 // We care about the syntactic form of the initializer list, only.
2231 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2232 IE = Syntactic;
2233 EnqueueChildren(IE);
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 WL.push_back(MemberExprParts(M, Parent));
2237
2238 // If the base of the member access expression is an implicit 'this', don't
2239 // visit it.
2240 // FIXME: If we ever want to show these implicit accesses, this will be
2241 // unfortunate. However, clang_getCursor() relies on this behavior.
2242 if (!M->isImplicitAccess())
2243 AddStmt(M->getBase());
2244}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002246 AddTypeLoc(E->getEncodedTypeSourceInfo());
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 EnqueueChildren(M);
2250 AddTypeLoc(M->getClassReceiverTypeInfo());
2251}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 // Visit the components of the offsetof expression.
2254 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2255 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2256 const OffsetOfNode &Node = E->getComponent(I-1);
2257 switch (Node.getKind()) {
2258 case OffsetOfNode::Array:
2259 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2260 break;
2261 case OffsetOfNode::Field:
2262 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2263 break;
2264 case OffsetOfNode::Identifier:
2265 case OffsetOfNode::Base:
2266 continue;
2267 }
2268 }
2269 // Visit the type into which we're computing the offset.
2270 AddTypeLoc(E->getTypeSourceInfo());
2271}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002272void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002273 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2274 WL.push_back(OverloadExprParts(E, Parent));
2275}
2276void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 EnqueueChildren(E);
2279 if (E->isArgumentType())
2280 AddTypeLoc(E->getArgumentTypeInfo());
2281}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002283 EnqueueChildren(S);
2284}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 AddStmt(S->getBody());
2287 AddStmt(S->getCond());
2288 AddDecl(S->getConditionVariable());
2289}
2290
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 AddStmt(W->getBody());
2293 AddStmt(W->getCond());
2294 AddDecl(W->getConditionVariable());
2295}
2296
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002298 for (unsigned I = E->getNumArgs(); I > 0; --I)
2299 AddTypeLoc(E->getArg(I-1));
2300}
2301
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002302void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 AddTypeLoc(E->getQueriedTypeSourceInfo());
2304}
2305
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002306void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002307 EnqueueChildren(E);
2308}
2309
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 VisitOverloadExpr(U);
2312 if (!U->isImplicitAccess())
2313 AddStmt(U->getBase());
2314}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002315void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 AddStmt(E->getSubExpr());
2317 AddTypeLoc(E->getWrittenTypeInfo());
2318}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002319void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 WL.push_back(SizeOfPackExprParts(E, Parent));
2321}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002322void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 // If the opaque value has a source expression, just transparently
2324 // visit that. This is useful for (e.g.) pseudo-object expressions.
2325 if (Expr *SourceExpr = E->getSourceExpr())
2326 return Visit(SourceExpr);
2327}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002328void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002329 AddStmt(E->getBody());
2330 WL.push_back(LambdaExprParts(E, Parent));
2331}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002332void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 // Treat the expression like its syntactic form.
2334 Visit(E->getSyntacticForm());
2335}
2336
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002337void EnqueueVisitor::VisitOMPExecutableDirective(
2338 const OMPExecutableDirective *D) {
2339 EnqueueChildren(D);
2340 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2341 E = D->clauses().end();
2342 I != E; ++I)
2343 EnqueueChildren(*I);
2344}
2345
Alexander Musman3aaab662014-08-19 11:27:13 +00002346void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2347 VisitOMPExecutableDirective(D);
2348}
2349
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002350void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2351 VisitOMPExecutableDirective(D);
2352}
2353
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002354void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002355 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002356}
2357
Alexey Bataevf29276e2014-06-18 04:14:57 +00002358void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002359 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002360}
2361
Alexander Musmanf82886e2014-09-18 05:12:34 +00002362void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2363 VisitOMPLoopDirective(D);
2364}
2365
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002366void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2367 VisitOMPExecutableDirective(D);
2368}
2369
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002370void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2371 VisitOMPExecutableDirective(D);
2372}
2373
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002374void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2375 VisitOMPExecutableDirective(D);
2376}
2377
Alexander Musman80c22892014-07-17 08:54:58 +00002378void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2379 VisitOMPExecutableDirective(D);
2380}
2381
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002382void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2383 VisitOMPExecutableDirective(D);
2384 AddDeclarationNameInfo(D);
2385}
2386
Alexey Bataev4acb8592014-07-07 13:01:15 +00002387void
2388EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002389 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002390}
2391
Alexander Musmane4e893b2014-09-23 09:33:00 +00002392void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2393 const OMPParallelForSimdDirective *D) {
2394 VisitOMPLoopDirective(D);
2395}
2396
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002397void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2398 const OMPParallelSectionsDirective *D) {
2399 VisitOMPExecutableDirective(D);
2400}
2401
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002402void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2403 VisitOMPExecutableDirective(D);
2404}
2405
Alexey Bataev68446b72014-07-18 07:47:19 +00002406void
2407EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2408 VisitOMPExecutableDirective(D);
2409}
2410
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002411void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2412 VisitOMPExecutableDirective(D);
2413}
2414
Alexey Bataev2df347a2014-07-18 10:17:07 +00002415void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2416 VisitOMPExecutableDirective(D);
2417}
2418
Alexey Bataev6125da92014-07-21 11:26:11 +00002419void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2420 VisitOMPExecutableDirective(D);
2421}
2422
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002423void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2424 VisitOMPExecutableDirective(D);
2425}
2426
Alexey Bataev0162e452014-07-22 10:10:35 +00002427void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2428 VisitOMPExecutableDirective(D);
2429}
2430
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002431void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2432 VisitOMPExecutableDirective(D);
2433}
2434
Alexey Bataev13314bf2014-10-09 04:18:56 +00002435void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2436 VisitOMPExecutableDirective(D);
2437}
2438
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002439void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002440 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2441}
2442
2443bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2444 if (RegionOfInterest.isValid()) {
2445 SourceRange Range = getRawCursorExtent(C);
2446 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2447 return false;
2448 }
2449 return true;
2450}
2451
2452bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2453 while (!WL.empty()) {
2454 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002455 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002456
2457 // Set the Parent field, then back to its old value once we're done.
2458 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2459
2460 switch (LI.getKind()) {
2461 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002462 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 if (!D)
2464 continue;
2465
2466 // For now, perform default visitation for Decls.
2467 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2468 cast<DeclVisit>(&LI)->isFirst())))
2469 return true;
2470
2471 continue;
2472 }
2473 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2474 const ASTTemplateArgumentListInfo *ArgList =
2475 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2476 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2477 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2478 Arg != ArgEnd; ++Arg) {
2479 if (VisitTemplateArgumentLoc(*Arg))
2480 return true;
2481 }
2482 continue;
2483 }
2484 case VisitorJob::TypeLocVisitKind: {
2485 // Perform default visitation for TypeLocs.
2486 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2487 return true;
2488 continue;
2489 }
2490 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002491 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002492 if (LabelStmt *stmt = LS->getStmt()) {
2493 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2494 TU))) {
2495 return true;
2496 }
2497 }
2498 continue;
2499 }
2500
2501 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2502 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2503 if (VisitNestedNameSpecifierLoc(V->get()))
2504 return true;
2505 continue;
2506 }
2507
2508 case VisitorJob::DeclarationNameInfoVisitKind: {
2509 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2510 ->get()))
2511 return true;
2512 continue;
2513 }
2514 case VisitorJob::MemberRefVisitKind: {
2515 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2516 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2517 return true;
2518 continue;
2519 }
2520 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002521 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002522 if (!S)
2523 continue;
2524
2525 // Update the current cursor.
2526 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2527 if (!IsInRegionOfInterest(Cursor))
2528 continue;
2529 switch (Visitor(Cursor, Parent, ClientData)) {
2530 case CXChildVisit_Break: return true;
2531 case CXChildVisit_Continue: break;
2532 case CXChildVisit_Recurse:
2533 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002534 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002535 EnqueueWorkList(WL, S);
2536 break;
2537 }
2538 continue;
2539 }
2540 case VisitorJob::MemberExprPartsKind: {
2541 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002542 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002543
2544 // Visit the nested-name-specifier
2545 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2546 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2547 return true;
2548
2549 // Visit the declaration name.
2550 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2551 return true;
2552
2553 // Visit the explicitly-specified template arguments, if any.
2554 if (M->hasExplicitTemplateArgs()) {
2555 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2556 *ArgEnd = Arg + M->getNumTemplateArgs();
2557 Arg != ArgEnd; ++Arg) {
2558 if (VisitTemplateArgumentLoc(*Arg))
2559 return true;
2560 }
2561 }
2562 continue;
2563 }
2564 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002565 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002566 // Visit nested-name-specifier, if present.
2567 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2568 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2569 return true;
2570 // Visit declaration name.
2571 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2572 return true;
2573 continue;
2574 }
2575 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002576 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002577 // Visit the nested-name-specifier.
2578 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2579 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2580 return true;
2581 // Visit the declaration name.
2582 if (VisitDeclarationNameInfo(O->getNameInfo()))
2583 return true;
2584 // Visit the overloaded declaration reference.
2585 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2586 return true;
2587 continue;
2588 }
2589 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002590 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002591 NamedDecl *Pack = E->getPack();
2592 if (isa<TemplateTypeParmDecl>(Pack)) {
2593 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2594 E->getPackLoc(), TU)))
2595 return true;
2596
2597 continue;
2598 }
2599
2600 if (isa<TemplateTemplateParmDecl>(Pack)) {
2601 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2602 E->getPackLoc(), TU)))
2603 return true;
2604
2605 continue;
2606 }
2607
2608 // Non-type template parameter packs and function parameter packs are
2609 // treated like DeclRefExpr cursors.
2610 continue;
2611 }
2612
2613 case VisitorJob::LambdaExprPartsKind: {
2614 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002615 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002616 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2617 CEnd = E->explicit_capture_end();
2618 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002619 // FIXME: Lambda init-captures.
2620 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002621 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002622
Guy Benyei11169dd2012-12-18 14:30:41 +00002623 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2624 C->getLocation(),
2625 TU)))
2626 return true;
2627 }
2628
2629 // Visit parameters and return type, if present.
2630 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2631 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2632 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2633 // Visit the whole type.
2634 if (Visit(TL))
2635 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002636 } else if (FunctionProtoTypeLoc Proto =
2637 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002638 if (E->hasExplicitParameters()) {
2639 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002640 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2641 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002642 return true;
2643 } else {
2644 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002645 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002646 return true;
2647 }
2648 }
2649 }
2650 break;
2651 }
2652
2653 case VisitorJob::PostChildrenVisitKind:
2654 if (PostChildrenVisitor(Parent, ClientData))
2655 return true;
2656 break;
2657 }
2658 }
2659 return false;
2660}
2661
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002662bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002663 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002664 if (!WorkListFreeList.empty()) {
2665 WL = WorkListFreeList.back();
2666 WL->clear();
2667 WorkListFreeList.pop_back();
2668 }
2669 else {
2670 WL = new VisitorWorkList();
2671 WorkListCache.push_back(WL);
2672 }
2673 EnqueueWorkList(*WL, S);
2674 bool result = RunVisitorWorkList(*WL);
2675 WorkListFreeList.push_back(WL);
2676 return result;
2677}
2678
2679namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002680typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002681RefNamePieces
2682buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2683 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2684 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002685 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2686 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2687 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2688
2689 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2690
2691 RefNamePieces Pieces;
2692
2693 if (WantQualifier && QLoc.isValid())
2694 Pieces.push_back(QLoc);
2695
2696 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2697 Pieces.push_back(NI.getLoc());
2698
2699 if (WantTemplateArgs && TemplateArgs)
2700 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2701 TemplateArgs->RAngleLoc));
2702
2703 if (Kind == DeclarationName::CXXOperatorName) {
2704 Pieces.push_back(SourceLocation::getFromRawEncoding(
2705 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2706 Pieces.push_back(SourceLocation::getFromRawEncoding(
2707 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2708 }
2709
2710 if (WantSinglePiece) {
2711 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2712 Pieces.clear();
2713 Pieces.push_back(R);
2714 }
2715
2716 return Pieces;
2717}
2718}
2719
2720//===----------------------------------------------------------------------===//
2721// Misc. API hooks.
2722//===----------------------------------------------------------------------===//
2723
Chad Rosier05c71aa2013-03-27 18:28:23 +00002724static void fatal_error_handler(void *user_data, const std::string& reason,
2725 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002726 // Write the result out to stderr avoiding errs() because raw_ostreams can
2727 // call report_fatal_error.
2728 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2729 ::abort();
2730}
2731
Chandler Carruth66660742014-06-27 16:37:27 +00002732namespace {
2733struct RegisterFatalErrorHandler {
2734 RegisterFatalErrorHandler() {
2735 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2736 }
2737};
2738}
2739
2740static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2741
Guy Benyei11169dd2012-12-18 14:30:41 +00002742extern "C" {
2743CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2744 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002745 // We use crash recovery to make some of our APIs more reliable, implicitly
2746 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002747 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2748 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002749
Chandler Carruth66660742014-06-27 16:37:27 +00002750 // Look through the managed static to trigger construction of the managed
2751 // static which registers our fatal error handler. This ensures it is only
2752 // registered once.
2753 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002754
2755 CIndexer *CIdxr = new CIndexer();
2756 if (excludeDeclarationsFromPCH)
2757 CIdxr->setOnlyLocalDecls();
2758 if (displayDiagnostics)
2759 CIdxr->setDisplayDiagnostics();
2760
2761 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2762 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2763 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2764 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2765 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2766 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2767
2768 return CIdxr;
2769}
2770
2771void clang_disposeIndex(CXIndex CIdx) {
2772 if (CIdx)
2773 delete static_cast<CIndexer *>(CIdx);
2774}
2775
2776void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2777 if (CIdx)
2778 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2779}
2780
2781unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2782 if (CIdx)
2783 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2784 return 0;
2785}
2786
2787void clang_toggleCrashRecovery(unsigned isEnabled) {
2788 if (isEnabled)
2789 llvm::CrashRecoveryContext::Enable();
2790 else
2791 llvm::CrashRecoveryContext::Disable();
2792}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002793
Guy Benyei11169dd2012-12-18 14:30:41 +00002794CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2795 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002796 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002797 enum CXErrorCode Result =
2798 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002799 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002800 assert((TU && Result == CXError_Success) ||
2801 (!TU && Result != CXError_Success));
2802 return TU;
2803}
2804
2805enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2806 const char *ast_filename,
2807 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002808 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002809 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002810
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002811 if (!CIdx || !ast_filename || !out_TU)
2812 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002813
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002814 LOG_FUNC_SECTION {
2815 *Log << ast_filename;
2816 }
2817
Guy Benyei11169dd2012-12-18 14:30:41 +00002818 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2819 FileSystemOptions FileSystemOpts;
2820
Justin Bognerd512c1e2014-10-15 00:33:06 +00002821 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2822 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002823 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2824 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2825 /*CaptureDiagnostics=*/true,
2826 /*AllowPCHWithCompilerErrors=*/true,
2827 /*UserFilesAreVolatile=*/true);
2828 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002829 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002830}
2831
2832unsigned clang_defaultEditingTranslationUnitOptions() {
2833 return CXTranslationUnit_PrecompiledPreamble |
2834 CXTranslationUnit_CacheCompletionResults;
2835}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002836
Guy Benyei11169dd2012-12-18 14:30:41 +00002837CXTranslationUnit
2838clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2839 const char *source_filename,
2840 int num_command_line_args,
2841 const char * const *command_line_args,
2842 unsigned num_unsaved_files,
2843 struct CXUnsavedFile *unsaved_files) {
2844 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2845 return clang_parseTranslationUnit(CIdx, source_filename,
2846 command_line_args, num_command_line_args,
2847 unsaved_files, num_unsaved_files,
2848 Options);
2849}
2850
2851struct ParseTranslationUnitInfo {
2852 CXIndex CIdx;
2853 const char *source_filename;
2854 const char *const *command_line_args;
2855 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002856 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002857 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002858 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002859 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002860};
2861static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002862 const ParseTranslationUnitInfo *PTUI =
2863 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002864 CXIndex CIdx = PTUI->CIdx;
2865 const char *source_filename = PTUI->source_filename;
2866 const char * const *command_line_args = PTUI->command_line_args;
2867 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002868 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002869 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002870
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002871 // Set up the initial return values.
2872 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002873 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002874
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002875 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002876 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002877 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002878 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002879 }
2880
Guy Benyei11169dd2012-12-18 14:30:41 +00002881 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2882
2883 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2884 setThreadBackgroundPriority();
2885
2886 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2887 // FIXME: Add a flag for modules.
2888 TranslationUnitKind TUKind
2889 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002890 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002891 = options & CXTranslationUnit_CacheCompletionResults;
2892 bool IncludeBriefCommentsInCodeCompletion
2893 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2894 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2895 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2896
2897 // Configure the diagnostics.
2898 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002899 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002900
2901 // Recover resources if we crash before exiting this function.
2902 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2903 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002904 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002905
Ahmed Charlesb8984322014-03-07 20:03:18 +00002906 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2907 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002908
2909 // Recover resources if we crash before exiting this function.
2910 llvm::CrashRecoveryContextCleanupRegistrar<
2911 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2912
Alp Toker9d85b182014-07-07 01:23:14 +00002913 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002914 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002915 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002916 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002917 }
2918
Ahmed Charlesb8984322014-03-07 20:03:18 +00002919 std::unique_ptr<std::vector<const char *>> Args(
2920 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002921
2922 // Recover resources if we crash before exiting this method.
2923 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2924 ArgsCleanup(Args.get());
2925
2926 // Since the Clang C library is primarily used by batch tools dealing with
2927 // (often very broken) source code, where spell-checking can have a
2928 // significant negative impact on performance (particularly when
2929 // precompiled headers are involved), we disable it by default.
2930 // Only do this if we haven't found a spell-checking-related argument.
2931 bool FoundSpellCheckingArgument = false;
2932 for (int I = 0; I != num_command_line_args; ++I) {
2933 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2934 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2935 FoundSpellCheckingArgument = true;
2936 break;
2937 }
2938 }
2939 if (!FoundSpellCheckingArgument)
2940 Args->push_back("-fno-spell-checking");
2941
2942 Args->insert(Args->end(), command_line_args,
2943 command_line_args + num_command_line_args);
2944
2945 // The 'source_filename' argument is optional. If the caller does not
2946 // specify it then it is assumed that the source file is specified
2947 // in the actual argument list.
2948 // Put the source file after command_line_args otherwise if '-x' flag is
2949 // present it will be unused.
2950 if (source_filename)
2951 Args->push_back(source_filename);
2952
2953 // Do we need the detailed preprocessing record?
2954 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2955 Args->push_back("-Xclang");
2956 Args->push_back("-detailed-preprocessing-record");
2957 }
2958
2959 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002960 std::unique_ptr<ASTUnit> ErrUnit;
2961 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002962 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002963 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2964 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2965 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2966 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2967 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2968 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002969
2970 if (NumErrors != Diags->getClient()->getNumErrors()) {
2971 // Make sure to check that 'Unit' is non-NULL.
2972 if (CXXIdx->getDisplayDiagnostics())
2973 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2974 }
2975
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002976 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2977 PTUI->result = CXError_ASTReadError;
2978 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002979 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002980 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2981 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002982}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002983
2984CXTranslationUnit
2985clang_parseTranslationUnit(CXIndex CIdx,
2986 const char *source_filename,
2987 const char *const *command_line_args,
2988 int num_command_line_args,
2989 struct CXUnsavedFile *unsaved_files,
2990 unsigned num_unsaved_files,
2991 unsigned options) {
2992 CXTranslationUnit TU;
2993 enum CXErrorCode Result = clang_parseTranslationUnit2(
2994 CIdx, source_filename, command_line_args, num_command_line_args,
2995 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002996 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002997 assert((TU && Result == CXError_Success) ||
2998 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002999 return TU;
3000}
3001
3002enum CXErrorCode clang_parseTranslationUnit2(
3003 CXIndex CIdx,
3004 const char *source_filename,
3005 const char *const *command_line_args,
3006 int num_command_line_args,
3007 struct CXUnsavedFile *unsaved_files,
3008 unsigned num_unsaved_files,
3009 unsigned options,
3010 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003011 LOG_FUNC_SECTION {
3012 *Log << source_filename << ": ";
3013 for (int i = 0; i != num_command_line_args; ++i)
3014 *Log << command_line_args[i] << " ";
3015 }
3016
Alp Toker9d85b182014-07-07 01:23:14 +00003017 if (num_unsaved_files && !unsaved_files)
3018 return CXError_InvalidArguments;
3019
Alp Toker5c532982014-07-07 22:42:03 +00003020 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003021 ParseTranslationUnitInfo PTUI = {
3022 CIdx,
3023 source_filename,
3024 command_line_args,
3025 num_command_line_args,
3026 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3027 options,
3028 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003029 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003030 llvm::CrashRecoveryContext CRC;
3031
3032 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3033 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3034 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3035 fprintf(stderr, " 'command_line_args' : [");
3036 for (int i = 0; i != num_command_line_args; ++i) {
3037 if (i)
3038 fprintf(stderr, ", ");
3039 fprintf(stderr, "'%s'", command_line_args[i]);
3040 }
3041 fprintf(stderr, "],\n");
3042 fprintf(stderr, " 'unsaved_files' : [");
3043 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3044 if (i)
3045 fprintf(stderr, ", ");
3046 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3047 unsaved_files[i].Length);
3048 }
3049 fprintf(stderr, "],\n");
3050 fprintf(stderr, " 'options' : %d,\n", options);
3051 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003052
3053 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003054 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003055 if (CXTranslationUnit *TU = PTUI.out_TU)
3056 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003057 }
Alp Toker5c532982014-07-07 22:42:03 +00003058
3059 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003060}
3061
3062unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3063 return CXSaveTranslationUnit_None;
3064}
3065
3066namespace {
3067
3068struct SaveTranslationUnitInfo {
3069 CXTranslationUnit TU;
3070 const char *FileName;
3071 unsigned options;
3072 CXSaveError result;
3073};
3074
3075}
3076
3077static void clang_saveTranslationUnit_Impl(void *UserData) {
3078 SaveTranslationUnitInfo *STUI =
3079 static_cast<SaveTranslationUnitInfo*>(UserData);
3080
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003081 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003082 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3083 setThreadBackgroundPriority();
3084
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003085 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003086 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3087}
3088
3089int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3090 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003091 LOG_FUNC_SECTION {
3092 *Log << TU << ' ' << FileName;
3093 }
3094
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003095 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003096 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003097 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003098 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003099
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003100 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003101 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3102 if (!CXXUnit->hasSema())
3103 return CXSaveError_InvalidTU;
3104
3105 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3106
3107 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3108 getenv("LIBCLANG_NOTHREADS")) {
3109 clang_saveTranslationUnit_Impl(&STUI);
3110
3111 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3112 PrintLibclangResourceUsage(TU);
3113
3114 return STUI.result;
3115 }
3116
3117 // We have an AST that has invalid nodes due to compiler errors.
3118 // Use a crash recovery thread for protection.
3119
3120 llvm::CrashRecoveryContext CRC;
3121
3122 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3123 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3124 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3125 fprintf(stderr, " 'options' : %d,\n", options);
3126 fprintf(stderr, "}\n");
3127
3128 return CXSaveError_Unknown;
3129
3130 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3131 PrintLibclangResourceUsage(TU);
3132 }
3133
3134 return STUI.result;
3135}
3136
3137void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3138 if (CTUnit) {
3139 // If the translation unit has been marked as unsafe to free, just discard
3140 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003141 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3142 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003143 return;
3144
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003145 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003146 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003147 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3148 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003149 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003150 delete CTUnit;
3151 }
3152}
3153
3154unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3155 return CXReparse_None;
3156}
3157
3158struct ReparseTranslationUnitInfo {
3159 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003160 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003162 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003163};
3164
3165static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003166 const ReparseTranslationUnitInfo *RTUI =
3167 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003168 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003169 unsigned options = RTUI->options;
3170 (void) options;
3171
3172 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003173 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003174 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003175 RTUI->result = CXError_InvalidArguments;
3176 return;
3177 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003178
3179 // Reset the associated diagnostics.
3180 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003181 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003182
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003183 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3185 setThreadBackgroundPriority();
3186
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003187 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003189
3190 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3191 new std::vector<ASTUnit::RemappedFile>());
3192
Guy Benyei11169dd2012-12-18 14:30:41 +00003193 // Recover resources if we crash before exiting this function.
3194 llvm::CrashRecoveryContextCleanupRegistrar<
3195 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003196
3197 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003198 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003199 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003200 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003202
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003203 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003204 RTUI->result = CXError_Success;
3205 else if (isASTReadError(CXXUnit))
3206 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003207}
3208
3209int clang_reparseTranslationUnit(CXTranslationUnit TU,
3210 unsigned num_unsaved_files,
3211 struct CXUnsavedFile *unsaved_files,
3212 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003213 LOG_FUNC_SECTION {
3214 *Log << TU;
3215 }
3216
Alp Toker9d85b182014-07-07 01:23:14 +00003217 if (num_unsaved_files && !unsaved_files)
3218 return CXError_InvalidArguments;
3219
Alp Toker5c532982014-07-07 22:42:03 +00003220 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003221 ReparseTranslationUnitInfo RTUI = {
3222 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003223 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003224
3225 if (getenv("LIBCLANG_NOTHREADS")) {
3226 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003227 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003228 }
3229
3230 llvm::CrashRecoveryContext CRC;
3231
3232 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3233 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003234 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003235 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003236 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3237 PrintLibclangResourceUsage(TU);
3238
Alp Toker5c532982014-07-07 22:42:03 +00003239 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003240}
3241
3242
3243CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003244 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003245 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003246 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003247 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003248
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003249 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003250 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003251}
3252
3253CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003254 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003255 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003256 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003257 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003258
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003259 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3261}
3262
3263} // end: extern "C"
3264
3265//===----------------------------------------------------------------------===//
3266// CXFile Operations.
3267//===----------------------------------------------------------------------===//
3268
3269extern "C" {
3270CXString clang_getFileName(CXFile SFile) {
3271 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003272 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003273
3274 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003275 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003276}
3277
3278time_t clang_getFileTime(CXFile SFile) {
3279 if (!SFile)
3280 return 0;
3281
3282 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3283 return FEnt->getModificationTime();
3284}
3285
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003286CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003287 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003288 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003289 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003290 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003291
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003292 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003293
3294 FileManager &FMgr = CXXUnit->getFileManager();
3295 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3296}
3297
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003298unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3299 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003300 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003301 LOG_BAD_TU(TU);
3302 return 0;
3303 }
3304
3305 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 return 0;
3307
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003308 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 FileEntry *FEnt = static_cast<FileEntry *>(file);
3310 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3311 .isFileMultipleIncludeGuarded(FEnt);
3312}
3313
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003314int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3315 if (!file || !outID)
3316 return 1;
3317
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003318 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003319 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3320 outID->data[0] = ID.getDevice();
3321 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003322 outID->data[2] = FEnt->getModificationTime();
3323 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003324}
3325
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003326int clang_File_isEqual(CXFile file1, CXFile file2) {
3327 if (file1 == file2)
3328 return true;
3329
3330 if (!file1 || !file2)
3331 return false;
3332
3333 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3334 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3335 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3336}
3337
Guy Benyei11169dd2012-12-18 14:30:41 +00003338} // end: extern "C"
3339
3340//===----------------------------------------------------------------------===//
3341// CXCursor Operations.
3342//===----------------------------------------------------------------------===//
3343
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003344static const Decl *getDeclFromExpr(const Stmt *E) {
3345 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 return getDeclFromExpr(CE->getSubExpr());
3347
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003348 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003350 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003352 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003354 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 if (PRE->isExplicitProperty())
3356 return PRE->getExplicitProperty();
3357 // It could be messaging both getter and setter as in:
3358 // ++myobj.myprop;
3359 // in which case prefer to associate the setter since it is less obvious
3360 // from inspecting the source that the setter is going to get called.
3361 if (PRE->isMessagingSetter())
3362 return PRE->getImplicitPropertySetter();
3363 return PRE->getImplicitPropertyGetter();
3364 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003365 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003367 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 if (Expr *Src = OVE->getSourceExpr())
3369 return getDeclFromExpr(Src);
3370
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003371 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003373 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 if (!CE->isElidable())
3375 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003376 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 return OME->getMethodDecl();
3378
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003379 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003381 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3383 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003384 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003385 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3386 isa<ParmVarDecl>(SizeOfPack->getPack()))
3387 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003388
3389 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003390}
3391
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003392static SourceLocation getLocationFromExpr(const Expr *E) {
3393 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 return getLocationFromExpr(CE->getSubExpr());
3395
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003396 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003398 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003400 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003402 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003404 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003406 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 return PropRef->getLocation();
3408
3409 return E->getLocStart();
3410}
3411
3412extern "C" {
3413
3414unsigned clang_visitChildren(CXCursor parent,
3415 CXCursorVisitor visitor,
3416 CXClientData client_data) {
3417 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3418 /*VisitPreprocessorLast=*/false);
3419 return CursorVis.VisitChildren(parent);
3420}
3421
3422#ifndef __has_feature
3423#define __has_feature(x) 0
3424#endif
3425#if __has_feature(blocks)
3426typedef enum CXChildVisitResult
3427 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3428
3429static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3430 CXClientData client_data) {
3431 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3432 return block(cursor, parent);
3433}
3434#else
3435// If we are compiled with a compiler that doesn't have native blocks support,
3436// define and call the block manually, so the
3437typedef struct _CXChildVisitResult
3438{
3439 void *isa;
3440 int flags;
3441 int reserved;
3442 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3443 CXCursor);
3444} *CXCursorVisitorBlock;
3445
3446static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3447 CXClientData client_data) {
3448 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3449 return block->invoke(block, cursor, parent);
3450}
3451#endif
3452
3453
3454unsigned clang_visitChildrenWithBlock(CXCursor parent,
3455 CXCursorVisitorBlock block) {
3456 return clang_visitChildren(parent, visitWithBlock, block);
3457}
3458
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003459static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003461 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003462
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003463 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003465 if (const ObjCPropertyImplDecl *PropImpl =
3466 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003467 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003468 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003469
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003470 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003472 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003473
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003474 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 }
3476
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003477 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003478 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003479
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003480 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3482 // and returns different names. NamedDecl returns the class name and
3483 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003484 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003485
3486 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003487 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003488
3489 SmallString<1024> S;
3490 llvm::raw_svector_ostream os(S);
3491 ND->printName(os);
3492
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003493 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003494}
3495
3496CXString clang_getCursorSpelling(CXCursor C) {
3497 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003498 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003499
3500 if (clang_isReference(C.kind)) {
3501 switch (C.kind) {
3502 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003503 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003504 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 }
3506 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003507 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003508 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 }
3510 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003511 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003513 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 }
3515 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003516 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003517 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 }
3519 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003520 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 assert(Type && "Missing type decl");
3522
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003523 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 getAsString());
3525 }
3526 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003527 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 assert(Template && "Missing template decl");
3529
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003530 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 }
3532
3533 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003534 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 assert(NS && "Missing namespace decl");
3536
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003537 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 }
3539
3540 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003541 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 assert(Field && "Missing member decl");
3543
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003544 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 }
3546
3547 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003548 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 assert(Label && "Missing label");
3550
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003551 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 }
3553
3554 case CXCursor_OverloadedDeclRef: {
3555 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003556 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3557 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003558 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003559 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003561 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003562 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 OverloadedTemplateStorage *Ovl
3564 = Storage.get<OverloadedTemplateStorage*>();
3565 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003566 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003567 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 }
3569
3570 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003571 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003572 assert(Var && "Missing variable decl");
3573
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003574 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 }
3576
3577 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003578 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 }
3580 }
3581
3582 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003583 const Expr *E = getCursorExpr(C);
3584
3585 if (C.kind == CXCursor_ObjCStringLiteral ||
3586 C.kind == CXCursor_StringLiteral) {
3587 const StringLiteral *SLit;
3588 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3589 SLit = OSL->getString();
3590 } else {
3591 SLit = cast<StringLiteral>(E);
3592 }
3593 SmallString<256> Buf;
3594 llvm::raw_svector_ostream OS(Buf);
3595 SLit->outputString(OS);
3596 return cxstring::createDup(OS.str());
3597 }
3598
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003599 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 if (D)
3601 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003602 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 }
3604
3605 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003606 const Stmt *S = getCursorStmt(C);
3607 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003608 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003609
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003610 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 }
3612
3613 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 ->getNameStart());
3616
3617 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 ->getNameStart());
3620
3621 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003622 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003623
3624 if (clang_isDeclaration(C.kind))
3625 return getDeclSpelling(getCursorDecl(C));
3626
3627 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003628 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003629 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 }
3631
3632 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003633 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003634 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 }
3636
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003637 if (C.kind == CXCursor_PackedAttr) {
3638 return cxstring::createRef("packed");
3639 }
3640
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003641 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003642}
3643
3644CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3645 unsigned pieceIndex,
3646 unsigned options) {
3647 if (clang_Cursor_isNull(C))
3648 return clang_getNullRange();
3649
3650 ASTContext &Ctx = getCursorContext(C);
3651
3652 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003653 const Stmt *S = getCursorStmt(C);
3654 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 if (pieceIndex > 0)
3656 return clang_getNullRange();
3657 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3658 }
3659
3660 return clang_getNullRange();
3661 }
3662
3663 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003664 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3666 if (pieceIndex >= ME->getNumSelectorLocs())
3667 return clang_getNullRange();
3668 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3669 }
3670 }
3671
3672 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3673 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003674 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3676 if (pieceIndex >= MD->getNumSelectorLocs())
3677 return clang_getNullRange();
3678 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3679 }
3680 }
3681
3682 if (C.kind == CXCursor_ObjCCategoryDecl ||
3683 C.kind == CXCursor_ObjCCategoryImplDecl) {
3684 if (pieceIndex > 0)
3685 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003686 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3688 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003689 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3691 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3692 }
3693
3694 if (C.kind == CXCursor_ModuleImportDecl) {
3695 if (pieceIndex > 0)
3696 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003697 if (const ImportDecl *ImportD =
3698 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3700 if (!Locs.empty())
3701 return cxloc::translateSourceRange(Ctx,
3702 SourceRange(Locs.front(), Locs.back()));
3703 }
3704 return clang_getNullRange();
3705 }
3706
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003707 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3708 C.kind == CXCursor_ConversionFunction) {
3709 if (pieceIndex > 0)
3710 return clang_getNullRange();
3711 if (const FunctionDecl *FD =
3712 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3713 DeclarationNameInfo FunctionName = FD->getNameInfo();
3714 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3715 }
3716 return clang_getNullRange();
3717 }
3718
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 // FIXME: A CXCursor_InclusionDirective should give the location of the
3720 // filename, but we don't keep track of this.
3721
3722 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3723 // but we don't keep track of this.
3724
3725 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3726 // but we don't keep track of this.
3727
3728 // Default handling, give the location of the cursor.
3729
3730 if (pieceIndex > 0)
3731 return clang_getNullRange();
3732
3733 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3734 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3735 return cxloc::translateSourceRange(Ctx, Loc);
3736}
3737
Eli Bendersky44a206f2014-07-31 18:04:56 +00003738CXString clang_Cursor_getMangling(CXCursor C) {
3739 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3740 return cxstring::createEmpty();
3741
Eli Bendersky44a206f2014-07-31 18:04:56 +00003742 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003743 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003744 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3745 return cxstring::createEmpty();
3746
Eli Bendersky79759592014-08-01 15:01:10 +00003747 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003748 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003749 ASTContext &Ctx = ND->getASTContext();
3750 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003751
Eli Bendersky79759592014-08-01 15:01:10 +00003752 std::string FrontendBuf;
3753 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3754 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003755
Eli Bendersky79759592014-08-01 15:01:10 +00003756 // Now apply backend mangling.
3757 std::unique_ptr<llvm::DataLayout> DL(
3758 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3759 llvm::Mangler BackendMangler(DL.get());
3760
3761 std::string FinalBuf;
3762 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3763 BackendMangler.getNameWithPrefix(FinalBufOS,
3764 llvm::Twine(FrontendBufOS.str()));
3765
3766 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003767}
3768
Guy Benyei11169dd2012-12-18 14:30:41 +00003769CXString clang_getCursorDisplayName(CXCursor C) {
3770 if (!clang_isDeclaration(C.kind))
3771 return clang_getCursorSpelling(C);
3772
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003773 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003775 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003776
3777 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003778 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 D = FunTmpl->getTemplatedDecl();
3780
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003781 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 SmallString<64> Str;
3783 llvm::raw_svector_ostream OS(Str);
3784 OS << *Function;
3785 if (Function->getPrimaryTemplate())
3786 OS << "<>";
3787 OS << "(";
3788 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3789 if (I)
3790 OS << ", ";
3791 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3792 }
3793
3794 if (Function->isVariadic()) {
3795 if (Function->getNumParams())
3796 OS << ", ";
3797 OS << "...";
3798 }
3799 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003800 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 }
3802
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003803 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 SmallString<64> Str;
3805 llvm::raw_svector_ostream OS(Str);
3806 OS << *ClassTemplate;
3807 OS << "<";
3808 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3809 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3810 if (I)
3811 OS << ", ";
3812
3813 NamedDecl *Param = Params->getParam(I);
3814 if (Param->getIdentifier()) {
3815 OS << Param->getIdentifier()->getName();
3816 continue;
3817 }
3818
3819 // There is no parameter name, which makes this tricky. Try to come up
3820 // with something useful that isn't too long.
3821 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3822 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3823 else if (NonTypeTemplateParmDecl *NTTP
3824 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3825 OS << NTTP->getType().getAsString(Policy);
3826 else
3827 OS << "template<...> class";
3828 }
3829
3830 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003831 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 }
3833
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003834 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3836 // If the type was explicitly written, use that.
3837 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003838 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003839
Benjamin Kramer9170e912013-02-22 15:46:01 +00003840 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 llvm::raw_svector_ostream OS(Str);
3842 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003843 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 ClassSpec->getTemplateArgs().data(),
3845 ClassSpec->getTemplateArgs().size(),
3846 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003847 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 }
3849
3850 return clang_getCursorSpelling(C);
3851}
3852
3853CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3854 switch (Kind) {
3855 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003983 case CXCursor_ObjCSelfExpr:
3984 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004073 case CXCursor_SEHLeaveStmt:
4074 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004103 case CXCursor_PackedAttr:
4104 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004105 case CXCursor_PureAttr:
4106 return cxstring::createRef("attribute(pure)");
4107 case CXCursor_ConstAttr:
4108 return cxstring::createRef("attribute(const)");
4109 case CXCursor_NoDuplicateAttr:
4110 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004111 case CXCursor_CUDAConstantAttr:
4112 return cxstring::createRef("attribute(constant)");
4113 case CXCursor_CUDADeviceAttr:
4114 return cxstring::createRef("attribute(device)");
4115 case CXCursor_CUDAGlobalAttr:
4116 return cxstring::createRef("attribute(global)");
4117 case CXCursor_CUDAHostAttr:
4118 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004119 case CXCursor_CUDASharedAttr:
4120 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004169 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004170 return cxstring::createRef("OMPParallelDirective");
4171 case CXCursor_OMPSimdDirective:
4172 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004173 case CXCursor_OMPForDirective:
4174 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004175 case CXCursor_OMPForSimdDirective:
4176 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004177 case CXCursor_OMPSectionsDirective:
4178 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004179 case CXCursor_OMPSectionDirective:
4180 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004181 case CXCursor_OMPSingleDirective:
4182 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004183 case CXCursor_OMPMasterDirective:
4184 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004185 case CXCursor_OMPCriticalDirective:
4186 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004187 case CXCursor_OMPParallelForDirective:
4188 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004189 case CXCursor_OMPParallelForSimdDirective:
4190 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004191 case CXCursor_OMPParallelSectionsDirective:
4192 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004193 case CXCursor_OMPTaskDirective:
4194 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004195 case CXCursor_OMPTaskyieldDirective:
4196 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004197 case CXCursor_OMPBarrierDirective:
4198 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004199 case CXCursor_OMPTaskwaitDirective:
4200 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004201 case CXCursor_OMPFlushDirective:
4202 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004203 case CXCursor_OMPOrderedDirective:
4204 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004205 case CXCursor_OMPAtomicDirective:
4206 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004207 case CXCursor_OMPTargetDirective:
4208 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004209 case CXCursor_OMPTeamsDirective:
4210 return cxstring::createRef("OMPTeamsDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004211 case CXCursor_OverloadCandidate:
4212 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 }
4214
4215 llvm_unreachable("Unhandled CXCursorKind");
4216}
4217
4218struct GetCursorData {
4219 SourceLocation TokenBeginLoc;
4220 bool PointsAtMacroArgExpansion;
4221 bool VisitedObjCPropertyImplDecl;
4222 SourceLocation VisitedDeclaratorDeclStartLoc;
4223 CXCursor &BestCursor;
4224
4225 GetCursorData(SourceManager &SM,
4226 SourceLocation tokenBegin, CXCursor &outputCursor)
4227 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4228 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4229 VisitedObjCPropertyImplDecl = false;
4230 }
4231};
4232
4233static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4234 CXCursor parent,
4235 CXClientData client_data) {
4236 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4237 CXCursor *BestCursor = &Data->BestCursor;
4238
4239 // If we point inside a macro argument we should provide info of what the
4240 // token is so use the actual cursor, don't replace it with a macro expansion
4241 // cursor.
4242 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4243 return CXChildVisit_Recurse;
4244
4245 if (clang_isDeclaration(cursor.kind)) {
4246 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004247 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4249 if (MD->isImplicit())
4250 return CXChildVisit_Break;
4251
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004252 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4254 // Check that when we have multiple @class references in the same line,
4255 // that later ones do not override the previous ones.
4256 // If we have:
4257 // @class Foo, Bar;
4258 // source ranges for both start at '@', so 'Bar' will end up overriding
4259 // 'Foo' even though the cursor location was at 'Foo'.
4260 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4261 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004262 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4264 if (PrevID != ID &&
4265 !PrevID->isThisDeclarationADefinition() &&
4266 !ID->isThisDeclarationADefinition())
4267 return CXChildVisit_Break;
4268 }
4269
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004270 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4272 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4273 // Check that when we have multiple declarators in the same line,
4274 // that later ones do not override the previous ones.
4275 // If we have:
4276 // int Foo, Bar;
4277 // source ranges for both start at 'int', so 'Bar' will end up overriding
4278 // 'Foo' even though the cursor location was at 'Foo'.
4279 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4280 return CXChildVisit_Break;
4281 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4282
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004283 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4285 (void)PropImp;
4286 // Check that when we have multiple @synthesize in the same line,
4287 // that later ones do not override the previous ones.
4288 // If we have:
4289 // @synthesize Foo, Bar;
4290 // source ranges for both start at '@', so 'Bar' will end up overriding
4291 // 'Foo' even though the cursor location was at 'Foo'.
4292 if (Data->VisitedObjCPropertyImplDecl)
4293 return CXChildVisit_Break;
4294 Data->VisitedObjCPropertyImplDecl = true;
4295 }
4296 }
4297
4298 if (clang_isExpression(cursor.kind) &&
4299 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004300 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 // Avoid having the cursor of an expression replace the declaration cursor
4302 // when the expression source range overlaps the declaration range.
4303 // This can happen for C++ constructor expressions whose range generally
4304 // include the variable declaration, e.g.:
4305 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4306 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4307 D->getLocation() == Data->TokenBeginLoc)
4308 return CXChildVisit_Break;
4309 }
4310 }
4311
4312 // If our current best cursor is the construction of a temporary object,
4313 // don't replace that cursor with a type reference, because we want
4314 // clang_getCursor() to point at the constructor.
4315 if (clang_isExpression(BestCursor->kind) &&
4316 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4317 cursor.kind == CXCursor_TypeRef) {
4318 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4319 // as having the actual point on the type reference.
4320 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4321 return CXChildVisit_Recurse;
4322 }
4323
4324 *BestCursor = cursor;
4325 return CXChildVisit_Recurse;
4326}
4327
4328CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004329 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004330 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004331 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004332 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004333
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004334 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004335 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4336
4337 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4338 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4339
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004340 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004341 CXFile SearchFile;
4342 unsigned SearchLine, SearchColumn;
4343 CXFile ResultFile;
4344 unsigned ResultLine, ResultColumn;
4345 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4346 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4347 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004348
4349 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4350 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004351 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004352 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004353 SearchFileName = clang_getFileName(SearchFile);
4354 ResultFileName = clang_getFileName(ResultFile);
4355 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4356 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004357 *Log << llvm::format("(%s:%d:%d) = %s",
4358 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4359 clang_getCString(KindSpelling))
4360 << llvm::format("(%s:%d:%d):%s%s",
4361 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4362 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 clang_disposeString(SearchFileName);
4364 clang_disposeString(ResultFileName);
4365 clang_disposeString(KindSpelling);
4366 clang_disposeString(USR);
4367
4368 CXCursor Definition = clang_getCursorDefinition(Result);
4369 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4370 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4371 CXString DefinitionKindSpelling
4372 = clang_getCursorKindSpelling(Definition.kind);
4373 CXFile DefinitionFile;
4374 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004375 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004376 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004377 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004378 *Log << llvm::format(" -> %s(%s:%d:%d)",
4379 clang_getCString(DefinitionKindSpelling),
4380 clang_getCString(DefinitionFileName),
4381 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004382 clang_disposeString(DefinitionFileName);
4383 clang_disposeString(DefinitionKindSpelling);
4384 }
4385 }
4386
4387 return Result;
4388}
4389
4390CXCursor clang_getNullCursor(void) {
4391 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4392}
4393
4394unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004395 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4396 // can't set consistently. For example, when visiting a DeclStmt we will set
4397 // it but we don't set it on the result of clang_getCursorDefinition for
4398 // a reference of the same declaration.
4399 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4400 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4401 // to provide that kind of info.
4402 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004403 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004404 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004405 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004406
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 return X == Y;
4408}
4409
4410unsigned clang_hashCursor(CXCursor C) {
4411 unsigned Index = 0;
4412 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4413 Index = 1;
4414
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004415 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 std::make_pair(C.kind, C.data[Index]));
4417}
4418
4419unsigned clang_isInvalid(enum CXCursorKind K) {
4420 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4421}
4422
4423unsigned clang_isDeclaration(enum CXCursorKind K) {
4424 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4425 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4426}
4427
4428unsigned clang_isReference(enum CXCursorKind K) {
4429 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4430}
4431
4432unsigned clang_isExpression(enum CXCursorKind K) {
4433 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4434}
4435
4436unsigned clang_isStatement(enum CXCursorKind K) {
4437 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4438}
4439
4440unsigned clang_isAttribute(enum CXCursorKind K) {
4441 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4442}
4443
4444unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4445 return K == CXCursor_TranslationUnit;
4446}
4447
4448unsigned clang_isPreprocessing(enum CXCursorKind K) {
4449 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4450}
4451
4452unsigned clang_isUnexposed(enum CXCursorKind K) {
4453 switch (K) {
4454 case CXCursor_UnexposedDecl:
4455 case CXCursor_UnexposedExpr:
4456 case CXCursor_UnexposedStmt:
4457 case CXCursor_UnexposedAttr:
4458 return true;
4459 default:
4460 return false;
4461 }
4462}
4463
4464CXCursorKind clang_getCursorKind(CXCursor C) {
4465 return C.kind;
4466}
4467
4468CXSourceLocation clang_getCursorLocation(CXCursor C) {
4469 if (clang_isReference(C.kind)) {
4470 switch (C.kind) {
4471 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004472 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 = getCursorObjCSuperClassRef(C);
4474 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4475 }
4476
4477 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004478 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 = getCursorObjCProtocolRef(C);
4480 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4481 }
4482
4483 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004484 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 = getCursorObjCClassRef(C);
4486 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4487 }
4488
4489 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004490 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4492 }
4493
4494 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004495 std::pair<const TemplateDecl *, SourceLocation> P =
4496 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4498 }
4499
4500 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004501 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4503 }
4504
4505 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004506 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4508 }
4509
4510 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004511 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4513 }
4514
4515 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004516 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 if (!BaseSpec)
4518 return clang_getNullLocation();
4519
4520 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4521 return cxloc::translateSourceLocation(getCursorContext(C),
4522 TSInfo->getTypeLoc().getBeginLoc());
4523
4524 return cxloc::translateSourceLocation(getCursorContext(C),
4525 BaseSpec->getLocStart());
4526 }
4527
4528 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004529 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004530 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4531 }
4532
4533 case CXCursor_OverloadedDeclRef:
4534 return cxloc::translateSourceLocation(getCursorContext(C),
4535 getCursorOverloadedDeclRef(C).second);
4536
4537 default:
4538 // FIXME: Need a way to enumerate all non-reference cases.
4539 llvm_unreachable("Missed a reference kind");
4540 }
4541 }
4542
4543 if (clang_isExpression(C.kind))
4544 return cxloc::translateSourceLocation(getCursorContext(C),
4545 getLocationFromExpr(getCursorExpr(C)));
4546
4547 if (clang_isStatement(C.kind))
4548 return cxloc::translateSourceLocation(getCursorContext(C),
4549 getCursorStmt(C)->getLocStart());
4550
4551 if (C.kind == CXCursor_PreprocessingDirective) {
4552 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4553 return cxloc::translateSourceLocation(getCursorContext(C), L);
4554 }
4555
4556 if (C.kind == CXCursor_MacroExpansion) {
4557 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004558 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 return cxloc::translateSourceLocation(getCursorContext(C), L);
4560 }
4561
4562 if (C.kind == CXCursor_MacroDefinition) {
4563 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4564 return cxloc::translateSourceLocation(getCursorContext(C), L);
4565 }
4566
4567 if (C.kind == CXCursor_InclusionDirective) {
4568 SourceLocation L
4569 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4570 return cxloc::translateSourceLocation(getCursorContext(C), L);
4571 }
4572
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004573 if (clang_isAttribute(C.kind)) {
4574 SourceLocation L
4575 = cxcursor::getCursorAttr(C)->getLocation();
4576 return cxloc::translateSourceLocation(getCursorContext(C), L);
4577 }
4578
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 if (!clang_isDeclaration(C.kind))
4580 return clang_getNullLocation();
4581
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004582 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 if (!D)
4584 return clang_getNullLocation();
4585
4586 SourceLocation Loc = D->getLocation();
4587 // FIXME: Multiple variables declared in a single declaration
4588 // currently lack the information needed to correctly determine their
4589 // ranges when accounting for the type-specifier. We use context
4590 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4591 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004592 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 if (!cxcursor::isFirstInDeclGroup(C))
4594 Loc = VD->getLocation();
4595 }
4596
4597 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004598 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 Loc = MD->getSelectorStartLoc();
4600
4601 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4602}
4603
4604} // end extern "C"
4605
4606CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4607 assert(TU);
4608
4609 // Guard against an invalid SourceLocation, or we may assert in one
4610 // of the following calls.
4611 if (SLoc.isInvalid())
4612 return clang_getNullCursor();
4613
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004614 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004615
4616 // Translate the given source location to make it point at the beginning of
4617 // the token under the cursor.
4618 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4619 CXXUnit->getASTContext().getLangOpts());
4620
4621 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4622 if (SLoc.isValid()) {
4623 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4624 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4625 /*VisitPreprocessorLast=*/true,
4626 /*VisitIncludedEntities=*/false,
4627 SourceLocation(SLoc));
4628 CursorVis.visitFileRegion();
4629 }
4630
4631 return Result;
4632}
4633
4634static SourceRange getRawCursorExtent(CXCursor C) {
4635 if (clang_isReference(C.kind)) {
4636 switch (C.kind) {
4637 case CXCursor_ObjCSuperClassRef:
4638 return getCursorObjCSuperClassRef(C).second;
4639
4640 case CXCursor_ObjCProtocolRef:
4641 return getCursorObjCProtocolRef(C).second;
4642
4643 case CXCursor_ObjCClassRef:
4644 return getCursorObjCClassRef(C).second;
4645
4646 case CXCursor_TypeRef:
4647 return getCursorTypeRef(C).second;
4648
4649 case CXCursor_TemplateRef:
4650 return getCursorTemplateRef(C).second;
4651
4652 case CXCursor_NamespaceRef:
4653 return getCursorNamespaceRef(C).second;
4654
4655 case CXCursor_MemberRef:
4656 return getCursorMemberRef(C).second;
4657
4658 case CXCursor_CXXBaseSpecifier:
4659 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4660
4661 case CXCursor_LabelRef:
4662 return getCursorLabelRef(C).second;
4663
4664 case CXCursor_OverloadedDeclRef:
4665 return getCursorOverloadedDeclRef(C).second;
4666
4667 case CXCursor_VariableRef:
4668 return getCursorVariableRef(C).second;
4669
4670 default:
4671 // FIXME: Need a way to enumerate all non-reference cases.
4672 llvm_unreachable("Missed a reference kind");
4673 }
4674 }
4675
4676 if (clang_isExpression(C.kind))
4677 return getCursorExpr(C)->getSourceRange();
4678
4679 if (clang_isStatement(C.kind))
4680 return getCursorStmt(C)->getSourceRange();
4681
4682 if (clang_isAttribute(C.kind))
4683 return getCursorAttr(C)->getRange();
4684
4685 if (C.kind == CXCursor_PreprocessingDirective)
4686 return cxcursor::getCursorPreprocessingDirective(C);
4687
4688 if (C.kind == CXCursor_MacroExpansion) {
4689 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004690 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 return TU->mapRangeFromPreamble(Range);
4692 }
4693
4694 if (C.kind == CXCursor_MacroDefinition) {
4695 ASTUnit *TU = getCursorASTUnit(C);
4696 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4697 return TU->mapRangeFromPreamble(Range);
4698 }
4699
4700 if (C.kind == CXCursor_InclusionDirective) {
4701 ASTUnit *TU = getCursorASTUnit(C);
4702 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4703 return TU->mapRangeFromPreamble(Range);
4704 }
4705
4706 if (C.kind == CXCursor_TranslationUnit) {
4707 ASTUnit *TU = getCursorASTUnit(C);
4708 FileID MainID = TU->getSourceManager().getMainFileID();
4709 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4710 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4711 return SourceRange(Start, End);
4712 }
4713
4714 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004715 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004716 if (!D)
4717 return SourceRange();
4718
4719 SourceRange R = D->getSourceRange();
4720 // FIXME: Multiple variables declared in a single declaration
4721 // currently lack the information needed to correctly determine their
4722 // ranges when accounting for the type-specifier. We use context
4723 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4724 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004725 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004726 if (!cxcursor::isFirstInDeclGroup(C))
4727 R.setBegin(VD->getLocation());
4728 }
4729 return R;
4730 }
4731 return SourceRange();
4732}
4733
4734/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4735/// the decl-specifier-seq for declarations.
4736static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4737 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004738 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 if (!D)
4740 return SourceRange();
4741
4742 SourceRange R = D->getSourceRange();
4743
4744 // Adjust the start of the location for declarations preceded by
4745 // declaration specifiers.
4746 SourceLocation StartLoc;
4747 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4748 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4749 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004750 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4752 StartLoc = TI->getTypeLoc().getLocStart();
4753 }
4754
4755 if (StartLoc.isValid() && R.getBegin().isValid() &&
4756 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4757 R.setBegin(StartLoc);
4758
4759 // FIXME: Multiple variables declared in a single declaration
4760 // currently lack the information needed to correctly determine their
4761 // ranges when accounting for the type-specifier. We use context
4762 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4763 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004764 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 if (!cxcursor::isFirstInDeclGroup(C))
4766 R.setBegin(VD->getLocation());
4767 }
4768
4769 return R;
4770 }
4771
4772 return getRawCursorExtent(C);
4773}
4774
4775extern "C" {
4776
4777CXSourceRange clang_getCursorExtent(CXCursor C) {
4778 SourceRange R = getRawCursorExtent(C);
4779 if (R.isInvalid())
4780 return clang_getNullRange();
4781
4782 return cxloc::translateSourceRange(getCursorContext(C), R);
4783}
4784
4785CXCursor clang_getCursorReferenced(CXCursor C) {
4786 if (clang_isInvalid(C.kind))
4787 return clang_getNullCursor();
4788
4789 CXTranslationUnit tu = getCursorTU(C);
4790 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004791 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004792 if (!D)
4793 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004794 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004795 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004796 if (const ObjCPropertyImplDecl *PropImpl =
4797 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004798 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4799 return MakeCXCursor(Property, tu);
4800
4801 return C;
4802 }
4803
4804 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004805 const Expr *E = getCursorExpr(C);
4806 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 if (D) {
4808 CXCursor declCursor = MakeCXCursor(D, tu);
4809 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4810 declCursor);
4811 return declCursor;
4812 }
4813
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004814 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004815 return MakeCursorOverloadedDeclRef(Ovl, tu);
4816
4817 return clang_getNullCursor();
4818 }
4819
4820 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004821 const Stmt *S = getCursorStmt(C);
4822 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 if (LabelDecl *label = Goto->getLabel())
4824 if (LabelStmt *labelS = label->getStmt())
4825 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4826
4827 return clang_getNullCursor();
4828 }
4829
4830 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004831 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 return MakeMacroDefinitionCursor(Def, tu);
4833 }
4834
4835 if (!clang_isReference(C.kind))
4836 return clang_getNullCursor();
4837
4838 switch (C.kind) {
4839 case CXCursor_ObjCSuperClassRef:
4840 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4841
4842 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004843 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4844 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 return MakeCXCursor(Def, tu);
4846
4847 return MakeCXCursor(Prot, tu);
4848 }
4849
4850 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004851 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4852 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 return MakeCXCursor(Def, tu);
4854
4855 return MakeCXCursor(Class, tu);
4856 }
4857
4858 case CXCursor_TypeRef:
4859 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4860
4861 case CXCursor_TemplateRef:
4862 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4863
4864 case CXCursor_NamespaceRef:
4865 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4866
4867 case CXCursor_MemberRef:
4868 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4869
4870 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004871 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004872 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4873 tu ));
4874 }
4875
4876 case CXCursor_LabelRef:
4877 // FIXME: We end up faking the "parent" declaration here because we
4878 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004879 return MakeCXCursor(getCursorLabelRef(C).first,
4880 cxtu::getASTUnit(tu)->getASTContext()
4881 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004882 tu);
4883
4884 case CXCursor_OverloadedDeclRef:
4885 return C;
4886
4887 case CXCursor_VariableRef:
4888 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4889
4890 default:
4891 // We would prefer to enumerate all non-reference cursor kinds here.
4892 llvm_unreachable("Unhandled reference cursor kind");
4893 }
4894}
4895
4896CXCursor clang_getCursorDefinition(CXCursor C) {
4897 if (clang_isInvalid(C.kind))
4898 return clang_getNullCursor();
4899
4900 CXTranslationUnit TU = getCursorTU(C);
4901
4902 bool WasReference = false;
4903 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4904 C = clang_getCursorReferenced(C);
4905 WasReference = true;
4906 }
4907
4908 if (C.kind == CXCursor_MacroExpansion)
4909 return clang_getCursorReferenced(C);
4910
4911 if (!clang_isDeclaration(C.kind))
4912 return clang_getNullCursor();
4913
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004914 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 if (!D)
4916 return clang_getNullCursor();
4917
4918 switch (D->getKind()) {
4919 // Declaration kinds that don't really separate the notions of
4920 // declaration and definition.
4921 case Decl::Namespace:
4922 case Decl::Typedef:
4923 case Decl::TypeAlias:
4924 case Decl::TypeAliasTemplate:
4925 case Decl::TemplateTypeParm:
4926 case Decl::EnumConstant:
4927 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004928 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004929 case Decl::IndirectField:
4930 case Decl::ObjCIvar:
4931 case Decl::ObjCAtDefsField:
4932 case Decl::ImplicitParam:
4933 case Decl::ParmVar:
4934 case Decl::NonTypeTemplateParm:
4935 case Decl::TemplateTemplateParm:
4936 case Decl::ObjCCategoryImpl:
4937 case Decl::ObjCImplementation:
4938 case Decl::AccessSpec:
4939 case Decl::LinkageSpec:
4940 case Decl::ObjCPropertyImpl:
4941 case Decl::FileScopeAsm:
4942 case Decl::StaticAssert:
4943 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004944 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 case Decl::Label: // FIXME: Is this right??
4946 case Decl::ClassScopeFunctionSpecialization:
4947 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004948 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004949 return C;
4950
4951 // Declaration kinds that don't make any sense here, but are
4952 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004953 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004954 case Decl::TranslationUnit:
4955 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());
7271 OS << Msg.str() << '\n';
7272
7273 if (Trace) {
7274 llvm::sys::PrintStackTrace(stderr);
7275 OS << "--------------------------------------------------\n";
7276 }
7277}