blob: 00ef8c0bf424bc77748577e8cf6ab784e82a02c1 [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");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 }
4212
4213 llvm_unreachable("Unhandled CXCursorKind");
4214}
4215
4216struct GetCursorData {
4217 SourceLocation TokenBeginLoc;
4218 bool PointsAtMacroArgExpansion;
4219 bool VisitedObjCPropertyImplDecl;
4220 SourceLocation VisitedDeclaratorDeclStartLoc;
4221 CXCursor &BestCursor;
4222
4223 GetCursorData(SourceManager &SM,
4224 SourceLocation tokenBegin, CXCursor &outputCursor)
4225 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4226 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4227 VisitedObjCPropertyImplDecl = false;
4228 }
4229};
4230
4231static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4232 CXCursor parent,
4233 CXClientData client_data) {
4234 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4235 CXCursor *BestCursor = &Data->BestCursor;
4236
4237 // If we point inside a macro argument we should provide info of what the
4238 // token is so use the actual cursor, don't replace it with a macro expansion
4239 // cursor.
4240 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4241 return CXChildVisit_Recurse;
4242
4243 if (clang_isDeclaration(cursor.kind)) {
4244 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004245 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4247 if (MD->isImplicit())
4248 return CXChildVisit_Break;
4249
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004250 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4252 // Check that when we have multiple @class references in the same line,
4253 // that later ones do not override the previous ones.
4254 // If we have:
4255 // @class Foo, Bar;
4256 // source ranges for both start at '@', so 'Bar' will end up overriding
4257 // 'Foo' even though the cursor location was at 'Foo'.
4258 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4259 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004260 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4262 if (PrevID != ID &&
4263 !PrevID->isThisDeclarationADefinition() &&
4264 !ID->isThisDeclarationADefinition())
4265 return CXChildVisit_Break;
4266 }
4267
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004268 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4270 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4271 // Check that when we have multiple declarators in the same line,
4272 // that later ones do not override the previous ones.
4273 // If we have:
4274 // int Foo, Bar;
4275 // source ranges for both start at 'int', so 'Bar' will end up overriding
4276 // 'Foo' even though the cursor location was at 'Foo'.
4277 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4278 return CXChildVisit_Break;
4279 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4280
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004281 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4283 (void)PropImp;
4284 // Check that when we have multiple @synthesize in the same line,
4285 // that later ones do not override the previous ones.
4286 // If we have:
4287 // @synthesize Foo, Bar;
4288 // source ranges for both start at '@', so 'Bar' will end up overriding
4289 // 'Foo' even though the cursor location was at 'Foo'.
4290 if (Data->VisitedObjCPropertyImplDecl)
4291 return CXChildVisit_Break;
4292 Data->VisitedObjCPropertyImplDecl = true;
4293 }
4294 }
4295
4296 if (clang_isExpression(cursor.kind) &&
4297 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004298 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 // Avoid having the cursor of an expression replace the declaration cursor
4300 // when the expression source range overlaps the declaration range.
4301 // This can happen for C++ constructor expressions whose range generally
4302 // include the variable declaration, e.g.:
4303 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4304 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4305 D->getLocation() == Data->TokenBeginLoc)
4306 return CXChildVisit_Break;
4307 }
4308 }
4309
4310 // If our current best cursor is the construction of a temporary object,
4311 // don't replace that cursor with a type reference, because we want
4312 // clang_getCursor() to point at the constructor.
4313 if (clang_isExpression(BestCursor->kind) &&
4314 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4315 cursor.kind == CXCursor_TypeRef) {
4316 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4317 // as having the actual point on the type reference.
4318 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4319 return CXChildVisit_Recurse;
4320 }
4321
4322 *BestCursor = cursor;
4323 return CXChildVisit_Recurse;
4324}
4325
4326CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004327 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004328 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004329 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004330 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004331
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004332 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4334
4335 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4336 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4337
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004338 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004339 CXFile SearchFile;
4340 unsigned SearchLine, SearchColumn;
4341 CXFile ResultFile;
4342 unsigned ResultLine, ResultColumn;
4343 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4344 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4345 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004346
4347 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4348 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004349 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004350 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004351 SearchFileName = clang_getFileName(SearchFile);
4352 ResultFileName = clang_getFileName(ResultFile);
4353 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4354 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004355 *Log << llvm::format("(%s:%d:%d) = %s",
4356 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4357 clang_getCString(KindSpelling))
4358 << llvm::format("(%s:%d:%d):%s%s",
4359 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4360 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004361 clang_disposeString(SearchFileName);
4362 clang_disposeString(ResultFileName);
4363 clang_disposeString(KindSpelling);
4364 clang_disposeString(USR);
4365
4366 CXCursor Definition = clang_getCursorDefinition(Result);
4367 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4368 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4369 CXString DefinitionKindSpelling
4370 = clang_getCursorKindSpelling(Definition.kind);
4371 CXFile DefinitionFile;
4372 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004373 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004374 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004375 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004376 *Log << llvm::format(" -> %s(%s:%d:%d)",
4377 clang_getCString(DefinitionKindSpelling),
4378 clang_getCString(DefinitionFileName),
4379 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004380 clang_disposeString(DefinitionFileName);
4381 clang_disposeString(DefinitionKindSpelling);
4382 }
4383 }
4384
4385 return Result;
4386}
4387
4388CXCursor clang_getNullCursor(void) {
4389 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4390}
4391
4392unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004393 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4394 // can't set consistently. For example, when visiting a DeclStmt we will set
4395 // it but we don't set it on the result of clang_getCursorDefinition for
4396 // a reference of the same declaration.
4397 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4398 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4399 // to provide that kind of info.
4400 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004401 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004402 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004403 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004404
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 return X == Y;
4406}
4407
4408unsigned clang_hashCursor(CXCursor C) {
4409 unsigned Index = 0;
4410 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4411 Index = 1;
4412
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004413 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 std::make_pair(C.kind, C.data[Index]));
4415}
4416
4417unsigned clang_isInvalid(enum CXCursorKind K) {
4418 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4419}
4420
4421unsigned clang_isDeclaration(enum CXCursorKind K) {
4422 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4423 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4424}
4425
4426unsigned clang_isReference(enum CXCursorKind K) {
4427 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4428}
4429
4430unsigned clang_isExpression(enum CXCursorKind K) {
4431 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4432}
4433
4434unsigned clang_isStatement(enum CXCursorKind K) {
4435 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4436}
4437
4438unsigned clang_isAttribute(enum CXCursorKind K) {
4439 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4440}
4441
4442unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4443 return K == CXCursor_TranslationUnit;
4444}
4445
4446unsigned clang_isPreprocessing(enum CXCursorKind K) {
4447 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4448}
4449
4450unsigned clang_isUnexposed(enum CXCursorKind K) {
4451 switch (K) {
4452 case CXCursor_UnexposedDecl:
4453 case CXCursor_UnexposedExpr:
4454 case CXCursor_UnexposedStmt:
4455 case CXCursor_UnexposedAttr:
4456 return true;
4457 default:
4458 return false;
4459 }
4460}
4461
4462CXCursorKind clang_getCursorKind(CXCursor C) {
4463 return C.kind;
4464}
4465
4466CXSourceLocation clang_getCursorLocation(CXCursor C) {
4467 if (clang_isReference(C.kind)) {
4468 switch (C.kind) {
4469 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004470 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 = getCursorObjCSuperClassRef(C);
4472 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4473 }
4474
4475 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004476 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 = getCursorObjCProtocolRef(C);
4478 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4479 }
4480
4481 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004482 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 = getCursorObjCClassRef(C);
4484 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4485 }
4486
4487 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004488 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4490 }
4491
4492 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004493 std::pair<const TemplateDecl *, SourceLocation> P =
4494 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4496 }
4497
4498 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004499 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4501 }
4502
4503 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004504 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4506 }
4507
4508 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004509 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4511 }
4512
4513 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004514 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 if (!BaseSpec)
4516 return clang_getNullLocation();
4517
4518 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4519 return cxloc::translateSourceLocation(getCursorContext(C),
4520 TSInfo->getTypeLoc().getBeginLoc());
4521
4522 return cxloc::translateSourceLocation(getCursorContext(C),
4523 BaseSpec->getLocStart());
4524 }
4525
4526 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004527 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4529 }
4530
4531 case CXCursor_OverloadedDeclRef:
4532 return cxloc::translateSourceLocation(getCursorContext(C),
4533 getCursorOverloadedDeclRef(C).second);
4534
4535 default:
4536 // FIXME: Need a way to enumerate all non-reference cases.
4537 llvm_unreachable("Missed a reference kind");
4538 }
4539 }
4540
4541 if (clang_isExpression(C.kind))
4542 return cxloc::translateSourceLocation(getCursorContext(C),
4543 getLocationFromExpr(getCursorExpr(C)));
4544
4545 if (clang_isStatement(C.kind))
4546 return cxloc::translateSourceLocation(getCursorContext(C),
4547 getCursorStmt(C)->getLocStart());
4548
4549 if (C.kind == CXCursor_PreprocessingDirective) {
4550 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4551 return cxloc::translateSourceLocation(getCursorContext(C), L);
4552 }
4553
4554 if (C.kind == CXCursor_MacroExpansion) {
4555 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004556 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 return cxloc::translateSourceLocation(getCursorContext(C), L);
4558 }
4559
4560 if (C.kind == CXCursor_MacroDefinition) {
4561 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4562 return cxloc::translateSourceLocation(getCursorContext(C), L);
4563 }
4564
4565 if (C.kind == CXCursor_InclusionDirective) {
4566 SourceLocation L
4567 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4568 return cxloc::translateSourceLocation(getCursorContext(C), L);
4569 }
4570
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004571 if (clang_isAttribute(C.kind)) {
4572 SourceLocation L
4573 = cxcursor::getCursorAttr(C)->getLocation();
4574 return cxloc::translateSourceLocation(getCursorContext(C), L);
4575 }
4576
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 if (!clang_isDeclaration(C.kind))
4578 return clang_getNullLocation();
4579
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004580 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 if (!D)
4582 return clang_getNullLocation();
4583
4584 SourceLocation Loc = D->getLocation();
4585 // FIXME: Multiple variables declared in a single declaration
4586 // currently lack the information needed to correctly determine their
4587 // ranges when accounting for the type-specifier. We use context
4588 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4589 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004590 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 if (!cxcursor::isFirstInDeclGroup(C))
4592 Loc = VD->getLocation();
4593 }
4594
4595 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004596 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 Loc = MD->getSelectorStartLoc();
4598
4599 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4600}
4601
4602} // end extern "C"
4603
4604CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4605 assert(TU);
4606
4607 // Guard against an invalid SourceLocation, or we may assert in one
4608 // of the following calls.
4609 if (SLoc.isInvalid())
4610 return clang_getNullCursor();
4611
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004612 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004613
4614 // Translate the given source location to make it point at the beginning of
4615 // the token under the cursor.
4616 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4617 CXXUnit->getASTContext().getLangOpts());
4618
4619 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4620 if (SLoc.isValid()) {
4621 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4622 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4623 /*VisitPreprocessorLast=*/true,
4624 /*VisitIncludedEntities=*/false,
4625 SourceLocation(SLoc));
4626 CursorVis.visitFileRegion();
4627 }
4628
4629 return Result;
4630}
4631
4632static SourceRange getRawCursorExtent(CXCursor C) {
4633 if (clang_isReference(C.kind)) {
4634 switch (C.kind) {
4635 case CXCursor_ObjCSuperClassRef:
4636 return getCursorObjCSuperClassRef(C).second;
4637
4638 case CXCursor_ObjCProtocolRef:
4639 return getCursorObjCProtocolRef(C).second;
4640
4641 case CXCursor_ObjCClassRef:
4642 return getCursorObjCClassRef(C).second;
4643
4644 case CXCursor_TypeRef:
4645 return getCursorTypeRef(C).second;
4646
4647 case CXCursor_TemplateRef:
4648 return getCursorTemplateRef(C).second;
4649
4650 case CXCursor_NamespaceRef:
4651 return getCursorNamespaceRef(C).second;
4652
4653 case CXCursor_MemberRef:
4654 return getCursorMemberRef(C).second;
4655
4656 case CXCursor_CXXBaseSpecifier:
4657 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4658
4659 case CXCursor_LabelRef:
4660 return getCursorLabelRef(C).second;
4661
4662 case CXCursor_OverloadedDeclRef:
4663 return getCursorOverloadedDeclRef(C).second;
4664
4665 case CXCursor_VariableRef:
4666 return getCursorVariableRef(C).second;
4667
4668 default:
4669 // FIXME: Need a way to enumerate all non-reference cases.
4670 llvm_unreachable("Missed a reference kind");
4671 }
4672 }
4673
4674 if (clang_isExpression(C.kind))
4675 return getCursorExpr(C)->getSourceRange();
4676
4677 if (clang_isStatement(C.kind))
4678 return getCursorStmt(C)->getSourceRange();
4679
4680 if (clang_isAttribute(C.kind))
4681 return getCursorAttr(C)->getRange();
4682
4683 if (C.kind == CXCursor_PreprocessingDirective)
4684 return cxcursor::getCursorPreprocessingDirective(C);
4685
4686 if (C.kind == CXCursor_MacroExpansion) {
4687 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004688 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 return TU->mapRangeFromPreamble(Range);
4690 }
4691
4692 if (C.kind == CXCursor_MacroDefinition) {
4693 ASTUnit *TU = getCursorASTUnit(C);
4694 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4695 return TU->mapRangeFromPreamble(Range);
4696 }
4697
4698 if (C.kind == CXCursor_InclusionDirective) {
4699 ASTUnit *TU = getCursorASTUnit(C);
4700 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4701 return TU->mapRangeFromPreamble(Range);
4702 }
4703
4704 if (C.kind == CXCursor_TranslationUnit) {
4705 ASTUnit *TU = getCursorASTUnit(C);
4706 FileID MainID = TU->getSourceManager().getMainFileID();
4707 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4708 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4709 return SourceRange(Start, End);
4710 }
4711
4712 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004713 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004714 if (!D)
4715 return SourceRange();
4716
4717 SourceRange R = D->getSourceRange();
4718 // FIXME: Multiple variables declared in a single declaration
4719 // currently lack the information needed to correctly determine their
4720 // ranges when accounting for the type-specifier. We use context
4721 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4722 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004723 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004724 if (!cxcursor::isFirstInDeclGroup(C))
4725 R.setBegin(VD->getLocation());
4726 }
4727 return R;
4728 }
4729 return SourceRange();
4730}
4731
4732/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4733/// the decl-specifier-seq for declarations.
4734static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4735 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004736 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 if (!D)
4738 return SourceRange();
4739
4740 SourceRange R = D->getSourceRange();
4741
4742 // Adjust the start of the location for declarations preceded by
4743 // declaration specifiers.
4744 SourceLocation StartLoc;
4745 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4746 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4747 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004748 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4750 StartLoc = TI->getTypeLoc().getLocStart();
4751 }
4752
4753 if (StartLoc.isValid() && R.getBegin().isValid() &&
4754 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4755 R.setBegin(StartLoc);
4756
4757 // FIXME: Multiple variables declared in a single declaration
4758 // currently lack the information needed to correctly determine their
4759 // ranges when accounting for the type-specifier. We use context
4760 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4761 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004762 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 if (!cxcursor::isFirstInDeclGroup(C))
4764 R.setBegin(VD->getLocation());
4765 }
4766
4767 return R;
4768 }
4769
4770 return getRawCursorExtent(C);
4771}
4772
4773extern "C" {
4774
4775CXSourceRange clang_getCursorExtent(CXCursor C) {
4776 SourceRange R = getRawCursorExtent(C);
4777 if (R.isInvalid())
4778 return clang_getNullRange();
4779
4780 return cxloc::translateSourceRange(getCursorContext(C), R);
4781}
4782
4783CXCursor clang_getCursorReferenced(CXCursor C) {
4784 if (clang_isInvalid(C.kind))
4785 return clang_getNullCursor();
4786
4787 CXTranslationUnit tu = getCursorTU(C);
4788 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004789 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004790 if (!D)
4791 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004792 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004794 if (const ObjCPropertyImplDecl *PropImpl =
4795 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004796 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4797 return MakeCXCursor(Property, tu);
4798
4799 return C;
4800 }
4801
4802 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004803 const Expr *E = getCursorExpr(C);
4804 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004805 if (D) {
4806 CXCursor declCursor = MakeCXCursor(D, tu);
4807 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4808 declCursor);
4809 return declCursor;
4810 }
4811
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004812 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 return MakeCursorOverloadedDeclRef(Ovl, tu);
4814
4815 return clang_getNullCursor();
4816 }
4817
4818 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004819 const Stmt *S = getCursorStmt(C);
4820 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004821 if (LabelDecl *label = Goto->getLabel())
4822 if (LabelStmt *labelS = label->getStmt())
4823 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4824
4825 return clang_getNullCursor();
4826 }
4827
4828 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004829 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 return MakeMacroDefinitionCursor(Def, tu);
4831 }
4832
4833 if (!clang_isReference(C.kind))
4834 return clang_getNullCursor();
4835
4836 switch (C.kind) {
4837 case CXCursor_ObjCSuperClassRef:
4838 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4839
4840 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004841 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4842 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004843 return MakeCXCursor(Def, tu);
4844
4845 return MakeCXCursor(Prot, tu);
4846 }
4847
4848 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004849 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4850 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 return MakeCXCursor(Def, tu);
4852
4853 return MakeCXCursor(Class, tu);
4854 }
4855
4856 case CXCursor_TypeRef:
4857 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4858
4859 case CXCursor_TemplateRef:
4860 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4861
4862 case CXCursor_NamespaceRef:
4863 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4864
4865 case CXCursor_MemberRef:
4866 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4867
4868 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004869 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004870 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4871 tu ));
4872 }
4873
4874 case CXCursor_LabelRef:
4875 // FIXME: We end up faking the "parent" declaration here because we
4876 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004877 return MakeCXCursor(getCursorLabelRef(C).first,
4878 cxtu::getASTUnit(tu)->getASTContext()
4879 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004880 tu);
4881
4882 case CXCursor_OverloadedDeclRef:
4883 return C;
4884
4885 case CXCursor_VariableRef:
4886 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4887
4888 default:
4889 // We would prefer to enumerate all non-reference cursor kinds here.
4890 llvm_unreachable("Unhandled reference cursor kind");
4891 }
4892}
4893
4894CXCursor clang_getCursorDefinition(CXCursor C) {
4895 if (clang_isInvalid(C.kind))
4896 return clang_getNullCursor();
4897
4898 CXTranslationUnit TU = getCursorTU(C);
4899
4900 bool WasReference = false;
4901 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4902 C = clang_getCursorReferenced(C);
4903 WasReference = true;
4904 }
4905
4906 if (C.kind == CXCursor_MacroExpansion)
4907 return clang_getCursorReferenced(C);
4908
4909 if (!clang_isDeclaration(C.kind))
4910 return clang_getNullCursor();
4911
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004912 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 if (!D)
4914 return clang_getNullCursor();
4915
4916 switch (D->getKind()) {
4917 // Declaration kinds that don't really separate the notions of
4918 // declaration and definition.
4919 case Decl::Namespace:
4920 case Decl::Typedef:
4921 case Decl::TypeAlias:
4922 case Decl::TypeAliasTemplate:
4923 case Decl::TemplateTypeParm:
4924 case Decl::EnumConstant:
4925 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004926 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 case Decl::IndirectField:
4928 case Decl::ObjCIvar:
4929 case Decl::ObjCAtDefsField:
4930 case Decl::ImplicitParam:
4931 case Decl::ParmVar:
4932 case Decl::NonTypeTemplateParm:
4933 case Decl::TemplateTemplateParm:
4934 case Decl::ObjCCategoryImpl:
4935 case Decl::ObjCImplementation:
4936 case Decl::AccessSpec:
4937 case Decl::LinkageSpec:
4938 case Decl::ObjCPropertyImpl:
4939 case Decl::FileScopeAsm:
4940 case Decl::StaticAssert:
4941 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004942 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004943 case Decl::Label: // FIXME: Is this right??
4944 case Decl::ClassScopeFunctionSpecialization:
4945 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004946 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004947 return C;
4948
4949 // Declaration kinds that don't make any sense here, but are
4950 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004951 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004952 case Decl::TranslationUnit:
4953 break;
4954
4955 // Declaration kinds for which the definition is not resolvable.
4956 case Decl::UnresolvedUsingTypename:
4957 case Decl::UnresolvedUsingValue:
4958 break;
4959
4960 case Decl::UsingDirective:
4961 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4962 TU);
4963
4964 case Decl::NamespaceAlias:
4965 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4966
4967 case Decl::Enum:
4968 case Decl::Record:
4969 case Decl::CXXRecord:
4970 case Decl::ClassTemplateSpecialization:
4971 case Decl::ClassTemplatePartialSpecialization:
4972 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4973 return MakeCXCursor(Def, TU);
4974 return clang_getNullCursor();
4975
4976 case Decl::Function:
4977 case Decl::CXXMethod:
4978 case Decl::CXXConstructor:
4979 case Decl::CXXDestructor:
4980 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004981 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004982 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004983 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004984 return clang_getNullCursor();
4985 }
4986
Larisse Voufo39a1e502013-08-06 01:03:05 +00004987 case Decl::Var:
4988 case Decl::VarTemplateSpecialization:
4989 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004990 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004991 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 return MakeCXCursor(Def, TU);
4993 return clang_getNullCursor();
4994 }
4995
4996 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004997 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4999 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5000 return clang_getNullCursor();
5001 }
5002
5003 case Decl::ClassTemplate: {
5004 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5005 ->getDefinition())
5006 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5007 TU);
5008 return clang_getNullCursor();
5009 }
5010
Larisse Voufo39a1e502013-08-06 01:03:05 +00005011 case Decl::VarTemplate: {
5012 if (VarDecl *Def =
5013 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5014 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5015 return clang_getNullCursor();
5016 }
5017
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 case Decl::Using:
5019 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5020 D->getLocation(), TU);
5021
5022 case Decl::UsingShadow:
5023 return clang_getCursorDefinition(
5024 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5025 TU));
5026
5027 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005028 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005029 if (Method->isThisDeclarationADefinition())
5030 return C;
5031
5032 // Dig out the method definition in the associated
5033 // @implementation, if we have it.
5034 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005035 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005036 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5037 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5038 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5039 Method->isInstanceMethod()))
5040 if (Def->isThisDeclarationADefinition())
5041 return MakeCXCursor(Def, TU);
5042
5043 return clang_getNullCursor();
5044 }
5045
5046 case Decl::ObjCCategory:
5047 if (ObjCCategoryImplDecl *Impl
5048 = cast<ObjCCategoryDecl>(D)->getImplementation())
5049 return MakeCXCursor(Impl, TU);
5050 return clang_getNullCursor();
5051
5052 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005053 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005054 return MakeCXCursor(Def, TU);
5055 return clang_getNullCursor();
5056
5057 case Decl::ObjCInterface: {
5058 // There are two notions of a "definition" for an Objective-C
5059 // class: the interface and its implementation. When we resolved a
5060 // reference to an Objective-C class, produce the @interface as
5061 // the definition; when we were provided with the interface,
5062 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005063 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005064 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005065 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005066 return MakeCXCursor(Def, TU);
5067 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5068 return MakeCXCursor(Impl, TU);
5069 return clang_getNullCursor();
5070 }
5071
5072 case Decl::ObjCProperty:
5073 // FIXME: We don't really know where to find the
5074 // ObjCPropertyImplDecls that implement this property.
5075 return clang_getNullCursor();
5076
5077 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005078 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005079 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005080 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 return MakeCXCursor(Def, TU);
5082
5083 return clang_getNullCursor();
5084
5085 case Decl::Friend:
5086 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5087 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5088 return clang_getNullCursor();
5089
5090 case Decl::FriendTemplate:
5091 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5092 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5093 return clang_getNullCursor();
5094 }
5095
5096 return clang_getNullCursor();
5097}
5098
5099unsigned clang_isCursorDefinition(CXCursor C) {
5100 if (!clang_isDeclaration(C.kind))
5101 return 0;
5102
5103 return clang_getCursorDefinition(C) == C;
5104}
5105
5106CXCursor clang_getCanonicalCursor(CXCursor C) {
5107 if (!clang_isDeclaration(C.kind))
5108 return C;
5109
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005110 if (const Decl *D = getCursorDecl(C)) {
5111 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005112 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5113 return MakeCXCursor(CatD, getCursorTU(C));
5114
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005115 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5116 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005117 return MakeCXCursor(IFD, getCursorTU(C));
5118
5119 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5120 }
5121
5122 return C;
5123}
5124
5125int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5126 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5127}
5128
5129unsigned clang_getNumOverloadedDecls(CXCursor C) {
5130 if (C.kind != CXCursor_OverloadedDeclRef)
5131 return 0;
5132
5133 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005134 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005135 return E->getNumDecls();
5136
5137 if (OverloadedTemplateStorage *S
5138 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5139 return S->size();
5140
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005141 const Decl *D = Storage.get<const Decl *>();
5142 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 return Using->shadow_size();
5144
5145 return 0;
5146}
5147
5148CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5149 if (cursor.kind != CXCursor_OverloadedDeclRef)
5150 return clang_getNullCursor();
5151
5152 if (index >= clang_getNumOverloadedDecls(cursor))
5153 return clang_getNullCursor();
5154
5155 CXTranslationUnit TU = getCursorTU(cursor);
5156 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005157 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 return MakeCXCursor(E->decls_begin()[index], TU);
5159
5160 if (OverloadedTemplateStorage *S
5161 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5162 return MakeCXCursor(S->begin()[index], TU);
5163
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005164 const Decl *D = Storage.get<const Decl *>();
5165 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 // FIXME: This is, unfortunately, linear time.
5167 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5168 std::advance(Pos, index);
5169 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5170 }
5171
5172 return clang_getNullCursor();
5173}
5174
5175void clang_getDefinitionSpellingAndExtent(CXCursor C,
5176 const char **startBuf,
5177 const char **endBuf,
5178 unsigned *startLine,
5179 unsigned *startColumn,
5180 unsigned *endLine,
5181 unsigned *endColumn) {
5182 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005183 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5185
5186 SourceManager &SM = FD->getASTContext().getSourceManager();
5187 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5188 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5189 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5190 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5191 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5192 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5193}
5194
5195
5196CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5197 unsigned PieceIndex) {
5198 RefNamePieces Pieces;
5199
5200 switch (C.kind) {
5201 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005202 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5204 E->getQualifierLoc().getSourceRange());
5205 break;
5206
5207 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005208 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5210 E->getQualifierLoc().getSourceRange(),
5211 E->getOptionalExplicitTemplateArgs());
5212 break;
5213
5214 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005215 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005217 const Expr *Callee = OCE->getCallee();
5218 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 Callee = ICE->getSubExpr();
5220
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005221 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5223 DRE->getQualifierLoc().getSourceRange());
5224 }
5225 break;
5226
5227 default:
5228 break;
5229 }
5230
5231 if (Pieces.empty()) {
5232 if (PieceIndex == 0)
5233 return clang_getCursorExtent(C);
5234 } else if (PieceIndex < Pieces.size()) {
5235 SourceRange R = Pieces[PieceIndex];
5236 if (R.isValid())
5237 return cxloc::translateSourceRange(getCursorContext(C), R);
5238 }
5239
5240 return clang_getNullRange();
5241}
5242
5243void clang_enableStackTraces(void) {
5244 llvm::sys::PrintStackTraceOnErrorSignal();
5245}
5246
5247void clang_executeOnThread(void (*fn)(void*), void *user_data,
5248 unsigned stack_size) {
5249 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5250}
5251
5252} // end: extern "C"
5253
5254//===----------------------------------------------------------------------===//
5255// Token-based Operations.
5256//===----------------------------------------------------------------------===//
5257
5258/* CXToken layout:
5259 * int_data[0]: a CXTokenKind
5260 * int_data[1]: starting token location
5261 * int_data[2]: token length
5262 * int_data[3]: reserved
5263 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5264 * otherwise unused.
5265 */
5266extern "C" {
5267
5268CXTokenKind clang_getTokenKind(CXToken CXTok) {
5269 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5270}
5271
5272CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5273 switch (clang_getTokenKind(CXTok)) {
5274 case CXToken_Identifier:
5275 case CXToken_Keyword:
5276 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005277 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 ->getNameStart());
5279
5280 case CXToken_Literal: {
5281 // We have stashed the starting pointer in the ptr_data field. Use it.
5282 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005283 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 }
5285
5286 case CXToken_Punctuation:
5287 case CXToken_Comment:
5288 break;
5289 }
5290
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005291 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005292 LOG_BAD_TU(TU);
5293 return cxstring::createEmpty();
5294 }
5295
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 // We have to find the starting buffer pointer the hard way, by
5297 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005298 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005299 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005300 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005301
5302 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5303 std::pair<FileID, unsigned> LocInfo
5304 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5305 bool Invalid = false;
5306 StringRef Buffer
5307 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5308 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005309 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005310
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005311 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005312}
5313
5314CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005315 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005316 LOG_BAD_TU(TU);
5317 return clang_getNullLocation();
5318 }
5319
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005320 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005321 if (!CXXUnit)
5322 return clang_getNullLocation();
5323
5324 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5325 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5326}
5327
5328CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005329 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005330 LOG_BAD_TU(TU);
5331 return clang_getNullRange();
5332 }
5333
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005334 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005335 if (!CXXUnit)
5336 return clang_getNullRange();
5337
5338 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5339 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5340}
5341
5342static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5343 SmallVectorImpl<CXToken> &CXTokens) {
5344 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5345 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005346 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005348 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005349
5350 // Cannot tokenize across files.
5351 if (BeginLocInfo.first != EndLocInfo.first)
5352 return;
5353
5354 // Create a lexer
5355 bool Invalid = false;
5356 StringRef Buffer
5357 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5358 if (Invalid)
5359 return;
5360
5361 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5362 CXXUnit->getASTContext().getLangOpts(),
5363 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5364 Lex.SetCommentRetentionState(true);
5365
5366 // Lex tokens until we hit the end of the range.
5367 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5368 Token Tok;
5369 bool previousWasAt = false;
5370 do {
5371 // Lex the next token
5372 Lex.LexFromRawLexer(Tok);
5373 if (Tok.is(tok::eof))
5374 break;
5375
5376 // Initialize the CXToken.
5377 CXToken CXTok;
5378
5379 // - Common fields
5380 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5381 CXTok.int_data[2] = Tok.getLength();
5382 CXTok.int_data[3] = 0;
5383
5384 // - Kind-specific fields
5385 if (Tok.isLiteral()) {
5386 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005387 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005388 } else if (Tok.is(tok::raw_identifier)) {
5389 // Lookup the identifier to determine whether we have a keyword.
5390 IdentifierInfo *II
5391 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5392
5393 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5394 CXTok.int_data[0] = CXToken_Keyword;
5395 }
5396 else {
5397 CXTok.int_data[0] = Tok.is(tok::identifier)
5398 ? CXToken_Identifier
5399 : CXToken_Keyword;
5400 }
5401 CXTok.ptr_data = II;
5402 } else if (Tok.is(tok::comment)) {
5403 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005404 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005405 } else {
5406 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005407 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 }
5409 CXTokens.push_back(CXTok);
5410 previousWasAt = Tok.is(tok::at);
5411 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5412}
5413
5414void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5415 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005416 LOG_FUNC_SECTION {
5417 *Log << TU << ' ' << Range;
5418 }
5419
Guy Benyei11169dd2012-12-18 14:30:41 +00005420 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005421 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 if (NumTokens)
5423 *NumTokens = 0;
5424
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005425 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005426 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005427 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005428 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005429
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005430 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 if (!CXXUnit || !Tokens || !NumTokens)
5432 return;
5433
5434 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5435
5436 SourceRange R = cxloc::translateCXSourceRange(Range);
5437 if (R.isInvalid())
5438 return;
5439
5440 SmallVector<CXToken, 32> CXTokens;
5441 getTokens(CXXUnit, R, CXTokens);
5442
5443 if (CXTokens.empty())
5444 return;
5445
5446 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5447 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5448 *NumTokens = CXTokens.size();
5449}
5450
5451void clang_disposeTokens(CXTranslationUnit TU,
5452 CXToken *Tokens, unsigned NumTokens) {
5453 free(Tokens);
5454}
5455
5456} // end: extern "C"
5457
5458//===----------------------------------------------------------------------===//
5459// Token annotation APIs.
5460//===----------------------------------------------------------------------===//
5461
Guy Benyei11169dd2012-12-18 14:30:41 +00005462static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5463 CXCursor parent,
5464 CXClientData client_data);
5465static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5466 CXClientData client_data);
5467
5468namespace {
5469class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005470 CXToken *Tokens;
5471 CXCursor *Cursors;
5472 unsigned NumTokens;
5473 unsigned TokIdx;
5474 unsigned PreprocessingTokIdx;
5475 CursorVisitor AnnotateVis;
5476 SourceManager &SrcMgr;
5477 bool HasContextSensitiveKeywords;
5478
5479 struct PostChildrenInfo {
5480 CXCursor Cursor;
5481 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005482 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005483 unsigned BeforeChildrenTokenIdx;
5484 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005485 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005486
5487 CXToken &getTok(unsigned Idx) {
5488 assert(Idx < NumTokens);
5489 return Tokens[Idx];
5490 }
5491 const CXToken &getTok(unsigned Idx) const {
5492 assert(Idx < NumTokens);
5493 return Tokens[Idx];
5494 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005495 bool MoreTokens() const { return TokIdx < NumTokens; }
5496 unsigned NextToken() const { return TokIdx; }
5497 void AdvanceToken() { ++TokIdx; }
5498 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005499 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005500 }
5501 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005502 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005503 }
5504 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005505 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005506 }
5507
5508 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005509 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005510 SourceRange);
5511
5512public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005513 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005514 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005515 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005516 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005517 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005518 AnnotateTokensVisitor, this,
5519 /*VisitPreprocessorLast=*/true,
5520 /*VisitIncludedEntities=*/false,
5521 RegionOfInterest,
5522 /*VisitDeclsOnly=*/false,
5523 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005524 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 HasContextSensitiveKeywords(false) { }
5526
5527 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5528 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5529 bool postVisitChildren(CXCursor cursor);
5530 void AnnotateTokens();
5531
5532 /// \brief Determine whether the annotator saw any cursors that have
5533 /// context-sensitive keywords.
5534 bool hasContextSensitiveKeywords() const {
5535 return HasContextSensitiveKeywords;
5536 }
5537
5538 ~AnnotateTokensWorker() {
5539 assert(PostChildrenInfos.empty());
5540 }
5541};
5542}
5543
5544void AnnotateTokensWorker::AnnotateTokens() {
5545 // Walk the AST within the region of interest, annotating tokens
5546 // along the way.
5547 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005548}
Guy Benyei11169dd2012-12-18 14:30:41 +00005549
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005550static inline void updateCursorAnnotation(CXCursor &Cursor,
5551 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005552 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005553 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005554 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005555}
5556
5557/// \brief It annotates and advances tokens with a cursor until the comparison
5558//// between the cursor location and the source range is the same as
5559/// \arg compResult.
5560///
5561/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5562/// Pass RangeOverlap to annotate tokens inside a range.
5563void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5564 RangeComparisonResult compResult,
5565 SourceRange range) {
5566 while (MoreTokens()) {
5567 const unsigned I = NextToken();
5568 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005569 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5570 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005571
5572 SourceLocation TokLoc = GetTokenLoc(I);
5573 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005574 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005575 AdvanceToken();
5576 continue;
5577 }
5578 break;
5579 }
5580}
5581
5582/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005583/// \returns true if it advanced beyond all macro tokens, false otherwise.
5584bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005585 CXCursor updateC,
5586 RangeComparisonResult compResult,
5587 SourceRange range) {
5588 assert(MoreTokens());
5589 assert(isFunctionMacroToken(NextToken()) &&
5590 "Should be called only for macro arg tokens");
5591
5592 // This works differently than annotateAndAdvanceTokens; because expanded
5593 // macro arguments can have arbitrary translation-unit source order, we do not
5594 // advance the token index one by one until a token fails the range test.
5595 // We only advance once past all of the macro arg tokens if all of them
5596 // pass the range test. If one of them fails we keep the token index pointing
5597 // at the start of the macro arg tokens so that the failing token will be
5598 // annotated by a subsequent annotation try.
5599
5600 bool atLeastOneCompFail = false;
5601
5602 unsigned I = NextToken();
5603 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5604 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5605 if (TokLoc.isFileID())
5606 continue; // not macro arg token, it's parens or comma.
5607 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5608 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5609 Cursors[I] = updateC;
5610 } else
5611 atLeastOneCompFail = true;
5612 }
5613
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005614 if (atLeastOneCompFail)
5615 return false;
5616
5617 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5618 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005619}
5620
5621enum CXChildVisitResult
5622AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005623 SourceRange cursorRange = getRawCursorExtent(cursor);
5624 if (cursorRange.isInvalid())
5625 return CXChildVisit_Recurse;
5626
5627 if (!HasContextSensitiveKeywords) {
5628 // Objective-C properties can have context-sensitive keywords.
5629 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005630 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005631 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5632 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5633 }
5634 // Objective-C methods can have context-sensitive keywords.
5635 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5636 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005637 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005638 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5639 if (Method->getObjCDeclQualifier())
5640 HasContextSensitiveKeywords = true;
5641 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005642 for (const auto *P : Method->params()) {
5643 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005644 HasContextSensitiveKeywords = true;
5645 break;
5646 }
5647 }
5648 }
5649 }
5650 }
5651 // C++ methods can have context-sensitive keywords.
5652 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005653 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005654 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5655 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5656 HasContextSensitiveKeywords = true;
5657 }
5658 }
5659 // C++ classes can have context-sensitive keywords.
5660 else if (cursor.kind == CXCursor_StructDecl ||
5661 cursor.kind == CXCursor_ClassDecl ||
5662 cursor.kind == CXCursor_ClassTemplate ||
5663 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005664 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005665 if (D->hasAttr<FinalAttr>())
5666 HasContextSensitiveKeywords = true;
5667 }
5668 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005669
5670 // Don't override a property annotation with its getter/setter method.
5671 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5672 parent.kind == CXCursor_ObjCPropertyDecl)
5673 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005674
5675 if (clang_isPreprocessing(cursor.kind)) {
5676 // Items in the preprocessing record are kept separate from items in
5677 // declarations, so we keep a separate token index.
5678 unsigned SavedTokIdx = TokIdx;
5679 TokIdx = PreprocessingTokIdx;
5680
5681 // Skip tokens up until we catch up to the beginning of the preprocessing
5682 // entry.
5683 while (MoreTokens()) {
5684 const unsigned I = NextToken();
5685 SourceLocation TokLoc = GetTokenLoc(I);
5686 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5687 case RangeBefore:
5688 AdvanceToken();
5689 continue;
5690 case RangeAfter:
5691 case RangeOverlap:
5692 break;
5693 }
5694 break;
5695 }
5696
5697 // Look at all of the tokens within this range.
5698 while (MoreTokens()) {
5699 const unsigned I = NextToken();
5700 SourceLocation TokLoc = GetTokenLoc(I);
5701 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5702 case RangeBefore:
5703 llvm_unreachable("Infeasible");
5704 case RangeAfter:
5705 break;
5706 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005707 // For macro expansions, just note where the beginning of the macro
5708 // expansion occurs.
5709 if (cursor.kind == CXCursor_MacroExpansion) {
5710 if (TokLoc == cursorRange.getBegin())
5711 Cursors[I] = cursor;
5712 AdvanceToken();
5713 break;
5714 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005715 // We may have already annotated macro names inside macro definitions.
5716 if (Cursors[I].kind != CXCursor_MacroExpansion)
5717 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005718 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005719 continue;
5720 }
5721 break;
5722 }
5723
5724 // Save the preprocessing token index; restore the non-preprocessing
5725 // token index.
5726 PreprocessingTokIdx = TokIdx;
5727 TokIdx = SavedTokIdx;
5728 return CXChildVisit_Recurse;
5729 }
5730
5731 if (cursorRange.isInvalid())
5732 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005733
5734 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005735 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 const enum CXCursorKind K = clang_getCursorKind(parent);
5737 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005738 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5739 // Attributes are annotated out-of-order, skip tokens until we reach it.
5740 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005741 ? clang_getNullCursor() : parent;
5742
5743 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5744
5745 // Avoid having the cursor of an expression "overwrite" the annotation of the
5746 // variable declaration that it belongs to.
5747 // This can happen for C++ constructor expressions whose range generally
5748 // include the variable declaration, e.g.:
5749 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005750 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005751 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005752 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005753 const unsigned I = NextToken();
5754 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5755 E->getLocStart() == D->getLocation() &&
5756 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005757 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005758 AdvanceToken();
5759 }
5760 }
5761 }
5762
5763 // Before recursing into the children keep some state that we are going
5764 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5765 // extra work after the child nodes are visited.
5766 // Note that we don't call VisitChildren here to avoid traversing statements
5767 // code-recursively which can blow the stack.
5768
5769 PostChildrenInfo Info;
5770 Info.Cursor = cursor;
5771 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005772 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005773 Info.BeforeChildrenTokenIdx = NextToken();
5774 PostChildrenInfos.push_back(Info);
5775
5776 return CXChildVisit_Recurse;
5777}
5778
5779bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5780 if (PostChildrenInfos.empty())
5781 return false;
5782 const PostChildrenInfo &Info = PostChildrenInfos.back();
5783 if (!clang_equalCursors(Info.Cursor, cursor))
5784 return false;
5785
5786 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5787 const unsigned AfterChildren = NextToken();
5788 SourceRange cursorRange = Info.CursorRange;
5789
5790 // Scan the tokens that are at the end of the cursor, but are not captured
5791 // but the child cursors.
5792 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5793
5794 // Scan the tokens that are at the beginning of the cursor, but are not
5795 // capture by the child cursors.
5796 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5797 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5798 break;
5799
5800 Cursors[I] = cursor;
5801 }
5802
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005803 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5804 // encountered the attribute cursor.
5805 if (clang_isAttribute(cursor.kind))
5806 TokIdx = Info.BeforeReachingCursorIdx;
5807
Guy Benyei11169dd2012-12-18 14:30:41 +00005808 PostChildrenInfos.pop_back();
5809 return false;
5810}
5811
5812static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5813 CXCursor parent,
5814 CXClientData client_data) {
5815 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5816}
5817
5818static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5819 CXClientData client_data) {
5820 return static_cast<AnnotateTokensWorker*>(client_data)->
5821 postVisitChildren(cursor);
5822}
5823
5824namespace {
5825
5826/// \brief Uses the macro expansions in the preprocessing record to find
5827/// and mark tokens that are macro arguments. This info is used by the
5828/// AnnotateTokensWorker.
5829class MarkMacroArgTokensVisitor {
5830 SourceManager &SM;
5831 CXToken *Tokens;
5832 unsigned NumTokens;
5833 unsigned CurIdx;
5834
5835public:
5836 MarkMacroArgTokensVisitor(SourceManager &SM,
5837 CXToken *tokens, unsigned numTokens)
5838 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5839
5840 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5841 if (cursor.kind != CXCursor_MacroExpansion)
5842 return CXChildVisit_Continue;
5843
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005844 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005845 if (macroRange.getBegin() == macroRange.getEnd())
5846 return CXChildVisit_Continue; // it's not a function macro.
5847
5848 for (; CurIdx < NumTokens; ++CurIdx) {
5849 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5850 macroRange.getBegin()))
5851 break;
5852 }
5853
5854 if (CurIdx == NumTokens)
5855 return CXChildVisit_Break;
5856
5857 for (; CurIdx < NumTokens; ++CurIdx) {
5858 SourceLocation tokLoc = getTokenLoc(CurIdx);
5859 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5860 break;
5861
5862 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5863 }
5864
5865 if (CurIdx == NumTokens)
5866 return CXChildVisit_Break;
5867
5868 return CXChildVisit_Continue;
5869 }
5870
5871private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005872 CXToken &getTok(unsigned Idx) {
5873 assert(Idx < NumTokens);
5874 return Tokens[Idx];
5875 }
5876 const CXToken &getTok(unsigned Idx) const {
5877 assert(Idx < NumTokens);
5878 return Tokens[Idx];
5879 }
5880
Guy Benyei11169dd2012-12-18 14:30:41 +00005881 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005882 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005883 }
5884
5885 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5886 // The third field is reserved and currently not used. Use it here
5887 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005888 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005889 }
5890};
5891
5892} // end anonymous namespace
5893
5894static CXChildVisitResult
5895MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5896 CXClientData client_data) {
5897 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5898 parent);
5899}
5900
5901namespace {
5902 struct clang_annotateTokens_Data {
5903 CXTranslationUnit TU;
5904 ASTUnit *CXXUnit;
5905 CXToken *Tokens;
5906 unsigned NumTokens;
5907 CXCursor *Cursors;
5908 };
5909}
5910
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005911/// \brief Used by \c annotatePreprocessorTokens.
5912/// \returns true if lexing was finished, false otherwise.
5913static bool lexNext(Lexer &Lex, Token &Tok,
5914 unsigned &NextIdx, unsigned NumTokens) {
5915 if (NextIdx >= NumTokens)
5916 return true;
5917
5918 ++NextIdx;
5919 Lex.LexFromRawLexer(Tok);
5920 if (Tok.is(tok::eof))
5921 return true;
5922
5923 return false;
5924}
5925
Guy Benyei11169dd2012-12-18 14:30:41 +00005926static void annotatePreprocessorTokens(CXTranslationUnit TU,
5927 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005928 CXCursor *Cursors,
5929 CXToken *Tokens,
5930 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005931 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005932
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005933 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005934 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5935 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005936 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005937 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005938 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005939
5940 if (BeginLocInfo.first != EndLocInfo.first)
5941 return;
5942
5943 StringRef Buffer;
5944 bool Invalid = false;
5945 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5946 if (Buffer.empty() || Invalid)
5947 return;
5948
5949 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5950 CXXUnit->getASTContext().getLangOpts(),
5951 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5952 Buffer.end());
5953 Lex.SetCommentRetentionState(true);
5954
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005955 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005956 // Lex tokens in raw mode until we hit the end of the range, to avoid
5957 // entering #includes or expanding macros.
5958 while (true) {
5959 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005960 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5961 break;
5962 unsigned TokIdx = NextIdx-1;
5963 assert(Tok.getLocation() ==
5964 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005965
5966 reprocess:
5967 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005968 // We have found a preprocessing directive. Annotate the tokens
5969 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005970 //
5971 // FIXME: Some simple tests here could identify macro definitions and
5972 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005973
5974 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005975 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5976 break;
5977
Craig Topper69186e72014-06-08 08:38:04 +00005978 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005979 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005980 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5981 break;
5982
5983 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005984 IdentifierInfo &II =
5985 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005986 SourceLocation MappedTokLoc =
5987 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5988 MI = getMacroInfo(II, MappedTokLoc, TU);
5989 }
5990 }
5991
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005992 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005993 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005994 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5995 finished = true;
5996 break;
5997 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005998 // If we are in a macro definition, check if the token was ever a
5999 // macro name and annotate it if that's the case.
6000 if (MI) {
6001 SourceLocation SaveLoc = Tok.getLocation();
6002 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6003 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
6004 Tok.setLocation(SaveLoc);
6005 if (MacroDef)
6006 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6007 Tok.getLocation(), TU);
6008 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006009 } while (!Tok.isAtStartOfLine());
6010
6011 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6012 assert(TokIdx <= LastIdx);
6013 SourceLocation EndLoc =
6014 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6015 CXCursor Cursor =
6016 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6017
6018 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006019 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006020
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006021 if (finished)
6022 break;
6023 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006024 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006025 }
6026}
6027
6028// This gets run a separate thread to avoid stack blowout.
6029static void clang_annotateTokensImpl(void *UserData) {
6030 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6031 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6032 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6033 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6034 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6035
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006036 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006037 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6038 setThreadBackgroundPriority();
6039
6040 // Determine the region of interest, which contains all of the tokens.
6041 SourceRange RegionOfInterest;
6042 RegionOfInterest.setBegin(
6043 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6044 RegionOfInterest.setEnd(
6045 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6046 Tokens[NumTokens-1])));
6047
Guy Benyei11169dd2012-12-18 14:30:41 +00006048 // Relex the tokens within the source range to look for preprocessing
6049 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006050 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006051
6052 // If begin location points inside a macro argument, set it to the expansion
6053 // location so we can have the full context when annotating semantically.
6054 {
6055 SourceManager &SM = CXXUnit->getSourceManager();
6056 SourceLocation Loc =
6057 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6058 if (Loc.isMacroID())
6059 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6060 }
6061
Guy Benyei11169dd2012-12-18 14:30:41 +00006062 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6063 // Search and mark tokens that are macro argument expansions.
6064 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6065 Tokens, NumTokens);
6066 CursorVisitor MacroArgMarker(TU,
6067 MarkMacroArgTokensVisitorDelegate, &Visitor,
6068 /*VisitPreprocessorLast=*/true,
6069 /*VisitIncludedEntities=*/false,
6070 RegionOfInterest);
6071 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6072 }
6073
6074 // Annotate all of the source locations in the region of interest that map to
6075 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006076 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006077
6078 // FIXME: We use a ridiculous stack size here because the data-recursion
6079 // algorithm uses a large stack frame than the non-data recursive version,
6080 // and AnnotationTokensWorker currently transforms the data-recursion
6081 // algorithm back into a traditional recursion by explicitly calling
6082 // VisitChildren(). We will need to remove this explicit recursive call.
6083 W.AnnotateTokens();
6084
6085 // If we ran into any entities that involve context-sensitive keywords,
6086 // take another pass through the tokens to mark them as such.
6087 if (W.hasContextSensitiveKeywords()) {
6088 for (unsigned I = 0; I != NumTokens; ++I) {
6089 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6090 continue;
6091
6092 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6093 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006094 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006095 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6096 if (Property->getPropertyAttributesAsWritten() != 0 &&
6097 llvm::StringSwitch<bool>(II->getName())
6098 .Case("readonly", true)
6099 .Case("assign", true)
6100 .Case("unsafe_unretained", true)
6101 .Case("readwrite", true)
6102 .Case("retain", true)
6103 .Case("copy", true)
6104 .Case("nonatomic", true)
6105 .Case("atomic", true)
6106 .Case("getter", true)
6107 .Case("setter", true)
6108 .Case("strong", true)
6109 .Case("weak", true)
6110 .Default(false))
6111 Tokens[I].int_data[0] = CXToken_Keyword;
6112 }
6113 continue;
6114 }
6115
6116 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6117 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6118 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6119 if (llvm::StringSwitch<bool>(II->getName())
6120 .Case("in", true)
6121 .Case("out", true)
6122 .Case("inout", true)
6123 .Case("oneway", true)
6124 .Case("bycopy", true)
6125 .Case("byref", true)
6126 .Default(false))
6127 Tokens[I].int_data[0] = CXToken_Keyword;
6128 continue;
6129 }
6130
6131 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6132 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6133 Tokens[I].int_data[0] = CXToken_Keyword;
6134 continue;
6135 }
6136 }
6137 }
6138}
6139
6140extern "C" {
6141
6142void clang_annotateTokens(CXTranslationUnit TU,
6143 CXToken *Tokens, unsigned NumTokens,
6144 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006145 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006146 LOG_BAD_TU(TU);
6147 return;
6148 }
6149 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006150 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006151 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006152 }
6153
6154 LOG_FUNC_SECTION {
6155 *Log << TU << ' ';
6156 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6157 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6158 *Log << clang_getRange(bloc, eloc);
6159 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006160
6161 // Any token we don't specifically annotate will have a NULL cursor.
6162 CXCursor C = clang_getNullCursor();
6163 for (unsigned I = 0; I != NumTokens; ++I)
6164 Cursors[I] = C;
6165
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006166 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006167 if (!CXXUnit)
6168 return;
6169
6170 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6171
6172 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6173 llvm::CrashRecoveryContext CRC;
6174 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6175 GetSafetyThreadStackSize() * 2)) {
6176 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6177 }
6178}
6179
6180} // end: extern "C"
6181
6182//===----------------------------------------------------------------------===//
6183// Operations for querying linkage of a cursor.
6184//===----------------------------------------------------------------------===//
6185
6186extern "C" {
6187CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6188 if (!clang_isDeclaration(cursor.kind))
6189 return CXLinkage_Invalid;
6190
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006191 const Decl *D = cxcursor::getCursorDecl(cursor);
6192 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006193 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006194 case NoLinkage:
6195 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006196 case InternalLinkage: return CXLinkage_Internal;
6197 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6198 case ExternalLinkage: return CXLinkage_External;
6199 };
6200
6201 return CXLinkage_Invalid;
6202}
6203} // end: extern "C"
6204
6205//===----------------------------------------------------------------------===//
6206// Operations for querying language of a cursor.
6207//===----------------------------------------------------------------------===//
6208
6209static CXLanguageKind getDeclLanguage(const Decl *D) {
6210 if (!D)
6211 return CXLanguage_C;
6212
6213 switch (D->getKind()) {
6214 default:
6215 break;
6216 case Decl::ImplicitParam:
6217 case Decl::ObjCAtDefsField:
6218 case Decl::ObjCCategory:
6219 case Decl::ObjCCategoryImpl:
6220 case Decl::ObjCCompatibleAlias:
6221 case Decl::ObjCImplementation:
6222 case Decl::ObjCInterface:
6223 case Decl::ObjCIvar:
6224 case Decl::ObjCMethod:
6225 case Decl::ObjCProperty:
6226 case Decl::ObjCPropertyImpl:
6227 case Decl::ObjCProtocol:
6228 return CXLanguage_ObjC;
6229 case Decl::CXXConstructor:
6230 case Decl::CXXConversion:
6231 case Decl::CXXDestructor:
6232 case Decl::CXXMethod:
6233 case Decl::CXXRecord:
6234 case Decl::ClassTemplate:
6235 case Decl::ClassTemplatePartialSpecialization:
6236 case Decl::ClassTemplateSpecialization:
6237 case Decl::Friend:
6238 case Decl::FriendTemplate:
6239 case Decl::FunctionTemplate:
6240 case Decl::LinkageSpec:
6241 case Decl::Namespace:
6242 case Decl::NamespaceAlias:
6243 case Decl::NonTypeTemplateParm:
6244 case Decl::StaticAssert:
6245 case Decl::TemplateTemplateParm:
6246 case Decl::TemplateTypeParm:
6247 case Decl::UnresolvedUsingTypename:
6248 case Decl::UnresolvedUsingValue:
6249 case Decl::Using:
6250 case Decl::UsingDirective:
6251 case Decl::UsingShadow:
6252 return CXLanguage_CPlusPlus;
6253 }
6254
6255 return CXLanguage_C;
6256}
6257
6258extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006259
6260static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6261 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6262 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006263
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006264 switch (D->getAvailability()) {
6265 case AR_Available:
6266 case AR_NotYetIntroduced:
6267 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006268 return getCursorAvailabilityForDecl(
6269 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006270 return CXAvailability_Available;
6271
6272 case AR_Deprecated:
6273 return CXAvailability_Deprecated;
6274
6275 case AR_Unavailable:
6276 return CXAvailability_NotAvailable;
6277 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006278
6279 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006280}
6281
Guy Benyei11169dd2012-12-18 14:30:41 +00006282enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6283 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006284 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6285 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006286
6287 return CXAvailability_Available;
6288}
6289
6290static CXVersion convertVersion(VersionTuple In) {
6291 CXVersion Out = { -1, -1, -1 };
6292 if (In.empty())
6293 return Out;
6294
6295 Out.Major = In.getMajor();
6296
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006297 Optional<unsigned> Minor = In.getMinor();
6298 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006299 Out.Minor = *Minor;
6300 else
6301 return Out;
6302
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006303 Optional<unsigned> Subminor = In.getSubminor();
6304 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006305 Out.Subminor = *Subminor;
6306
6307 return Out;
6308}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006309
6310static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6311 int *always_deprecated,
6312 CXString *deprecated_message,
6313 int *always_unavailable,
6314 CXString *unavailable_message,
6315 CXPlatformAvailability *availability,
6316 int availability_size) {
6317 bool HadAvailAttr = false;
6318 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006319 for (auto A : D->attrs()) {
6320 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006321 HadAvailAttr = true;
6322 if (always_deprecated)
6323 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006324 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006325 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006326 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006327 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006328 continue;
6329 }
6330
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006331 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006332 HadAvailAttr = true;
6333 if (always_unavailable)
6334 *always_unavailable = 1;
6335 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006336 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006337 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6338 }
6339 continue;
6340 }
6341
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006342 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006343 HadAvailAttr = true;
6344 if (N < availability_size) {
6345 availability[N].Platform
6346 = cxstring::createDup(Avail->getPlatform()->getName());
6347 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6348 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6349 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6350 availability[N].Unavailable = Avail->getUnavailable();
6351 availability[N].Message = cxstring::createDup(Avail->getMessage());
6352 }
6353 ++N;
6354 }
6355 }
6356
6357 if (!HadAvailAttr)
6358 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6359 return getCursorPlatformAvailabilityForDecl(
6360 cast<Decl>(EnumConst->getDeclContext()),
6361 always_deprecated,
6362 deprecated_message,
6363 always_unavailable,
6364 unavailable_message,
6365 availability,
6366 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006367
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006368 return N;
6369}
6370
Guy Benyei11169dd2012-12-18 14:30:41 +00006371int clang_getCursorPlatformAvailability(CXCursor cursor,
6372 int *always_deprecated,
6373 CXString *deprecated_message,
6374 int *always_unavailable,
6375 CXString *unavailable_message,
6376 CXPlatformAvailability *availability,
6377 int availability_size) {
6378 if (always_deprecated)
6379 *always_deprecated = 0;
6380 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006381 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 if (always_unavailable)
6383 *always_unavailable = 0;
6384 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006385 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006386
Guy Benyei11169dd2012-12-18 14:30:41 +00006387 if (!clang_isDeclaration(cursor.kind))
6388 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006389
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006390 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006391 if (!D)
6392 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006393
6394 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6395 deprecated_message,
6396 always_unavailable,
6397 unavailable_message,
6398 availability,
6399 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006400}
6401
6402void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6403 clang_disposeString(availability->Platform);
6404 clang_disposeString(availability->Message);
6405}
6406
6407CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6408 if (clang_isDeclaration(cursor.kind))
6409 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6410
6411 return CXLanguage_Invalid;
6412}
6413
6414 /// \brief If the given cursor is the "templated" declaration
6415 /// descibing a class or function template, return the class or
6416 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006417static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006418 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006419 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006420
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006421 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006422 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6423 return FunTmpl;
6424
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006425 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006426 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6427 return ClassTmpl;
6428
6429 return D;
6430}
6431
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006432
6433enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6434 StorageClass sc = SC_None;
6435 const Decl *D = getCursorDecl(C);
6436 if (D) {
6437 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6438 sc = FD->getStorageClass();
6439 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6440 sc = VD->getStorageClass();
6441 } else {
6442 return CX_SC_Invalid;
6443 }
6444 } else {
6445 return CX_SC_Invalid;
6446 }
6447 switch (sc) {
6448 case SC_None:
6449 return CX_SC_None;
6450 case SC_Extern:
6451 return CX_SC_Extern;
6452 case SC_Static:
6453 return CX_SC_Static;
6454 case SC_PrivateExtern:
6455 return CX_SC_PrivateExtern;
6456 case SC_OpenCLWorkGroupLocal:
6457 return CX_SC_OpenCLWorkGroupLocal;
6458 case SC_Auto:
6459 return CX_SC_Auto;
6460 case SC_Register:
6461 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006462 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006463 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006464}
6465
Guy Benyei11169dd2012-12-18 14:30:41 +00006466CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6467 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006468 if (const Decl *D = getCursorDecl(cursor)) {
6469 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006470 if (!DC)
6471 return clang_getNullCursor();
6472
6473 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6474 getCursorTU(cursor));
6475 }
6476 }
6477
6478 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006479 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006480 return MakeCXCursor(D, getCursorTU(cursor));
6481 }
6482
6483 return clang_getNullCursor();
6484}
6485
6486CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6487 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006488 if (const Decl *D = getCursorDecl(cursor)) {
6489 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006490 if (!DC)
6491 return clang_getNullCursor();
6492
6493 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6494 getCursorTU(cursor));
6495 }
6496 }
6497
6498 // FIXME: Note that we can't easily compute the lexical context of a
6499 // statement or expression, so we return nothing.
6500 return clang_getNullCursor();
6501}
6502
6503CXFile clang_getIncludedFile(CXCursor cursor) {
6504 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006505 return nullptr;
6506
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006507 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006508 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006509}
6510
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006511unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6512 if (C.kind != CXCursor_ObjCPropertyDecl)
6513 return CXObjCPropertyAttr_noattr;
6514
6515 unsigned Result = CXObjCPropertyAttr_noattr;
6516 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6517 ObjCPropertyDecl::PropertyAttributeKind Attr =
6518 PD->getPropertyAttributesAsWritten();
6519
6520#define SET_CXOBJCPROP_ATTR(A) \
6521 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6522 Result |= CXObjCPropertyAttr_##A
6523 SET_CXOBJCPROP_ATTR(readonly);
6524 SET_CXOBJCPROP_ATTR(getter);
6525 SET_CXOBJCPROP_ATTR(assign);
6526 SET_CXOBJCPROP_ATTR(readwrite);
6527 SET_CXOBJCPROP_ATTR(retain);
6528 SET_CXOBJCPROP_ATTR(copy);
6529 SET_CXOBJCPROP_ATTR(nonatomic);
6530 SET_CXOBJCPROP_ATTR(setter);
6531 SET_CXOBJCPROP_ATTR(atomic);
6532 SET_CXOBJCPROP_ATTR(weak);
6533 SET_CXOBJCPROP_ATTR(strong);
6534 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6535#undef SET_CXOBJCPROP_ATTR
6536
6537 return Result;
6538}
6539
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006540unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6541 if (!clang_isDeclaration(C.kind))
6542 return CXObjCDeclQualifier_None;
6543
6544 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6545 const Decl *D = getCursorDecl(C);
6546 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6547 QT = MD->getObjCDeclQualifier();
6548 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6549 QT = PD->getObjCDeclQualifier();
6550 if (QT == Decl::OBJC_TQ_None)
6551 return CXObjCDeclQualifier_None;
6552
6553 unsigned Result = CXObjCDeclQualifier_None;
6554 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6555 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6556 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6557 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6558 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6559 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6560
6561 return Result;
6562}
6563
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006564unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6565 if (!clang_isDeclaration(C.kind))
6566 return 0;
6567
6568 const Decl *D = getCursorDecl(C);
6569 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6570 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6571 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6572 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6573
6574 return 0;
6575}
6576
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006577unsigned clang_Cursor_isVariadic(CXCursor C) {
6578 if (!clang_isDeclaration(C.kind))
6579 return 0;
6580
6581 const Decl *D = getCursorDecl(C);
6582 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6583 return FD->isVariadic();
6584 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6585 return MD->isVariadic();
6586
6587 return 0;
6588}
6589
Guy Benyei11169dd2012-12-18 14:30:41 +00006590CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6591 if (!clang_isDeclaration(C.kind))
6592 return clang_getNullRange();
6593
6594 const Decl *D = getCursorDecl(C);
6595 ASTContext &Context = getCursorContext(C);
6596 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6597 if (!RC)
6598 return clang_getNullRange();
6599
6600 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6601}
6602
6603CXString clang_Cursor_getRawCommentText(CXCursor C) {
6604 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006605 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006606
6607 const Decl *D = getCursorDecl(C);
6608 ASTContext &Context = getCursorContext(C);
6609 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6610 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6611 StringRef();
6612
6613 // Don't duplicate the string because RawText points directly into source
6614 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006615 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006616}
6617
6618CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6619 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006620 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006621
6622 const Decl *D = getCursorDecl(C);
6623 const ASTContext &Context = getCursorContext(C);
6624 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6625
6626 if (RC) {
6627 StringRef BriefText = RC->getBriefText(Context);
6628
6629 // Don't duplicate the string because RawComment ensures that this memory
6630 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006631 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006632 }
6633
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006634 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006635}
6636
Guy Benyei11169dd2012-12-18 14:30:41 +00006637CXModule clang_Cursor_getModule(CXCursor C) {
6638 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006639 if (const ImportDecl *ImportD =
6640 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006641 return ImportD->getImportedModule();
6642 }
6643
Craig Topper69186e72014-06-08 08:38:04 +00006644 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006645}
6646
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006647CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6648 if (isNotUsableTU(TU)) {
6649 LOG_BAD_TU(TU);
6650 return nullptr;
6651 }
6652 if (!File)
6653 return nullptr;
6654 FileEntry *FE = static_cast<FileEntry *>(File);
6655
6656 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6657 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6658 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6659
Richard Smithfeb54b62014-10-23 02:01:19 +00006660 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006661}
6662
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006663CXFile clang_Module_getASTFile(CXModule CXMod) {
6664 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006665 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006666 Module *Mod = static_cast<Module*>(CXMod);
6667 return const_cast<FileEntry *>(Mod->getASTFile());
6668}
6669
Guy Benyei11169dd2012-12-18 14:30:41 +00006670CXModule clang_Module_getParent(CXModule CXMod) {
6671 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006672 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006673 Module *Mod = static_cast<Module*>(CXMod);
6674 return Mod->Parent;
6675}
6676
6677CXString clang_Module_getName(CXModule CXMod) {
6678 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006679 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006680 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006681 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006682}
6683
6684CXString clang_Module_getFullName(CXModule CXMod) {
6685 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006686 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006687 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006688 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006689}
6690
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006691int clang_Module_isSystem(CXModule CXMod) {
6692 if (!CXMod)
6693 return 0;
6694 Module *Mod = static_cast<Module*>(CXMod);
6695 return Mod->IsSystem;
6696}
6697
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006698unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6699 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006700 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006701 LOG_BAD_TU(TU);
6702 return 0;
6703 }
6704 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006705 return 0;
6706 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006707 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6708 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6709 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006710}
6711
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006712CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6713 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006714 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006715 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006716 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006717 }
6718 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006719 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006720 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006721 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006722
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006723 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6724 if (Index < TopHeaders.size())
6725 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006726
Craig Topper69186e72014-06-08 08:38:04 +00006727 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006728}
6729
6730} // end: extern "C"
6731
6732//===----------------------------------------------------------------------===//
6733// C++ AST instrospection.
6734//===----------------------------------------------------------------------===//
6735
6736extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006737unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6738 if (!clang_isDeclaration(C.kind))
6739 return 0;
6740
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006741 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006742 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006743 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006744 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6745}
6746
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006747unsigned clang_CXXMethod_isConst(CXCursor C) {
6748 if (!clang_isDeclaration(C.kind))
6749 return 0;
6750
6751 const Decl *D = cxcursor::getCursorDecl(C);
6752 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006753 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006754 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6755}
6756
Guy Benyei11169dd2012-12-18 14:30:41 +00006757unsigned clang_CXXMethod_isStatic(CXCursor C) {
6758 if (!clang_isDeclaration(C.kind))
6759 return 0;
6760
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006761 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006762 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006763 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006764 return (Method && Method->isStatic()) ? 1 : 0;
6765}
6766
6767unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6768 if (!clang_isDeclaration(C.kind))
6769 return 0;
6770
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006771 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006772 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006773 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006774 return (Method && Method->isVirtual()) ? 1 : 0;
6775}
6776} // end: extern "C"
6777
6778//===----------------------------------------------------------------------===//
6779// Attribute introspection.
6780//===----------------------------------------------------------------------===//
6781
6782extern "C" {
6783CXType clang_getIBOutletCollectionType(CXCursor C) {
6784 if (C.kind != CXCursor_IBOutletCollectionAttr)
6785 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6786
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006787 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006788 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6789
6790 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6791}
6792} // end: extern "C"
6793
6794//===----------------------------------------------------------------------===//
6795// Inspecting memory usage.
6796//===----------------------------------------------------------------------===//
6797
6798typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6799
6800static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6801 enum CXTUResourceUsageKind k,
6802 unsigned long amount) {
6803 CXTUResourceUsageEntry entry = { k, amount };
6804 entries.push_back(entry);
6805}
6806
6807extern "C" {
6808
6809const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6810 const char *str = "";
6811 switch (kind) {
6812 case CXTUResourceUsage_AST:
6813 str = "ASTContext: expressions, declarations, and types";
6814 break;
6815 case CXTUResourceUsage_Identifiers:
6816 str = "ASTContext: identifiers";
6817 break;
6818 case CXTUResourceUsage_Selectors:
6819 str = "ASTContext: selectors";
6820 break;
6821 case CXTUResourceUsage_GlobalCompletionResults:
6822 str = "Code completion: cached global results";
6823 break;
6824 case CXTUResourceUsage_SourceManagerContentCache:
6825 str = "SourceManager: content cache allocator";
6826 break;
6827 case CXTUResourceUsage_AST_SideTables:
6828 str = "ASTContext: side tables";
6829 break;
6830 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6831 str = "SourceManager: malloc'ed memory buffers";
6832 break;
6833 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6834 str = "SourceManager: mmap'ed memory buffers";
6835 break;
6836 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6837 str = "ExternalASTSource: malloc'ed memory buffers";
6838 break;
6839 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6840 str = "ExternalASTSource: mmap'ed memory buffers";
6841 break;
6842 case CXTUResourceUsage_Preprocessor:
6843 str = "Preprocessor: malloc'ed memory";
6844 break;
6845 case CXTUResourceUsage_PreprocessingRecord:
6846 str = "Preprocessor: PreprocessingRecord";
6847 break;
6848 case CXTUResourceUsage_SourceManager_DataStructures:
6849 str = "SourceManager: data structures and tables";
6850 break;
6851 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6852 str = "Preprocessor: header search tables";
6853 break;
6854 }
6855 return str;
6856}
6857
6858CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006859 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006860 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006861 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006862 return usage;
6863 }
6864
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006865 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006866 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006867 ASTContext &astContext = astUnit->getASTContext();
6868
6869 // How much memory is used by AST nodes and types?
6870 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6871 (unsigned long) astContext.getASTAllocatedMemory());
6872
6873 // How much memory is used by identifiers?
6874 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6875 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6876
6877 // How much memory is used for selectors?
6878 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6879 (unsigned long) astContext.Selectors.getTotalMemory());
6880
6881 // How much memory is used by ASTContext's side tables?
6882 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6883 (unsigned long) astContext.getSideTableAllocatedMemory());
6884
6885 // How much memory is used for caching global code completion results?
6886 unsigned long completionBytes = 0;
6887 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006888 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006889 completionBytes = completionAllocator->getTotalMemory();
6890 }
6891 createCXTUResourceUsageEntry(*entries,
6892 CXTUResourceUsage_GlobalCompletionResults,
6893 completionBytes);
6894
6895 // How much memory is being used by SourceManager's content cache?
6896 createCXTUResourceUsageEntry(*entries,
6897 CXTUResourceUsage_SourceManagerContentCache,
6898 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6899
6900 // How much memory is being used by the MemoryBuffer's in SourceManager?
6901 const SourceManager::MemoryBufferSizes &srcBufs =
6902 astUnit->getSourceManager().getMemoryBufferSizes();
6903
6904 createCXTUResourceUsageEntry(*entries,
6905 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6906 (unsigned long) srcBufs.malloc_bytes);
6907 createCXTUResourceUsageEntry(*entries,
6908 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6909 (unsigned long) srcBufs.mmap_bytes);
6910 createCXTUResourceUsageEntry(*entries,
6911 CXTUResourceUsage_SourceManager_DataStructures,
6912 (unsigned long) astContext.getSourceManager()
6913 .getDataStructureSizes());
6914
6915 // How much memory is being used by the ExternalASTSource?
6916 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6917 const ExternalASTSource::MemoryBufferSizes &sizes =
6918 esrc->getMemoryBufferSizes();
6919
6920 createCXTUResourceUsageEntry(*entries,
6921 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6922 (unsigned long) sizes.malloc_bytes);
6923 createCXTUResourceUsageEntry(*entries,
6924 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6925 (unsigned long) sizes.mmap_bytes);
6926 }
6927
6928 // How much memory is being used by the Preprocessor?
6929 Preprocessor &pp = astUnit->getPreprocessor();
6930 createCXTUResourceUsageEntry(*entries,
6931 CXTUResourceUsage_Preprocessor,
6932 pp.getTotalMemory());
6933
6934 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6935 createCXTUResourceUsageEntry(*entries,
6936 CXTUResourceUsage_PreprocessingRecord,
6937 pRec->getTotalMemory());
6938 }
6939
6940 createCXTUResourceUsageEntry(*entries,
6941 CXTUResourceUsage_Preprocessor_HeaderSearch,
6942 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006943
Guy Benyei11169dd2012-12-18 14:30:41 +00006944 CXTUResourceUsage usage = { (void*) entries.get(),
6945 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006946 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006947 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006948 return usage;
6949}
6950
6951void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6952 if (usage.data)
6953 delete (MemUsageEntries*) usage.data;
6954}
6955
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006956CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6957 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006958 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006959 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006960
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006961 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006962 LOG_BAD_TU(TU);
6963 return skipped;
6964 }
6965
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006966 if (!file)
6967 return skipped;
6968
6969 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6970 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6971 if (!ppRec)
6972 return skipped;
6973
6974 ASTContext &Ctx = astUnit->getASTContext();
6975 SourceManager &sm = Ctx.getSourceManager();
6976 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6977 FileID wantedFileID = sm.translateFile(fileEntry);
6978
6979 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6980 std::vector<SourceRange> wantedRanges;
6981 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6982 i != ei; ++i) {
6983 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6984 wantedRanges.push_back(*i);
6985 }
6986
6987 skipped->count = wantedRanges.size();
6988 skipped->ranges = new CXSourceRange[skipped->count];
6989 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6990 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6991
6992 return skipped;
6993}
6994
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006995void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6996 if (ranges) {
6997 delete[] ranges->ranges;
6998 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006999 }
7000}
7001
Guy Benyei11169dd2012-12-18 14:30:41 +00007002} // end extern "C"
7003
7004void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7005 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7006 for (unsigned I = 0; I != Usage.numEntries; ++I)
7007 fprintf(stderr, " %s: %lu\n",
7008 clang_getTUResourceUsageName(Usage.entries[I].kind),
7009 Usage.entries[I].amount);
7010
7011 clang_disposeCXTUResourceUsage(Usage);
7012}
7013
7014//===----------------------------------------------------------------------===//
7015// Misc. utility functions.
7016//===----------------------------------------------------------------------===//
7017
7018/// Default to using an 8 MB stack size on "safety" threads.
7019static unsigned SafetyStackThreadSize = 8 << 20;
7020
7021namespace clang {
7022
7023bool RunSafely(llvm::CrashRecoveryContext &CRC,
7024 void (*Fn)(void*), void *UserData,
7025 unsigned Size) {
7026 if (!Size)
7027 Size = GetSafetyThreadStackSize();
7028 if (Size)
7029 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7030 return CRC.RunSafely(Fn, UserData);
7031}
7032
7033unsigned GetSafetyThreadStackSize() {
7034 return SafetyStackThreadSize;
7035}
7036
7037void SetSafetyThreadStackSize(unsigned Value) {
7038 SafetyStackThreadSize = Value;
7039}
7040
7041}
7042
7043void clang::setThreadBackgroundPriority() {
7044 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7045 return;
7046
Alp Toker1a86ad22014-07-06 06:24:00 +00007047#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007048 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7049#endif
7050}
7051
7052void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7053 if (!Unit)
7054 return;
7055
7056 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7057 DEnd = Unit->stored_diag_end();
7058 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007059 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007060 CXString Msg = clang_formatDiagnostic(&Diag,
7061 clang_defaultDiagnosticDisplayOptions());
7062 fprintf(stderr, "%s\n", clang_getCString(Msg));
7063 clang_disposeString(Msg);
7064 }
7065#ifdef LLVM_ON_WIN32
7066 // On Windows, force a flush, since there may be multiple copies of
7067 // stderr and stdout in the file system, all with different buffers
7068 // but writing to the same device.
7069 fflush(stderr);
7070#endif
7071}
7072
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007073MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7074 SourceLocation MacroDefLoc,
7075 CXTranslationUnit TU){
7076 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007077 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007078 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007079 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007080
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007081 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007082 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007083 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007084 if (MD) {
7085 for (MacroDirective::DefInfo
7086 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7087 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7088 return Def.getMacroInfo();
7089 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007090 }
7091
Craig Topper69186e72014-06-08 08:38:04 +00007092 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007093}
7094
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007095const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7096 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007097 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007098 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007099 const IdentifierInfo *II = MacroDef->getName();
7100 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007101 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007102
7103 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7104}
7105
7106MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7107 const Token &Tok,
7108 CXTranslationUnit TU) {
7109 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007110 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007111 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007112 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007113
7114 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007115 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007116 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7117 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007118 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007119
7120 // Check that the token is inside the definition and not its argument list.
7121 SourceManager &SM = Unit->getSourceManager();
7122 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007123 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007124 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007125 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007126
7127 Preprocessor &PP = Unit->getPreprocessor();
7128 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7129 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007130 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007131
Alp Toker2d57cea2014-05-17 04:53:25 +00007132 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007133 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007134 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007135
7136 // Check that the identifier is not one of the macro arguments.
7137 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007138 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007139
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007140 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7141 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007142 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007143
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007144 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007145}
7146
7147MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7148 SourceLocation Loc,
7149 CXTranslationUnit TU) {
7150 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007151 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007152
7153 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007154 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007155 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007156 Preprocessor &PP = Unit->getPreprocessor();
7157 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007158 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007159 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7160 Token Tok;
7161 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007162 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007163
7164 return checkForMacroInMacroDefinition(MI, Tok, TU);
7165}
7166
Guy Benyei11169dd2012-12-18 14:30:41 +00007167extern "C" {
7168
7169CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007170 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007171}
7172
7173} // end: extern "C"
7174
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007175Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7176 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007177 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007178 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007179 if (Unit->isMainFileAST())
7180 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007181 return *this;
7182 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007183 } else {
7184 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007185 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007186 return *this;
7187}
7188
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007189Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7190 *this << FE->getName();
7191 return *this;
7192}
7193
7194Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7195 CXString cursorName = clang_getCursorDisplayName(cursor);
7196 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7197 clang_disposeString(cursorName);
7198 return *this;
7199}
7200
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007201Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7202 CXFile File;
7203 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007204 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007205 CXString FileName = clang_getFileName(File);
7206 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7207 clang_disposeString(FileName);
7208 return *this;
7209}
7210
7211Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7212 CXSourceLocation BLoc = clang_getRangeStart(range);
7213 CXSourceLocation ELoc = clang_getRangeEnd(range);
7214
7215 CXFile BFile;
7216 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007217 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007218
7219 CXFile EFile;
7220 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007221 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007222
7223 CXString BFileName = clang_getFileName(BFile);
7224 if (BFile == EFile) {
7225 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7226 BLine, BColumn, ELine, EColumn);
7227 } else {
7228 CXString EFileName = clang_getFileName(EFile);
7229 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7230 BLine, BColumn)
7231 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7232 ELine, EColumn);
7233 clang_disposeString(EFileName);
7234 }
7235 clang_disposeString(BFileName);
7236 return *this;
7237}
7238
7239Logger &cxindex::Logger::operator<<(CXString Str) {
7240 *this << clang_getCString(Str);
7241 return *this;
7242}
7243
7244Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7245 LogOS << Fmt;
7246 return *this;
7247}
7248
Chandler Carruth37ad2582014-06-27 15:14:39 +00007249static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7250
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007251cxindex::Logger::~Logger() {
7252 LogOS.flush();
7253
Chandler Carruth37ad2582014-06-27 15:14:39 +00007254 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007255
7256 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7257
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007258 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007259 OS << "[libclang:" << Name << ':';
7260
Alp Toker1a86ad22014-07-06 06:24:00 +00007261#ifdef USE_DARWIN_THREADS
7262 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007263 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7264 OS << tid << ':';
7265#endif
7266
7267 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7268 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7269 OS << Msg.str() << '\n';
7270
7271 if (Trace) {
7272 llvm::sys::PrintStackTrace(stderr);
7273 OS << "--------------------------------------------------\n";
7274 }
7275}