blob: e96bb1cb895d902db33963d12981a341007eb782 [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);
1837 void VisitDeclRefExpr(const DeclRefExpr *D);
1838 void VisitDeclStmt(const DeclStmt *S);
1839 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1840 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1841 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1842 void VisitForStmt(const ForStmt *FS);
1843 void VisitGotoStmt(const GotoStmt *GS);
1844 void VisitIfStmt(const IfStmt *If);
1845 void VisitInitListExpr(const InitListExpr *IE);
1846 void VisitMemberExpr(const MemberExpr *M);
1847 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1848 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1849 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1850 void VisitOverloadExpr(const OverloadExpr *E);
1851 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1852 void VisitStmt(const Stmt *S);
1853 void VisitSwitchStmt(const SwitchStmt *S);
1854 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1856 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1857 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1858 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1859 void VisitVAArgExpr(const VAArgExpr *E);
1860 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1861 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1862 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1863 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001865 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001867 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001868 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001869 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001870 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001871 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001872 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001873 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001874 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001875 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001876 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001877 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001878 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001879 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001880 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001881 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001882 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001883 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001884 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001885 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001886 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887
Guy Benyei11169dd2012-12-18 14:30:41 +00001888private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1891 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1893 void AddStmt(const Stmt *S);
1894 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001897 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001898};
1899} // end anonyous namespace
1900
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 // 'S' should always be non-null, since it comes from the
1903 // statement we are visiting.
1904 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1905}
1906
1907void
1908EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1909 if (Qualifier)
1910 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1911}
1912
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 if (S)
1915 WL.push_back(StmtVisit(S, Parent));
1916}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001918 if (D)
1919 WL.push_back(DeclVisit(D, Parent, isFirst));
1920}
1921void EnqueueVisitor::
1922 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1923 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001924 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001925}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001926void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001927 if (D)
1928 WL.push_back(MemberRefVisit(D, L, Parent));
1929}
1930void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1931 if (TI)
1932 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1933 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001934void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001935 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001936 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 AddStmt(*Child);
1938 }
1939 if (size == WL.size())
1940 return;
1941 // Now reverse the entries we just added. This will match the DFS
1942 // ordering performed by the worklist.
1943 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1944 std::reverse(I, E);
1945}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946namespace {
1947class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1948 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001949 /// \brief Process clauses with list of variables.
1950 template <typename T>
1951 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001952public:
1953 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1954#define OPENMP_CLAUSE(Name, Class) \
1955 void Visit##Class(const Class *C);
1956#include "clang/Basic/OpenMPKinds.def"
1957};
1958
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001959void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1960 Visitor->AddStmt(C->getCondition());
1961}
1962
Alexey Bataev3778b602014-07-17 07:32:53 +00001963void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1964 Visitor->AddStmt(C->getCondition());
1965}
1966
Alexey Bataev568a8332014-03-06 06:15:19 +00001967void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1968 Visitor->AddStmt(C->getNumThreads());
1969}
1970
Alexey Bataev62c87d22014-03-21 04:51:18 +00001971void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1972 Visitor->AddStmt(C->getSafelen());
1973}
1974
Alexander Musman8bd31e62014-05-27 15:12:19 +00001975void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1976 Visitor->AddStmt(C->getNumForLoops());
1977}
1978
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001979void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001980
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001981void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1982
Alexey Bataev56dafe82014-06-20 07:16:17 +00001983void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1984 Visitor->AddStmt(C->getChunkSize());
1985}
1986
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001987void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1988
Alexey Bataev236070f2014-06-20 11:19:47 +00001989void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1990
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001991void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1992
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001993void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1994
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001995void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1996
Alexey Bataevdea47612014-07-23 07:46:59 +00001997void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1998
Alexey Bataev67a4f222014-07-23 10:25:33 +00001999void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2000
Alexey Bataev459dec02014-07-24 06:46:57 +00002001void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2002
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002003void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2004
Alexey Bataev756c1962013-09-24 03:17:45 +00002005template<typename T>
2006void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002007 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002008 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002009 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002010}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002011
2012void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002013 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002014 for (const auto *E : C->private_copies()) {
2015 Visitor->AddStmt(E);
2016 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002017}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002018void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2019 const OMPFirstprivateClause *C) {
2020 VisitOMPClauseList(C);
2021}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002022void OMPClauseEnqueue::VisitOMPLastprivateClause(
2023 const OMPLastprivateClause *C) {
2024 VisitOMPClauseList(C);
2025}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002026void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002027 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002028}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002029void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2030 VisitOMPClauseList(C);
2031}
Alexander Musman8dba6642014-04-22 13:09:42 +00002032void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2033 VisitOMPClauseList(C);
2034 Visitor->AddStmt(C->getStep());
2035}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002036void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2037 VisitOMPClauseList(C);
2038 Visitor->AddStmt(C->getAlignment());
2039}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002040void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2041 VisitOMPClauseList(C);
2042}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002043void
2044OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2045 VisitOMPClauseList(C);
2046}
Alexey Bataev6125da92014-07-21 11:26:11 +00002047void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2048 VisitOMPClauseList(C);
2049}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002050}
Alexey Bataev756c1962013-09-24 03:17:45 +00002051
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002052void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2053 unsigned size = WL.size();
2054 OMPClauseEnqueue Visitor(this);
2055 Visitor.Visit(S);
2056 if (size == WL.size())
2057 return;
2058 // Now reverse the entries we just added. This will match the DFS
2059 // ordering performed by the worklist.
2060 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2061 std::reverse(I, E);
2062}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002063void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002064 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2065}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 AddDecl(B->getBlockDecl());
2068}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 EnqueueChildren(E);
2071 AddTypeLoc(E->getTypeSourceInfo());
2072}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2074 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002075 E = S->body_rend(); I != E; ++I) {
2076 AddStmt(*I);
2077 }
2078}
2079void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 AddStmt(S->getSubStmt());
2082 AddDeclarationNameInfo(S);
2083 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2084 AddNestedNameSpecifierLoc(QualifierLoc);
2085}
2086
2087void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2090 AddDeclarationNameInfo(E);
2091 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2092 AddNestedNameSpecifierLoc(QualifierLoc);
2093 if (!E->isImplicitAccess())
2094 AddStmt(E->getBase());
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 // Enqueue the initializer , if any.
2098 AddStmt(E->getInitializer());
2099 // Enqueue the array size, if any.
2100 AddStmt(E->getArraySize());
2101 // Enqueue the allocated type.
2102 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2103 // Enqueue the placement arguments.
2104 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2105 AddStmt(E->getPlacementArg(I-1));
2106}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002108 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2109 AddStmt(CE->getArg(I-1));
2110 AddStmt(CE->getCallee());
2111 AddStmt(CE->getArg(0));
2112}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002113void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2114 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002115 // Visit the name of the type being destroyed.
2116 AddTypeLoc(E->getDestroyedTypeInfo());
2117 // Visit the scope type that looks disturbingly like the nested-name-specifier
2118 // but isn't.
2119 AddTypeLoc(E->getScopeTypeInfo());
2120 // Visit the nested-name-specifier.
2121 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2122 AddNestedNameSpecifierLoc(QualifierLoc);
2123 // Visit base expression.
2124 AddStmt(E->getBase());
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2127 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 AddTypeLoc(E->getTypeSourceInfo());
2129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2131 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 EnqueueChildren(E);
2133 AddTypeLoc(E->getTypeSourceInfo());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 EnqueueChildren(E);
2137 if (E->isTypeOperand())
2138 AddTypeLoc(E->getTypeOperandSourceInfo());
2139}
2140
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2142 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 EnqueueChildren(E);
2144 AddTypeLoc(E->getTypeSourceInfo());
2145}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 EnqueueChildren(E);
2148 if (E->isTypeOperand())
2149 AddTypeLoc(E->getTypeOperandSourceInfo());
2150}
2151
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 EnqueueChildren(S);
2154 AddDecl(S->getExceptionDecl());
2155}
2156
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002157void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002158 if (DR->hasExplicitTemplateArgs()) {
2159 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2160 }
2161 WL.push_back(DeclRefExprParts(DR, Parent));
2162}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2164 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2166 AddDeclarationNameInfo(E);
2167 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002170 unsigned size = WL.size();
2171 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002172 for (const auto *D : S->decls()) {
2173 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002174 isFirst = false;
2175 }
2176 if (size == WL.size())
2177 return;
2178 // Now reverse the entries we just added. This will match the DFS
2179 // ordering performed by the worklist.
2180 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2181 std::reverse(I, E);
2182}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002184 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 D = E->designators_rbegin(), DEnd = E->designators_rend();
2187 D != DEnd; ++D) {
2188 if (D->isFieldDesignator()) {
2189 if (FieldDecl *Field = D->getField())
2190 AddMemberRef(Field, D->getFieldLoc());
2191 continue;
2192 }
2193 if (D->isArrayDesignator()) {
2194 AddStmt(E->getArrayIndex(*D));
2195 continue;
2196 }
2197 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2198 AddStmt(E->getArrayRangeEnd(*D));
2199 AddStmt(E->getArrayRangeStart(*D));
2200 }
2201}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 EnqueueChildren(E);
2204 AddTypeLoc(E->getTypeInfoAsWritten());
2205}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 AddStmt(FS->getBody());
2208 AddStmt(FS->getInc());
2209 AddStmt(FS->getCond());
2210 AddDecl(FS->getConditionVariable());
2211 AddStmt(FS->getInit());
2212}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2215}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 AddStmt(If->getElse());
2218 AddStmt(If->getThen());
2219 AddStmt(If->getCond());
2220 AddDecl(If->getConditionVariable());
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 // We care about the syntactic form of the initializer list, only.
2224 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2225 IE = Syntactic;
2226 EnqueueChildren(IE);
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 WL.push_back(MemberExprParts(M, Parent));
2230
2231 // If the base of the member access expression is an implicit 'this', don't
2232 // visit it.
2233 // FIXME: If we ever want to show these implicit accesses, this will be
2234 // unfortunate. However, clang_getCursor() relies on this behavior.
2235 if (!M->isImplicitAccess())
2236 AddStmt(M->getBase());
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 AddTypeLoc(E->getEncodedTypeSourceInfo());
2240}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002242 EnqueueChildren(M);
2243 AddTypeLoc(M->getClassReceiverTypeInfo());
2244}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002246 // Visit the components of the offsetof expression.
2247 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2248 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2249 const OffsetOfNode &Node = E->getComponent(I-1);
2250 switch (Node.getKind()) {
2251 case OffsetOfNode::Array:
2252 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2253 break;
2254 case OffsetOfNode::Field:
2255 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2256 break;
2257 case OffsetOfNode::Identifier:
2258 case OffsetOfNode::Base:
2259 continue;
2260 }
2261 }
2262 // Visit the type into which we're computing the offset.
2263 AddTypeLoc(E->getTypeSourceInfo());
2264}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2267 WL.push_back(OverloadExprParts(E, Parent));
2268}
2269void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 EnqueueChildren(E);
2272 if (E->isArgumentType())
2273 AddTypeLoc(E->getArgumentTypeInfo());
2274}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 EnqueueChildren(S);
2277}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002278void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002279 AddStmt(S->getBody());
2280 AddStmt(S->getCond());
2281 AddDecl(S->getConditionVariable());
2282}
2283
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 AddStmt(W->getBody());
2286 AddStmt(W->getCond());
2287 AddDecl(W->getConditionVariable());
2288}
2289
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 for (unsigned I = E->getNumArgs(); I > 0; --I)
2292 AddTypeLoc(E->getArg(I-1));
2293}
2294
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002295void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002296 AddTypeLoc(E->getQueriedTypeSourceInfo());
2297}
2298
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002299void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002300 EnqueueChildren(E);
2301}
2302
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002303void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002304 VisitOverloadExpr(U);
2305 if (!U->isImplicitAccess())
2306 AddStmt(U->getBase());
2307}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 AddStmt(E->getSubExpr());
2310 AddTypeLoc(E->getWrittenTypeInfo());
2311}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 WL.push_back(SizeOfPackExprParts(E, Parent));
2314}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002315void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 // If the opaque value has a source expression, just transparently
2317 // visit that. This is useful for (e.g.) pseudo-object expressions.
2318 if (Expr *SourceExpr = E->getSourceExpr())
2319 return Visit(SourceExpr);
2320}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002321void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002322 AddStmt(E->getBody());
2323 WL.push_back(LambdaExprParts(E, Parent));
2324}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002325void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002326 // Treat the expression like its syntactic form.
2327 Visit(E->getSyntacticForm());
2328}
2329
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002330void EnqueueVisitor::VisitOMPExecutableDirective(
2331 const OMPExecutableDirective *D) {
2332 EnqueueChildren(D);
2333 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2334 E = D->clauses().end();
2335 I != E; ++I)
2336 EnqueueChildren(*I);
2337}
2338
Alexander Musman3aaab662014-08-19 11:27:13 +00002339void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2340 VisitOMPExecutableDirective(D);
2341}
2342
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002343void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2344 VisitOMPExecutableDirective(D);
2345}
2346
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002347void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002348 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002349}
2350
Alexey Bataevf29276e2014-06-18 04:14:57 +00002351void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002352 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002353}
2354
Alexander Musmanf82886e2014-09-18 05:12:34 +00002355void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2356 VisitOMPLoopDirective(D);
2357}
2358
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002359void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2360 VisitOMPExecutableDirective(D);
2361}
2362
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002363void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2364 VisitOMPExecutableDirective(D);
2365}
2366
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002367void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2368 VisitOMPExecutableDirective(D);
2369}
2370
Alexander Musman80c22892014-07-17 08:54:58 +00002371void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2372 VisitOMPExecutableDirective(D);
2373}
2374
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002375void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2376 VisitOMPExecutableDirective(D);
2377 AddDeclarationNameInfo(D);
2378}
2379
Alexey Bataev4acb8592014-07-07 13:01:15 +00002380void
2381EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002382 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002383}
2384
Alexander Musmane4e893b2014-09-23 09:33:00 +00002385void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2386 const OMPParallelForSimdDirective *D) {
2387 VisitOMPLoopDirective(D);
2388}
2389
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002390void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2391 const OMPParallelSectionsDirective *D) {
2392 VisitOMPExecutableDirective(D);
2393}
2394
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002395void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2396 VisitOMPExecutableDirective(D);
2397}
2398
Alexey Bataev68446b72014-07-18 07:47:19 +00002399void
2400EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2401 VisitOMPExecutableDirective(D);
2402}
2403
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002404void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2405 VisitOMPExecutableDirective(D);
2406}
2407
Alexey Bataev2df347a2014-07-18 10:17:07 +00002408void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2409 VisitOMPExecutableDirective(D);
2410}
2411
Alexey Bataev6125da92014-07-21 11:26:11 +00002412void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2413 VisitOMPExecutableDirective(D);
2414}
2415
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002416void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2417 VisitOMPExecutableDirective(D);
2418}
2419
Alexey Bataev0162e452014-07-22 10:10:35 +00002420void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2421 VisitOMPExecutableDirective(D);
2422}
2423
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002424void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2425 VisitOMPExecutableDirective(D);
2426}
2427
Alexey Bataev13314bf2014-10-09 04:18:56 +00002428void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2429 VisitOMPExecutableDirective(D);
2430}
2431
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002432void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2434}
2435
2436bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2437 if (RegionOfInterest.isValid()) {
2438 SourceRange Range = getRawCursorExtent(C);
2439 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2440 return false;
2441 }
2442 return true;
2443}
2444
2445bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2446 while (!WL.empty()) {
2447 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002448 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002449
2450 // Set the Parent field, then back to its old value once we're done.
2451 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2452
2453 switch (LI.getKind()) {
2454 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002455 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 if (!D)
2457 continue;
2458
2459 // For now, perform default visitation for Decls.
2460 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2461 cast<DeclVisit>(&LI)->isFirst())))
2462 return true;
2463
2464 continue;
2465 }
2466 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2467 const ASTTemplateArgumentListInfo *ArgList =
2468 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2469 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2470 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2471 Arg != ArgEnd; ++Arg) {
2472 if (VisitTemplateArgumentLoc(*Arg))
2473 return true;
2474 }
2475 continue;
2476 }
2477 case VisitorJob::TypeLocVisitKind: {
2478 // Perform default visitation for TypeLocs.
2479 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2480 return true;
2481 continue;
2482 }
2483 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002484 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002485 if (LabelStmt *stmt = LS->getStmt()) {
2486 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2487 TU))) {
2488 return true;
2489 }
2490 }
2491 continue;
2492 }
2493
2494 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2495 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2496 if (VisitNestedNameSpecifierLoc(V->get()))
2497 return true;
2498 continue;
2499 }
2500
2501 case VisitorJob::DeclarationNameInfoVisitKind: {
2502 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2503 ->get()))
2504 return true;
2505 continue;
2506 }
2507 case VisitorJob::MemberRefVisitKind: {
2508 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2509 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2510 return true;
2511 continue;
2512 }
2513 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002514 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002515 if (!S)
2516 continue;
2517
2518 // Update the current cursor.
2519 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2520 if (!IsInRegionOfInterest(Cursor))
2521 continue;
2522 switch (Visitor(Cursor, Parent, ClientData)) {
2523 case CXChildVisit_Break: return true;
2524 case CXChildVisit_Continue: break;
2525 case CXChildVisit_Recurse:
2526 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002527 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002528 EnqueueWorkList(WL, S);
2529 break;
2530 }
2531 continue;
2532 }
2533 case VisitorJob::MemberExprPartsKind: {
2534 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002535 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002536
2537 // Visit the nested-name-specifier
2538 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2539 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2540 return true;
2541
2542 // Visit the declaration name.
2543 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2544 return true;
2545
2546 // Visit the explicitly-specified template arguments, if any.
2547 if (M->hasExplicitTemplateArgs()) {
2548 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2549 *ArgEnd = Arg + M->getNumTemplateArgs();
2550 Arg != ArgEnd; ++Arg) {
2551 if (VisitTemplateArgumentLoc(*Arg))
2552 return true;
2553 }
2554 }
2555 continue;
2556 }
2557 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002558 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002559 // Visit nested-name-specifier, if present.
2560 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2561 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2562 return true;
2563 // Visit declaration name.
2564 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2565 return true;
2566 continue;
2567 }
2568 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002569 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002570 // Visit the nested-name-specifier.
2571 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2572 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2573 return true;
2574 // Visit the declaration name.
2575 if (VisitDeclarationNameInfo(O->getNameInfo()))
2576 return true;
2577 // Visit the overloaded declaration reference.
2578 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2579 return true;
2580 continue;
2581 }
2582 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002583 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002584 NamedDecl *Pack = E->getPack();
2585 if (isa<TemplateTypeParmDecl>(Pack)) {
2586 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2587 E->getPackLoc(), TU)))
2588 return true;
2589
2590 continue;
2591 }
2592
2593 if (isa<TemplateTemplateParmDecl>(Pack)) {
2594 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2595 E->getPackLoc(), TU)))
2596 return true;
2597
2598 continue;
2599 }
2600
2601 // Non-type template parameter packs and function parameter packs are
2602 // treated like DeclRefExpr cursors.
2603 continue;
2604 }
2605
2606 case VisitorJob::LambdaExprPartsKind: {
2607 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002608 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002609 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2610 CEnd = E->explicit_capture_end();
2611 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002612 // FIXME: Lambda init-captures.
2613 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002614 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002615
Guy Benyei11169dd2012-12-18 14:30:41 +00002616 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2617 C->getLocation(),
2618 TU)))
2619 return true;
2620 }
2621
2622 // Visit parameters and return type, if present.
2623 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2624 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2625 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2626 // Visit the whole type.
2627 if (Visit(TL))
2628 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002629 } else if (FunctionProtoTypeLoc Proto =
2630 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002631 if (E->hasExplicitParameters()) {
2632 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002633 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2634 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002635 return true;
2636 } else {
2637 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002638 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002639 return true;
2640 }
2641 }
2642 }
2643 break;
2644 }
2645
2646 case VisitorJob::PostChildrenVisitKind:
2647 if (PostChildrenVisitor(Parent, ClientData))
2648 return true;
2649 break;
2650 }
2651 }
2652 return false;
2653}
2654
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002655bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002656 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002657 if (!WorkListFreeList.empty()) {
2658 WL = WorkListFreeList.back();
2659 WL->clear();
2660 WorkListFreeList.pop_back();
2661 }
2662 else {
2663 WL = new VisitorWorkList();
2664 WorkListCache.push_back(WL);
2665 }
2666 EnqueueWorkList(*WL, S);
2667 bool result = RunVisitorWorkList(*WL);
2668 WorkListFreeList.push_back(WL);
2669 return result;
2670}
2671
2672namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002673typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002674RefNamePieces
2675buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2676 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2677 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002678 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2679 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2680 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2681
2682 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2683
2684 RefNamePieces Pieces;
2685
2686 if (WantQualifier && QLoc.isValid())
2687 Pieces.push_back(QLoc);
2688
2689 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2690 Pieces.push_back(NI.getLoc());
2691
2692 if (WantTemplateArgs && TemplateArgs)
2693 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2694 TemplateArgs->RAngleLoc));
2695
2696 if (Kind == DeclarationName::CXXOperatorName) {
2697 Pieces.push_back(SourceLocation::getFromRawEncoding(
2698 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2699 Pieces.push_back(SourceLocation::getFromRawEncoding(
2700 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2701 }
2702
2703 if (WantSinglePiece) {
2704 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2705 Pieces.clear();
2706 Pieces.push_back(R);
2707 }
2708
2709 return Pieces;
2710}
2711}
2712
2713//===----------------------------------------------------------------------===//
2714// Misc. API hooks.
2715//===----------------------------------------------------------------------===//
2716
Chad Rosier05c71aa2013-03-27 18:28:23 +00002717static void fatal_error_handler(void *user_data, const std::string& reason,
2718 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002719 // Write the result out to stderr avoiding errs() because raw_ostreams can
2720 // call report_fatal_error.
2721 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2722 ::abort();
2723}
2724
Chandler Carruth66660742014-06-27 16:37:27 +00002725namespace {
2726struct RegisterFatalErrorHandler {
2727 RegisterFatalErrorHandler() {
2728 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2729 }
2730};
2731}
2732
2733static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2734
Guy Benyei11169dd2012-12-18 14:30:41 +00002735extern "C" {
2736CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2737 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002738 // We use crash recovery to make some of our APIs more reliable, implicitly
2739 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002740 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2741 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002742
Chandler Carruth66660742014-06-27 16:37:27 +00002743 // Look through the managed static to trigger construction of the managed
2744 // static which registers our fatal error handler. This ensures it is only
2745 // registered once.
2746 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002747
2748 CIndexer *CIdxr = new CIndexer();
2749 if (excludeDeclarationsFromPCH)
2750 CIdxr->setOnlyLocalDecls();
2751 if (displayDiagnostics)
2752 CIdxr->setDisplayDiagnostics();
2753
2754 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2755 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2756 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2757 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2758 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2759 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2760
2761 return CIdxr;
2762}
2763
2764void clang_disposeIndex(CXIndex CIdx) {
2765 if (CIdx)
2766 delete static_cast<CIndexer *>(CIdx);
2767}
2768
2769void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2770 if (CIdx)
2771 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2772}
2773
2774unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2775 if (CIdx)
2776 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2777 return 0;
2778}
2779
2780void clang_toggleCrashRecovery(unsigned isEnabled) {
2781 if (isEnabled)
2782 llvm::CrashRecoveryContext::Enable();
2783 else
2784 llvm::CrashRecoveryContext::Disable();
2785}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002786
Guy Benyei11169dd2012-12-18 14:30:41 +00002787CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2788 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002789 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002790 enum CXErrorCode Result =
2791 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002792 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002793 assert((TU && Result == CXError_Success) ||
2794 (!TU && Result != CXError_Success));
2795 return TU;
2796}
2797
2798enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2799 const char *ast_filename,
2800 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002801 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002802 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002803
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002804 if (!CIdx || !ast_filename || !out_TU)
2805 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002806
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002807 LOG_FUNC_SECTION {
2808 *Log << ast_filename;
2809 }
2810
Guy Benyei11169dd2012-12-18 14:30:41 +00002811 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2812 FileSystemOptions FileSystemOpts;
2813
Justin Bognerd512c1e2014-10-15 00:33:06 +00002814 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2815 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002816 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2817 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2818 /*CaptureDiagnostics=*/true,
2819 /*AllowPCHWithCompilerErrors=*/true,
2820 /*UserFilesAreVolatile=*/true);
2821 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002822 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002823}
2824
2825unsigned clang_defaultEditingTranslationUnitOptions() {
2826 return CXTranslationUnit_PrecompiledPreamble |
2827 CXTranslationUnit_CacheCompletionResults;
2828}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002829
Guy Benyei11169dd2012-12-18 14:30:41 +00002830CXTranslationUnit
2831clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2832 const char *source_filename,
2833 int num_command_line_args,
2834 const char * const *command_line_args,
2835 unsigned num_unsaved_files,
2836 struct CXUnsavedFile *unsaved_files) {
2837 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2838 return clang_parseTranslationUnit(CIdx, source_filename,
2839 command_line_args, num_command_line_args,
2840 unsaved_files, num_unsaved_files,
2841 Options);
2842}
2843
2844struct ParseTranslationUnitInfo {
2845 CXIndex CIdx;
2846 const char *source_filename;
2847 const char *const *command_line_args;
2848 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002849 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002850 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002851 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002852 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002853};
2854static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002855 const ParseTranslationUnitInfo *PTUI =
2856 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002857 CXIndex CIdx = PTUI->CIdx;
2858 const char *source_filename = PTUI->source_filename;
2859 const char * const *command_line_args = PTUI->command_line_args;
2860 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002861 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002862 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002863
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002864 // Set up the initial return values.
2865 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002866 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002867
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002868 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002869 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002870 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002871 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002872 }
2873
Guy Benyei11169dd2012-12-18 14:30:41 +00002874 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2875
2876 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2877 setThreadBackgroundPriority();
2878
2879 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2880 // FIXME: Add a flag for modules.
2881 TranslationUnitKind TUKind
2882 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002883 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002884 = options & CXTranslationUnit_CacheCompletionResults;
2885 bool IncludeBriefCommentsInCodeCompletion
2886 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2887 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2888 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2889
2890 // Configure the diagnostics.
2891 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002892 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002893
2894 // Recover resources if we crash before exiting this function.
2895 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2896 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002897 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002898
Ahmed Charlesb8984322014-03-07 20:03:18 +00002899 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2900 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002901
2902 // Recover resources if we crash before exiting this function.
2903 llvm::CrashRecoveryContextCleanupRegistrar<
2904 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2905
Alp Toker9d85b182014-07-07 01:23:14 +00002906 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002907 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002908 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002909 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002910 }
2911
Ahmed Charlesb8984322014-03-07 20:03:18 +00002912 std::unique_ptr<std::vector<const char *>> Args(
2913 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002914
2915 // Recover resources if we crash before exiting this method.
2916 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2917 ArgsCleanup(Args.get());
2918
2919 // Since the Clang C library is primarily used by batch tools dealing with
2920 // (often very broken) source code, where spell-checking can have a
2921 // significant negative impact on performance (particularly when
2922 // precompiled headers are involved), we disable it by default.
2923 // Only do this if we haven't found a spell-checking-related argument.
2924 bool FoundSpellCheckingArgument = false;
2925 for (int I = 0; I != num_command_line_args; ++I) {
2926 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2927 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2928 FoundSpellCheckingArgument = true;
2929 break;
2930 }
2931 }
2932 if (!FoundSpellCheckingArgument)
2933 Args->push_back("-fno-spell-checking");
2934
2935 Args->insert(Args->end(), command_line_args,
2936 command_line_args + num_command_line_args);
2937
2938 // The 'source_filename' argument is optional. If the caller does not
2939 // specify it then it is assumed that the source file is specified
2940 // in the actual argument list.
2941 // Put the source file after command_line_args otherwise if '-x' flag is
2942 // present it will be unused.
2943 if (source_filename)
2944 Args->push_back(source_filename);
2945
2946 // Do we need the detailed preprocessing record?
2947 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2948 Args->push_back("-Xclang");
2949 Args->push_back("-detailed-preprocessing-record");
2950 }
2951
2952 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002953 std::unique_ptr<ASTUnit> ErrUnit;
2954 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002955 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002956 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2957 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2958 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2959 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2960 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2961 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002962
2963 if (NumErrors != Diags->getClient()->getNumErrors()) {
2964 // Make sure to check that 'Unit' is non-NULL.
2965 if (CXXIdx->getDisplayDiagnostics())
2966 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2967 }
2968
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002969 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2970 PTUI->result = CXError_ASTReadError;
2971 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002972 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002973 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2974 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002975}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002976
2977CXTranslationUnit
2978clang_parseTranslationUnit(CXIndex CIdx,
2979 const char *source_filename,
2980 const char *const *command_line_args,
2981 int num_command_line_args,
2982 struct CXUnsavedFile *unsaved_files,
2983 unsigned num_unsaved_files,
2984 unsigned options) {
2985 CXTranslationUnit TU;
2986 enum CXErrorCode Result = clang_parseTranslationUnit2(
2987 CIdx, source_filename, command_line_args, num_command_line_args,
2988 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002989 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002990 assert((TU && Result == CXError_Success) ||
2991 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002992 return TU;
2993}
2994
2995enum CXErrorCode clang_parseTranslationUnit2(
2996 CXIndex CIdx,
2997 const char *source_filename,
2998 const char *const *command_line_args,
2999 int num_command_line_args,
3000 struct CXUnsavedFile *unsaved_files,
3001 unsigned num_unsaved_files,
3002 unsigned options,
3003 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003004 LOG_FUNC_SECTION {
3005 *Log << source_filename << ": ";
3006 for (int i = 0; i != num_command_line_args; ++i)
3007 *Log << command_line_args[i] << " ";
3008 }
3009
Alp Toker9d85b182014-07-07 01:23:14 +00003010 if (num_unsaved_files && !unsaved_files)
3011 return CXError_InvalidArguments;
3012
Alp Toker5c532982014-07-07 22:42:03 +00003013 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003014 ParseTranslationUnitInfo PTUI = {
3015 CIdx,
3016 source_filename,
3017 command_line_args,
3018 num_command_line_args,
3019 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3020 options,
3021 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003022 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003023 llvm::CrashRecoveryContext CRC;
3024
3025 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3026 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3027 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3028 fprintf(stderr, " 'command_line_args' : [");
3029 for (int i = 0; i != num_command_line_args; ++i) {
3030 if (i)
3031 fprintf(stderr, ", ");
3032 fprintf(stderr, "'%s'", command_line_args[i]);
3033 }
3034 fprintf(stderr, "],\n");
3035 fprintf(stderr, " 'unsaved_files' : [");
3036 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3037 if (i)
3038 fprintf(stderr, ", ");
3039 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3040 unsaved_files[i].Length);
3041 }
3042 fprintf(stderr, "],\n");
3043 fprintf(stderr, " 'options' : %d,\n", options);
3044 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003045
3046 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003047 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003048 if (CXTranslationUnit *TU = PTUI.out_TU)
3049 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003050 }
Alp Toker5c532982014-07-07 22:42:03 +00003051
3052 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003053}
3054
3055unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3056 return CXSaveTranslationUnit_None;
3057}
3058
3059namespace {
3060
3061struct SaveTranslationUnitInfo {
3062 CXTranslationUnit TU;
3063 const char *FileName;
3064 unsigned options;
3065 CXSaveError result;
3066};
3067
3068}
3069
3070static void clang_saveTranslationUnit_Impl(void *UserData) {
3071 SaveTranslationUnitInfo *STUI =
3072 static_cast<SaveTranslationUnitInfo*>(UserData);
3073
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003074 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003075 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3076 setThreadBackgroundPriority();
3077
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003078 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003079 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3080}
3081
3082int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3083 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003084 LOG_FUNC_SECTION {
3085 *Log << TU << ' ' << FileName;
3086 }
3087
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003088 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003089 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003090 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003091 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003092
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003093 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003094 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3095 if (!CXXUnit->hasSema())
3096 return CXSaveError_InvalidTU;
3097
3098 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3099
3100 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3101 getenv("LIBCLANG_NOTHREADS")) {
3102 clang_saveTranslationUnit_Impl(&STUI);
3103
3104 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3105 PrintLibclangResourceUsage(TU);
3106
3107 return STUI.result;
3108 }
3109
3110 // We have an AST that has invalid nodes due to compiler errors.
3111 // Use a crash recovery thread for protection.
3112
3113 llvm::CrashRecoveryContext CRC;
3114
3115 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3116 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3117 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3118 fprintf(stderr, " 'options' : %d,\n", options);
3119 fprintf(stderr, "}\n");
3120
3121 return CXSaveError_Unknown;
3122
3123 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3124 PrintLibclangResourceUsage(TU);
3125 }
3126
3127 return STUI.result;
3128}
3129
3130void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3131 if (CTUnit) {
3132 // If the translation unit has been marked as unsafe to free, just discard
3133 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003134 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3135 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003136 return;
3137
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003138 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003139 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003140 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3141 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003142 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003143 delete CTUnit;
3144 }
3145}
3146
3147unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3148 return CXReparse_None;
3149}
3150
3151struct ReparseTranslationUnitInfo {
3152 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003153 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003154 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003155 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003156};
3157
3158static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003159 const ReparseTranslationUnitInfo *RTUI =
3160 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003162 unsigned options = RTUI->options;
3163 (void) options;
3164
3165 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003166 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003167 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003168 RTUI->result = CXError_InvalidArguments;
3169 return;
3170 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003171
3172 // Reset the associated diagnostics.
3173 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003174 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003175
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003176 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3178 setThreadBackgroundPriority();
3179
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003180 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003182
3183 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3184 new std::vector<ASTUnit::RemappedFile>());
3185
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 // Recover resources if we crash before exiting this function.
3187 llvm::CrashRecoveryContextCleanupRegistrar<
3188 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003189
3190 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003191 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003192 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003193 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003195
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003196 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003197 RTUI->result = CXError_Success;
3198 else if (isASTReadError(CXXUnit))
3199 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003200}
3201
3202int clang_reparseTranslationUnit(CXTranslationUnit TU,
3203 unsigned num_unsaved_files,
3204 struct CXUnsavedFile *unsaved_files,
3205 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003206 LOG_FUNC_SECTION {
3207 *Log << TU;
3208 }
3209
Alp Toker9d85b182014-07-07 01:23:14 +00003210 if (num_unsaved_files && !unsaved_files)
3211 return CXError_InvalidArguments;
3212
Alp Toker5c532982014-07-07 22:42:03 +00003213 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003214 ReparseTranslationUnitInfo RTUI = {
3215 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003216 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003217
3218 if (getenv("LIBCLANG_NOTHREADS")) {
3219 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003220 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 }
3222
3223 llvm::CrashRecoveryContext CRC;
3224
3225 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3226 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003227 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003228 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3230 PrintLibclangResourceUsage(TU);
3231
Alp Toker5c532982014-07-07 22:42:03 +00003232 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003233}
3234
3235
3236CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003237 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003238 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003239 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003240 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003241
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003242 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003243 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003244}
3245
3246CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003247 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003248 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003249 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003250 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003251
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003252 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003253 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3254}
3255
3256} // end: extern "C"
3257
3258//===----------------------------------------------------------------------===//
3259// CXFile Operations.
3260//===----------------------------------------------------------------------===//
3261
3262extern "C" {
3263CXString clang_getFileName(CXFile SFile) {
3264 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003265 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003266
3267 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003268 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003269}
3270
3271time_t clang_getFileTime(CXFile SFile) {
3272 if (!SFile)
3273 return 0;
3274
3275 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3276 return FEnt->getModificationTime();
3277}
3278
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003279CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003280 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003281 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003282 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003283 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003284
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003285 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003286
3287 FileManager &FMgr = CXXUnit->getFileManager();
3288 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3289}
3290
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003291unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3292 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003293 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003294 LOG_BAD_TU(TU);
3295 return 0;
3296 }
3297
3298 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 return 0;
3300
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003301 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 FileEntry *FEnt = static_cast<FileEntry *>(file);
3303 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3304 .isFileMultipleIncludeGuarded(FEnt);
3305}
3306
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003307int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3308 if (!file || !outID)
3309 return 1;
3310
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003311 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003312 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3313 outID->data[0] = ID.getDevice();
3314 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003315 outID->data[2] = FEnt->getModificationTime();
3316 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003317}
3318
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003319int clang_File_isEqual(CXFile file1, CXFile file2) {
3320 if (file1 == file2)
3321 return true;
3322
3323 if (!file1 || !file2)
3324 return false;
3325
3326 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3327 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3328 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3329}
3330
Guy Benyei11169dd2012-12-18 14:30:41 +00003331} // end: extern "C"
3332
3333//===----------------------------------------------------------------------===//
3334// CXCursor Operations.
3335//===----------------------------------------------------------------------===//
3336
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003337static const Decl *getDeclFromExpr(const Stmt *E) {
3338 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 return getDeclFromExpr(CE->getSubExpr());
3340
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003341 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003343 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003345 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003347 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 if (PRE->isExplicitProperty())
3349 return PRE->getExplicitProperty();
3350 // It could be messaging both getter and setter as in:
3351 // ++myobj.myprop;
3352 // in which case prefer to associate the setter since it is less obvious
3353 // from inspecting the source that the setter is going to get called.
3354 if (PRE->isMessagingSetter())
3355 return PRE->getImplicitPropertySetter();
3356 return PRE->getImplicitPropertyGetter();
3357 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003358 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003360 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 if (Expr *Src = OVE->getSourceExpr())
3362 return getDeclFromExpr(Src);
3363
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003364 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003366 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 if (!CE->isElidable())
3368 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003369 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 return OME->getMethodDecl();
3371
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003372 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003374 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3376 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003377 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3379 isa<ParmVarDecl>(SizeOfPack->getPack()))
3380 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003381
3382 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003383}
3384
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003385static SourceLocation getLocationFromExpr(const Expr *E) {
3386 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 return getLocationFromExpr(CE->getSubExpr());
3388
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003389 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003391 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003393 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003395 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003397 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003398 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003399 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 return PropRef->getLocation();
3401
3402 return E->getLocStart();
3403}
3404
3405extern "C" {
3406
3407unsigned clang_visitChildren(CXCursor parent,
3408 CXCursorVisitor visitor,
3409 CXClientData client_data) {
3410 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3411 /*VisitPreprocessorLast=*/false);
3412 return CursorVis.VisitChildren(parent);
3413}
3414
3415#ifndef __has_feature
3416#define __has_feature(x) 0
3417#endif
3418#if __has_feature(blocks)
3419typedef enum CXChildVisitResult
3420 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3421
3422static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3423 CXClientData client_data) {
3424 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3425 return block(cursor, parent);
3426}
3427#else
3428// If we are compiled with a compiler that doesn't have native blocks support,
3429// define and call the block manually, so the
3430typedef struct _CXChildVisitResult
3431{
3432 void *isa;
3433 int flags;
3434 int reserved;
3435 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3436 CXCursor);
3437} *CXCursorVisitorBlock;
3438
3439static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3440 CXClientData client_data) {
3441 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3442 return block->invoke(block, cursor, parent);
3443}
3444#endif
3445
3446
3447unsigned clang_visitChildrenWithBlock(CXCursor parent,
3448 CXCursorVisitorBlock block) {
3449 return clang_visitChildren(parent, visitWithBlock, block);
3450}
3451
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003452static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003454 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003455
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003456 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003458 if (const ObjCPropertyImplDecl *PropImpl =
3459 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003461 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003462
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003463 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003465 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003466
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003467 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 }
3469
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003470 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003471 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003472
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003473 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3475 // and returns different names. NamedDecl returns the class name and
3476 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003477 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003478
3479 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003480 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003481
3482 SmallString<1024> S;
3483 llvm::raw_svector_ostream os(S);
3484 ND->printName(os);
3485
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003486 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003487}
3488
3489CXString clang_getCursorSpelling(CXCursor C) {
3490 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003491 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003492
3493 if (clang_isReference(C.kind)) {
3494 switch (C.kind) {
3495 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003496 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003497 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 }
3499 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003500 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003501 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 }
3503 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003504 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003506 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 }
3508 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003509 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003510 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 }
3512 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003513 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 assert(Type && "Missing type decl");
3515
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003516 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 getAsString());
3518 }
3519 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003520 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 assert(Template && "Missing template decl");
3522
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003523 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 }
3525
3526 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003527 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 assert(NS && "Missing namespace decl");
3529
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003530 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 }
3532
3533 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003534 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 assert(Field && "Missing member decl");
3536
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003537 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 }
3539
3540 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003541 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 assert(Label && "Missing label");
3543
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003544 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 }
3546
3547 case CXCursor_OverloadedDeclRef: {
3548 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003549 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3550 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003551 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003552 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003554 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003555 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 OverloadedTemplateStorage *Ovl
3557 = Storage.get<OverloadedTemplateStorage*>();
3558 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003559 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003560 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 }
3562
3563 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003564 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 assert(Var && "Missing variable decl");
3566
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003567 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 }
3569
3570 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003571 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003572 }
3573 }
3574
3575 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003576 const Expr *E = getCursorExpr(C);
3577
3578 if (C.kind == CXCursor_ObjCStringLiteral ||
3579 C.kind == CXCursor_StringLiteral) {
3580 const StringLiteral *SLit;
3581 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3582 SLit = OSL->getString();
3583 } else {
3584 SLit = cast<StringLiteral>(E);
3585 }
3586 SmallString<256> Buf;
3587 llvm::raw_svector_ostream OS(Buf);
3588 SLit->outputString(OS);
3589 return cxstring::createDup(OS.str());
3590 }
3591
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003592 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 if (D)
3594 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003595 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 }
3597
3598 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003599 const Stmt *S = getCursorStmt(C);
3600 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003601 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003602
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003603 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 }
3605
3606 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003607 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 ->getNameStart());
3609
3610 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003611 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 ->getNameStart());
3613
3614 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003615 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003616
3617 if (clang_isDeclaration(C.kind))
3618 return getDeclSpelling(getCursorDecl(C));
3619
3620 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003621 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003622 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 }
3624
3625 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003626 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003627 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 }
3629
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003630 if (C.kind == CXCursor_PackedAttr) {
3631 return cxstring::createRef("packed");
3632 }
3633
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003634 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003635}
3636
3637CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3638 unsigned pieceIndex,
3639 unsigned options) {
3640 if (clang_Cursor_isNull(C))
3641 return clang_getNullRange();
3642
3643 ASTContext &Ctx = getCursorContext(C);
3644
3645 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003646 const Stmt *S = getCursorStmt(C);
3647 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 if (pieceIndex > 0)
3649 return clang_getNullRange();
3650 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3651 }
3652
3653 return clang_getNullRange();
3654 }
3655
3656 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003657 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3659 if (pieceIndex >= ME->getNumSelectorLocs())
3660 return clang_getNullRange();
3661 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3662 }
3663 }
3664
3665 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3666 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003667 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3669 if (pieceIndex >= MD->getNumSelectorLocs())
3670 return clang_getNullRange();
3671 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3672 }
3673 }
3674
3675 if (C.kind == CXCursor_ObjCCategoryDecl ||
3676 C.kind == CXCursor_ObjCCategoryImplDecl) {
3677 if (pieceIndex > 0)
3678 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003679 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3681 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003682 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3684 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3685 }
3686
3687 if (C.kind == CXCursor_ModuleImportDecl) {
3688 if (pieceIndex > 0)
3689 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003690 if (const ImportDecl *ImportD =
3691 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3693 if (!Locs.empty())
3694 return cxloc::translateSourceRange(Ctx,
3695 SourceRange(Locs.front(), Locs.back()));
3696 }
3697 return clang_getNullRange();
3698 }
3699
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003700 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3701 C.kind == CXCursor_ConversionFunction) {
3702 if (pieceIndex > 0)
3703 return clang_getNullRange();
3704 if (const FunctionDecl *FD =
3705 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3706 DeclarationNameInfo FunctionName = FD->getNameInfo();
3707 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3708 }
3709 return clang_getNullRange();
3710 }
3711
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 // FIXME: A CXCursor_InclusionDirective should give the location of the
3713 // filename, but we don't keep track of this.
3714
3715 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3716 // but we don't keep track of this.
3717
3718 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3719 // but we don't keep track of this.
3720
3721 // Default handling, give the location of the cursor.
3722
3723 if (pieceIndex > 0)
3724 return clang_getNullRange();
3725
3726 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3727 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3728 return cxloc::translateSourceRange(Ctx, Loc);
3729}
3730
Eli Bendersky44a206f2014-07-31 18:04:56 +00003731CXString clang_Cursor_getMangling(CXCursor C) {
3732 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3733 return cxstring::createEmpty();
3734
Eli Bendersky44a206f2014-07-31 18:04:56 +00003735 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003736 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003737 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3738 return cxstring::createEmpty();
3739
Eli Bendersky79759592014-08-01 15:01:10 +00003740 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003741 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003742 ASTContext &Ctx = ND->getASTContext();
3743 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003744
Eli Bendersky79759592014-08-01 15:01:10 +00003745 std::string FrontendBuf;
3746 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3747 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003748
Eli Bendersky79759592014-08-01 15:01:10 +00003749 // Now apply backend mangling.
3750 std::unique_ptr<llvm::DataLayout> DL(
3751 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3752 llvm::Mangler BackendMangler(DL.get());
3753
3754 std::string FinalBuf;
3755 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3756 BackendMangler.getNameWithPrefix(FinalBufOS,
3757 llvm::Twine(FrontendBufOS.str()));
3758
3759 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003760}
3761
Guy Benyei11169dd2012-12-18 14:30:41 +00003762CXString clang_getCursorDisplayName(CXCursor C) {
3763 if (!clang_isDeclaration(C.kind))
3764 return clang_getCursorSpelling(C);
3765
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003766 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003768 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003769
3770 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003771 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 D = FunTmpl->getTemplatedDecl();
3773
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003774 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 SmallString<64> Str;
3776 llvm::raw_svector_ostream OS(Str);
3777 OS << *Function;
3778 if (Function->getPrimaryTemplate())
3779 OS << "<>";
3780 OS << "(";
3781 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3782 if (I)
3783 OS << ", ";
3784 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3785 }
3786
3787 if (Function->isVariadic()) {
3788 if (Function->getNumParams())
3789 OS << ", ";
3790 OS << "...";
3791 }
3792 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003793 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 }
3795
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003796 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 SmallString<64> Str;
3798 llvm::raw_svector_ostream OS(Str);
3799 OS << *ClassTemplate;
3800 OS << "<";
3801 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3802 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3803 if (I)
3804 OS << ", ";
3805
3806 NamedDecl *Param = Params->getParam(I);
3807 if (Param->getIdentifier()) {
3808 OS << Param->getIdentifier()->getName();
3809 continue;
3810 }
3811
3812 // There is no parameter name, which makes this tricky. Try to come up
3813 // with something useful that isn't too long.
3814 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3815 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3816 else if (NonTypeTemplateParmDecl *NTTP
3817 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3818 OS << NTTP->getType().getAsString(Policy);
3819 else
3820 OS << "template<...> class";
3821 }
3822
3823 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003824 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 }
3826
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003827 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3829 // If the type was explicitly written, use that.
3830 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003831 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003832
Benjamin Kramer9170e912013-02-22 15:46:01 +00003833 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 llvm::raw_svector_ostream OS(Str);
3835 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003836 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 ClassSpec->getTemplateArgs().data(),
3838 ClassSpec->getTemplateArgs().size(),
3839 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003840 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 }
3842
3843 return clang_getCursorSpelling(C);
3844}
3845
3846CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3847 switch (Kind) {
3848 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003976 case CXCursor_ObjCSelfExpr:
3977 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004066 case CXCursor_SEHLeaveStmt:
4067 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004096 case CXCursor_PackedAttr:
4097 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004098 case CXCursor_PureAttr:
4099 return cxstring::createRef("attribute(pure)");
4100 case CXCursor_ConstAttr:
4101 return cxstring::createRef("attribute(const)");
4102 case CXCursor_NoDuplicateAttr:
4103 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004104 case CXCursor_CUDAConstantAttr:
4105 return cxstring::createRef("attribute(constant)");
4106 case CXCursor_CUDADeviceAttr:
4107 return cxstring::createRef("attribute(device)");
4108 case CXCursor_CUDAGlobalAttr:
4109 return cxstring::createRef("attribute(global)");
4110 case CXCursor_CUDAHostAttr:
4111 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004112 case CXCursor_CUDASharedAttr:
4113 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004162 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004163 return cxstring::createRef("OMPParallelDirective");
4164 case CXCursor_OMPSimdDirective:
4165 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004166 case CXCursor_OMPForDirective:
4167 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004168 case CXCursor_OMPForSimdDirective:
4169 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004170 case CXCursor_OMPSectionsDirective:
4171 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004172 case CXCursor_OMPSectionDirective:
4173 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004174 case CXCursor_OMPSingleDirective:
4175 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004176 case CXCursor_OMPMasterDirective:
4177 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004178 case CXCursor_OMPCriticalDirective:
4179 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004180 case CXCursor_OMPParallelForDirective:
4181 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004182 case CXCursor_OMPParallelForSimdDirective:
4183 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004184 case CXCursor_OMPParallelSectionsDirective:
4185 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004186 case CXCursor_OMPTaskDirective:
4187 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004188 case CXCursor_OMPTaskyieldDirective:
4189 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004190 case CXCursor_OMPBarrierDirective:
4191 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004192 case CXCursor_OMPTaskwaitDirective:
4193 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004194 case CXCursor_OMPFlushDirective:
4195 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004196 case CXCursor_OMPOrderedDirective:
4197 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004198 case CXCursor_OMPAtomicDirective:
4199 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004200 case CXCursor_OMPTargetDirective:
4201 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004202 case CXCursor_OMPTeamsDirective:
4203 return cxstring::createRef("OMPTeamsDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 }
4205
4206 llvm_unreachable("Unhandled CXCursorKind");
4207}
4208
4209struct GetCursorData {
4210 SourceLocation TokenBeginLoc;
4211 bool PointsAtMacroArgExpansion;
4212 bool VisitedObjCPropertyImplDecl;
4213 SourceLocation VisitedDeclaratorDeclStartLoc;
4214 CXCursor &BestCursor;
4215
4216 GetCursorData(SourceManager &SM,
4217 SourceLocation tokenBegin, CXCursor &outputCursor)
4218 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4219 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4220 VisitedObjCPropertyImplDecl = false;
4221 }
4222};
4223
4224static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4225 CXCursor parent,
4226 CXClientData client_data) {
4227 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4228 CXCursor *BestCursor = &Data->BestCursor;
4229
4230 // If we point inside a macro argument we should provide info of what the
4231 // token is so use the actual cursor, don't replace it with a macro expansion
4232 // cursor.
4233 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4234 return CXChildVisit_Recurse;
4235
4236 if (clang_isDeclaration(cursor.kind)) {
4237 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004238 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4240 if (MD->isImplicit())
4241 return CXChildVisit_Break;
4242
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004243 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4245 // Check that when we have multiple @class references in the same line,
4246 // that later ones do not override the previous ones.
4247 // If we have:
4248 // @class Foo, Bar;
4249 // source ranges for both start at '@', so 'Bar' will end up overriding
4250 // 'Foo' even though the cursor location was at 'Foo'.
4251 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4252 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004253 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004254 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4255 if (PrevID != ID &&
4256 !PrevID->isThisDeclarationADefinition() &&
4257 !ID->isThisDeclarationADefinition())
4258 return CXChildVisit_Break;
4259 }
4260
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004261 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4263 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4264 // Check that when we have multiple declarators in the same line,
4265 // that later ones do not override the previous ones.
4266 // If we have:
4267 // int Foo, Bar;
4268 // source ranges for both start at 'int', so 'Bar' will end up overriding
4269 // 'Foo' even though the cursor location was at 'Foo'.
4270 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4271 return CXChildVisit_Break;
4272 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4273
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004274 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4276 (void)PropImp;
4277 // Check that when we have multiple @synthesize in the same line,
4278 // that later ones do not override the previous ones.
4279 // If we have:
4280 // @synthesize Foo, Bar;
4281 // source ranges for both start at '@', so 'Bar' will end up overriding
4282 // 'Foo' even though the cursor location was at 'Foo'.
4283 if (Data->VisitedObjCPropertyImplDecl)
4284 return CXChildVisit_Break;
4285 Data->VisitedObjCPropertyImplDecl = true;
4286 }
4287 }
4288
4289 if (clang_isExpression(cursor.kind) &&
4290 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004291 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 // Avoid having the cursor of an expression replace the declaration cursor
4293 // when the expression source range overlaps the declaration range.
4294 // This can happen for C++ constructor expressions whose range generally
4295 // include the variable declaration, e.g.:
4296 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4297 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4298 D->getLocation() == Data->TokenBeginLoc)
4299 return CXChildVisit_Break;
4300 }
4301 }
4302
4303 // If our current best cursor is the construction of a temporary object,
4304 // don't replace that cursor with a type reference, because we want
4305 // clang_getCursor() to point at the constructor.
4306 if (clang_isExpression(BestCursor->kind) &&
4307 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4308 cursor.kind == CXCursor_TypeRef) {
4309 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4310 // as having the actual point on the type reference.
4311 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4312 return CXChildVisit_Recurse;
4313 }
4314
4315 *BestCursor = cursor;
4316 return CXChildVisit_Recurse;
4317}
4318
4319CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004320 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004321 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004322 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004323 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004324
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004325 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004326 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4327
4328 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4329 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4330
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004331 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 CXFile SearchFile;
4333 unsigned SearchLine, SearchColumn;
4334 CXFile ResultFile;
4335 unsigned ResultLine, ResultColumn;
4336 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4337 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4338 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004339
4340 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4341 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004342 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004343 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004344 SearchFileName = clang_getFileName(SearchFile);
4345 ResultFileName = clang_getFileName(ResultFile);
4346 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4347 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004348 *Log << llvm::format("(%s:%d:%d) = %s",
4349 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4350 clang_getCString(KindSpelling))
4351 << llvm::format("(%s:%d:%d):%s%s",
4352 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4353 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 clang_disposeString(SearchFileName);
4355 clang_disposeString(ResultFileName);
4356 clang_disposeString(KindSpelling);
4357 clang_disposeString(USR);
4358
4359 CXCursor Definition = clang_getCursorDefinition(Result);
4360 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4361 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4362 CXString DefinitionKindSpelling
4363 = clang_getCursorKindSpelling(Definition.kind);
4364 CXFile DefinitionFile;
4365 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004366 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004367 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004369 *Log << llvm::format(" -> %s(%s:%d:%d)",
4370 clang_getCString(DefinitionKindSpelling),
4371 clang_getCString(DefinitionFileName),
4372 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004373 clang_disposeString(DefinitionFileName);
4374 clang_disposeString(DefinitionKindSpelling);
4375 }
4376 }
4377
4378 return Result;
4379}
4380
4381CXCursor clang_getNullCursor(void) {
4382 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4383}
4384
4385unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004386 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4387 // can't set consistently. For example, when visiting a DeclStmt we will set
4388 // it but we don't set it on the result of clang_getCursorDefinition for
4389 // a reference of the same declaration.
4390 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4391 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4392 // to provide that kind of info.
4393 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004394 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004395 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004396 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004397
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 return X == Y;
4399}
4400
4401unsigned clang_hashCursor(CXCursor C) {
4402 unsigned Index = 0;
4403 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4404 Index = 1;
4405
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004406 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 std::make_pair(C.kind, C.data[Index]));
4408}
4409
4410unsigned clang_isInvalid(enum CXCursorKind K) {
4411 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4412}
4413
4414unsigned clang_isDeclaration(enum CXCursorKind K) {
4415 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4416 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4417}
4418
4419unsigned clang_isReference(enum CXCursorKind K) {
4420 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4421}
4422
4423unsigned clang_isExpression(enum CXCursorKind K) {
4424 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4425}
4426
4427unsigned clang_isStatement(enum CXCursorKind K) {
4428 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4429}
4430
4431unsigned clang_isAttribute(enum CXCursorKind K) {
4432 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4433}
4434
4435unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4436 return K == CXCursor_TranslationUnit;
4437}
4438
4439unsigned clang_isPreprocessing(enum CXCursorKind K) {
4440 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4441}
4442
4443unsigned clang_isUnexposed(enum CXCursorKind K) {
4444 switch (K) {
4445 case CXCursor_UnexposedDecl:
4446 case CXCursor_UnexposedExpr:
4447 case CXCursor_UnexposedStmt:
4448 case CXCursor_UnexposedAttr:
4449 return true;
4450 default:
4451 return false;
4452 }
4453}
4454
4455CXCursorKind clang_getCursorKind(CXCursor C) {
4456 return C.kind;
4457}
4458
4459CXSourceLocation clang_getCursorLocation(CXCursor C) {
4460 if (clang_isReference(C.kind)) {
4461 switch (C.kind) {
4462 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004463 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 = getCursorObjCSuperClassRef(C);
4465 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4466 }
4467
4468 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004469 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 = getCursorObjCProtocolRef(C);
4471 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4472 }
4473
4474 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004475 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 = getCursorObjCClassRef(C);
4477 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4478 }
4479
4480 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004481 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4483 }
4484
4485 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004486 std::pair<const TemplateDecl *, SourceLocation> P =
4487 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4489 }
4490
4491 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004492 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4494 }
4495
4496 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004497 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004498 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4499 }
4500
4501 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004502 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4504 }
4505
4506 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004507 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 if (!BaseSpec)
4509 return clang_getNullLocation();
4510
4511 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4512 return cxloc::translateSourceLocation(getCursorContext(C),
4513 TSInfo->getTypeLoc().getBeginLoc());
4514
4515 return cxloc::translateSourceLocation(getCursorContext(C),
4516 BaseSpec->getLocStart());
4517 }
4518
4519 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004520 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4522 }
4523
4524 case CXCursor_OverloadedDeclRef:
4525 return cxloc::translateSourceLocation(getCursorContext(C),
4526 getCursorOverloadedDeclRef(C).second);
4527
4528 default:
4529 // FIXME: Need a way to enumerate all non-reference cases.
4530 llvm_unreachable("Missed a reference kind");
4531 }
4532 }
4533
4534 if (clang_isExpression(C.kind))
4535 return cxloc::translateSourceLocation(getCursorContext(C),
4536 getLocationFromExpr(getCursorExpr(C)));
4537
4538 if (clang_isStatement(C.kind))
4539 return cxloc::translateSourceLocation(getCursorContext(C),
4540 getCursorStmt(C)->getLocStart());
4541
4542 if (C.kind == CXCursor_PreprocessingDirective) {
4543 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4544 return cxloc::translateSourceLocation(getCursorContext(C), L);
4545 }
4546
4547 if (C.kind == CXCursor_MacroExpansion) {
4548 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004549 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 return cxloc::translateSourceLocation(getCursorContext(C), L);
4551 }
4552
4553 if (C.kind == CXCursor_MacroDefinition) {
4554 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4555 return cxloc::translateSourceLocation(getCursorContext(C), L);
4556 }
4557
4558 if (C.kind == CXCursor_InclusionDirective) {
4559 SourceLocation L
4560 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4561 return cxloc::translateSourceLocation(getCursorContext(C), L);
4562 }
4563
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004564 if (clang_isAttribute(C.kind)) {
4565 SourceLocation L
4566 = cxcursor::getCursorAttr(C)->getLocation();
4567 return cxloc::translateSourceLocation(getCursorContext(C), L);
4568 }
4569
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 if (!clang_isDeclaration(C.kind))
4571 return clang_getNullLocation();
4572
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004573 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004574 if (!D)
4575 return clang_getNullLocation();
4576
4577 SourceLocation Loc = D->getLocation();
4578 // FIXME: Multiple variables declared in a single declaration
4579 // currently lack the information needed to correctly determine their
4580 // ranges when accounting for the type-specifier. We use context
4581 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4582 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004583 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 if (!cxcursor::isFirstInDeclGroup(C))
4585 Loc = VD->getLocation();
4586 }
4587
4588 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004589 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 Loc = MD->getSelectorStartLoc();
4591
4592 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4593}
4594
4595} // end extern "C"
4596
4597CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4598 assert(TU);
4599
4600 // Guard against an invalid SourceLocation, or we may assert in one
4601 // of the following calls.
4602 if (SLoc.isInvalid())
4603 return clang_getNullCursor();
4604
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004605 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004606
4607 // Translate the given source location to make it point at the beginning of
4608 // the token under the cursor.
4609 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4610 CXXUnit->getASTContext().getLangOpts());
4611
4612 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4613 if (SLoc.isValid()) {
4614 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4615 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4616 /*VisitPreprocessorLast=*/true,
4617 /*VisitIncludedEntities=*/false,
4618 SourceLocation(SLoc));
4619 CursorVis.visitFileRegion();
4620 }
4621
4622 return Result;
4623}
4624
4625static SourceRange getRawCursorExtent(CXCursor C) {
4626 if (clang_isReference(C.kind)) {
4627 switch (C.kind) {
4628 case CXCursor_ObjCSuperClassRef:
4629 return getCursorObjCSuperClassRef(C).second;
4630
4631 case CXCursor_ObjCProtocolRef:
4632 return getCursorObjCProtocolRef(C).second;
4633
4634 case CXCursor_ObjCClassRef:
4635 return getCursorObjCClassRef(C).second;
4636
4637 case CXCursor_TypeRef:
4638 return getCursorTypeRef(C).second;
4639
4640 case CXCursor_TemplateRef:
4641 return getCursorTemplateRef(C).second;
4642
4643 case CXCursor_NamespaceRef:
4644 return getCursorNamespaceRef(C).second;
4645
4646 case CXCursor_MemberRef:
4647 return getCursorMemberRef(C).second;
4648
4649 case CXCursor_CXXBaseSpecifier:
4650 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4651
4652 case CXCursor_LabelRef:
4653 return getCursorLabelRef(C).second;
4654
4655 case CXCursor_OverloadedDeclRef:
4656 return getCursorOverloadedDeclRef(C).second;
4657
4658 case CXCursor_VariableRef:
4659 return getCursorVariableRef(C).second;
4660
4661 default:
4662 // FIXME: Need a way to enumerate all non-reference cases.
4663 llvm_unreachable("Missed a reference kind");
4664 }
4665 }
4666
4667 if (clang_isExpression(C.kind))
4668 return getCursorExpr(C)->getSourceRange();
4669
4670 if (clang_isStatement(C.kind))
4671 return getCursorStmt(C)->getSourceRange();
4672
4673 if (clang_isAttribute(C.kind))
4674 return getCursorAttr(C)->getRange();
4675
4676 if (C.kind == CXCursor_PreprocessingDirective)
4677 return cxcursor::getCursorPreprocessingDirective(C);
4678
4679 if (C.kind == CXCursor_MacroExpansion) {
4680 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004681 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004682 return TU->mapRangeFromPreamble(Range);
4683 }
4684
4685 if (C.kind == CXCursor_MacroDefinition) {
4686 ASTUnit *TU = getCursorASTUnit(C);
4687 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4688 return TU->mapRangeFromPreamble(Range);
4689 }
4690
4691 if (C.kind == CXCursor_InclusionDirective) {
4692 ASTUnit *TU = getCursorASTUnit(C);
4693 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4694 return TU->mapRangeFromPreamble(Range);
4695 }
4696
4697 if (C.kind == CXCursor_TranslationUnit) {
4698 ASTUnit *TU = getCursorASTUnit(C);
4699 FileID MainID = TU->getSourceManager().getMainFileID();
4700 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4701 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4702 return SourceRange(Start, End);
4703 }
4704
4705 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004706 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004707 if (!D)
4708 return SourceRange();
4709
4710 SourceRange R = D->getSourceRange();
4711 // FIXME: Multiple variables declared in a single declaration
4712 // currently lack the information needed to correctly determine their
4713 // ranges when accounting for the type-specifier. We use context
4714 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4715 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004716 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 if (!cxcursor::isFirstInDeclGroup(C))
4718 R.setBegin(VD->getLocation());
4719 }
4720 return R;
4721 }
4722 return SourceRange();
4723}
4724
4725/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4726/// the decl-specifier-seq for declarations.
4727static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4728 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004729 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 if (!D)
4731 return SourceRange();
4732
4733 SourceRange R = D->getSourceRange();
4734
4735 // Adjust the start of the location for declarations preceded by
4736 // declaration specifiers.
4737 SourceLocation StartLoc;
4738 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4739 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4740 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004741 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4743 StartLoc = TI->getTypeLoc().getLocStart();
4744 }
4745
4746 if (StartLoc.isValid() && R.getBegin().isValid() &&
4747 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4748 R.setBegin(StartLoc);
4749
4750 // FIXME: Multiple variables declared in a single declaration
4751 // currently lack the information needed to correctly determine their
4752 // ranges when accounting for the type-specifier. We use context
4753 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4754 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004755 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 if (!cxcursor::isFirstInDeclGroup(C))
4757 R.setBegin(VD->getLocation());
4758 }
4759
4760 return R;
4761 }
4762
4763 return getRawCursorExtent(C);
4764}
4765
4766extern "C" {
4767
4768CXSourceRange clang_getCursorExtent(CXCursor C) {
4769 SourceRange R = getRawCursorExtent(C);
4770 if (R.isInvalid())
4771 return clang_getNullRange();
4772
4773 return cxloc::translateSourceRange(getCursorContext(C), R);
4774}
4775
4776CXCursor clang_getCursorReferenced(CXCursor C) {
4777 if (clang_isInvalid(C.kind))
4778 return clang_getNullCursor();
4779
4780 CXTranslationUnit tu = getCursorTU(C);
4781 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004782 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 if (!D)
4784 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004785 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004787 if (const ObjCPropertyImplDecl *PropImpl =
4788 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4790 return MakeCXCursor(Property, tu);
4791
4792 return C;
4793 }
4794
4795 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004796 const Expr *E = getCursorExpr(C);
4797 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004798 if (D) {
4799 CXCursor declCursor = MakeCXCursor(D, tu);
4800 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4801 declCursor);
4802 return declCursor;
4803 }
4804
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004805 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004806 return MakeCursorOverloadedDeclRef(Ovl, tu);
4807
4808 return clang_getNullCursor();
4809 }
4810
4811 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004812 const Stmt *S = getCursorStmt(C);
4813 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 if (LabelDecl *label = Goto->getLabel())
4815 if (LabelStmt *labelS = label->getStmt())
4816 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4817
4818 return clang_getNullCursor();
4819 }
4820
4821 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004822 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 return MakeMacroDefinitionCursor(Def, tu);
4824 }
4825
4826 if (!clang_isReference(C.kind))
4827 return clang_getNullCursor();
4828
4829 switch (C.kind) {
4830 case CXCursor_ObjCSuperClassRef:
4831 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4832
4833 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004834 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4835 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004836 return MakeCXCursor(Def, tu);
4837
4838 return MakeCXCursor(Prot, tu);
4839 }
4840
4841 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004842 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4843 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 return MakeCXCursor(Def, tu);
4845
4846 return MakeCXCursor(Class, tu);
4847 }
4848
4849 case CXCursor_TypeRef:
4850 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4851
4852 case CXCursor_TemplateRef:
4853 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4854
4855 case CXCursor_NamespaceRef:
4856 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4857
4858 case CXCursor_MemberRef:
4859 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4860
4861 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004862 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004863 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4864 tu ));
4865 }
4866
4867 case CXCursor_LabelRef:
4868 // FIXME: We end up faking the "parent" declaration here because we
4869 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004870 return MakeCXCursor(getCursorLabelRef(C).first,
4871 cxtu::getASTUnit(tu)->getASTContext()
4872 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 tu);
4874
4875 case CXCursor_OverloadedDeclRef:
4876 return C;
4877
4878 case CXCursor_VariableRef:
4879 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4880
4881 default:
4882 // We would prefer to enumerate all non-reference cursor kinds here.
4883 llvm_unreachable("Unhandled reference cursor kind");
4884 }
4885}
4886
4887CXCursor clang_getCursorDefinition(CXCursor C) {
4888 if (clang_isInvalid(C.kind))
4889 return clang_getNullCursor();
4890
4891 CXTranslationUnit TU = getCursorTU(C);
4892
4893 bool WasReference = false;
4894 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4895 C = clang_getCursorReferenced(C);
4896 WasReference = true;
4897 }
4898
4899 if (C.kind == CXCursor_MacroExpansion)
4900 return clang_getCursorReferenced(C);
4901
4902 if (!clang_isDeclaration(C.kind))
4903 return clang_getNullCursor();
4904
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004905 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004906 if (!D)
4907 return clang_getNullCursor();
4908
4909 switch (D->getKind()) {
4910 // Declaration kinds that don't really separate the notions of
4911 // declaration and definition.
4912 case Decl::Namespace:
4913 case Decl::Typedef:
4914 case Decl::TypeAlias:
4915 case Decl::TypeAliasTemplate:
4916 case Decl::TemplateTypeParm:
4917 case Decl::EnumConstant:
4918 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004919 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 case Decl::IndirectField:
4921 case Decl::ObjCIvar:
4922 case Decl::ObjCAtDefsField:
4923 case Decl::ImplicitParam:
4924 case Decl::ParmVar:
4925 case Decl::NonTypeTemplateParm:
4926 case Decl::TemplateTemplateParm:
4927 case Decl::ObjCCategoryImpl:
4928 case Decl::ObjCImplementation:
4929 case Decl::AccessSpec:
4930 case Decl::LinkageSpec:
4931 case Decl::ObjCPropertyImpl:
4932 case Decl::FileScopeAsm:
4933 case Decl::StaticAssert:
4934 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004935 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004936 case Decl::Label: // FIXME: Is this right??
4937 case Decl::ClassScopeFunctionSpecialization:
4938 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004939 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004940 return C;
4941
4942 // Declaration kinds that don't make any sense here, but are
4943 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004944 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004945 case Decl::TranslationUnit:
4946 break;
4947
4948 // Declaration kinds for which the definition is not resolvable.
4949 case Decl::UnresolvedUsingTypename:
4950 case Decl::UnresolvedUsingValue:
4951 break;
4952
4953 case Decl::UsingDirective:
4954 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4955 TU);
4956
4957 case Decl::NamespaceAlias:
4958 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4959
4960 case Decl::Enum:
4961 case Decl::Record:
4962 case Decl::CXXRecord:
4963 case Decl::ClassTemplateSpecialization:
4964 case Decl::ClassTemplatePartialSpecialization:
4965 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4966 return MakeCXCursor(Def, TU);
4967 return clang_getNullCursor();
4968
4969 case Decl::Function:
4970 case Decl::CXXMethod:
4971 case Decl::CXXConstructor:
4972 case Decl::CXXDestructor:
4973 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004974 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004975 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004976 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004977 return clang_getNullCursor();
4978 }
4979
Larisse Voufo39a1e502013-08-06 01:03:05 +00004980 case Decl::Var:
4981 case Decl::VarTemplateSpecialization:
4982 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004984 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 return MakeCXCursor(Def, TU);
4986 return clang_getNullCursor();
4987 }
4988
4989 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004990 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4992 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4993 return clang_getNullCursor();
4994 }
4995
4996 case Decl::ClassTemplate: {
4997 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4998 ->getDefinition())
4999 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5000 TU);
5001 return clang_getNullCursor();
5002 }
5003
Larisse Voufo39a1e502013-08-06 01:03:05 +00005004 case Decl::VarTemplate: {
5005 if (VarDecl *Def =
5006 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5007 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5008 return clang_getNullCursor();
5009 }
5010
Guy Benyei11169dd2012-12-18 14:30:41 +00005011 case Decl::Using:
5012 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5013 D->getLocation(), TU);
5014
5015 case Decl::UsingShadow:
5016 return clang_getCursorDefinition(
5017 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5018 TU));
5019
5020 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005021 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005022 if (Method->isThisDeclarationADefinition())
5023 return C;
5024
5025 // Dig out the method definition in the associated
5026 // @implementation, if we have it.
5027 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005028 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005029 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5030 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5031 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5032 Method->isInstanceMethod()))
5033 if (Def->isThisDeclarationADefinition())
5034 return MakeCXCursor(Def, TU);
5035
5036 return clang_getNullCursor();
5037 }
5038
5039 case Decl::ObjCCategory:
5040 if (ObjCCategoryImplDecl *Impl
5041 = cast<ObjCCategoryDecl>(D)->getImplementation())
5042 return MakeCXCursor(Impl, TU);
5043 return clang_getNullCursor();
5044
5045 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005046 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 return MakeCXCursor(Def, TU);
5048 return clang_getNullCursor();
5049
5050 case Decl::ObjCInterface: {
5051 // There are two notions of a "definition" for an Objective-C
5052 // class: the interface and its implementation. When we resolved a
5053 // reference to an Objective-C class, produce the @interface as
5054 // the definition; when we were provided with the interface,
5055 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005056 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005057 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005058 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005059 return MakeCXCursor(Def, TU);
5060 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5061 return MakeCXCursor(Impl, TU);
5062 return clang_getNullCursor();
5063 }
5064
5065 case Decl::ObjCProperty:
5066 // FIXME: We don't really know where to find the
5067 // ObjCPropertyImplDecls that implement this property.
5068 return clang_getNullCursor();
5069
5070 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005071 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005072 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005073 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005074 return MakeCXCursor(Def, TU);
5075
5076 return clang_getNullCursor();
5077
5078 case Decl::Friend:
5079 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5080 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5081 return clang_getNullCursor();
5082
5083 case Decl::FriendTemplate:
5084 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5085 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5086 return clang_getNullCursor();
5087 }
5088
5089 return clang_getNullCursor();
5090}
5091
5092unsigned clang_isCursorDefinition(CXCursor C) {
5093 if (!clang_isDeclaration(C.kind))
5094 return 0;
5095
5096 return clang_getCursorDefinition(C) == C;
5097}
5098
5099CXCursor clang_getCanonicalCursor(CXCursor C) {
5100 if (!clang_isDeclaration(C.kind))
5101 return C;
5102
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005103 if (const Decl *D = getCursorDecl(C)) {
5104 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005105 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5106 return MakeCXCursor(CatD, getCursorTU(C));
5107
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005108 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5109 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 return MakeCXCursor(IFD, getCursorTU(C));
5111
5112 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5113 }
5114
5115 return C;
5116}
5117
5118int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5119 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5120}
5121
5122unsigned clang_getNumOverloadedDecls(CXCursor C) {
5123 if (C.kind != CXCursor_OverloadedDeclRef)
5124 return 0;
5125
5126 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005127 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 return E->getNumDecls();
5129
5130 if (OverloadedTemplateStorage *S
5131 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5132 return S->size();
5133
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005134 const Decl *D = Storage.get<const Decl *>();
5135 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 return Using->shadow_size();
5137
5138 return 0;
5139}
5140
5141CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5142 if (cursor.kind != CXCursor_OverloadedDeclRef)
5143 return clang_getNullCursor();
5144
5145 if (index >= clang_getNumOverloadedDecls(cursor))
5146 return clang_getNullCursor();
5147
5148 CXTranslationUnit TU = getCursorTU(cursor);
5149 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005150 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005151 return MakeCXCursor(E->decls_begin()[index], TU);
5152
5153 if (OverloadedTemplateStorage *S
5154 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5155 return MakeCXCursor(S->begin()[index], TU);
5156
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005157 const Decl *D = Storage.get<const Decl *>();
5158 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 // FIXME: This is, unfortunately, linear time.
5160 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5161 std::advance(Pos, index);
5162 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5163 }
5164
5165 return clang_getNullCursor();
5166}
5167
5168void clang_getDefinitionSpellingAndExtent(CXCursor C,
5169 const char **startBuf,
5170 const char **endBuf,
5171 unsigned *startLine,
5172 unsigned *startColumn,
5173 unsigned *endLine,
5174 unsigned *endColumn) {
5175 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005176 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5178
5179 SourceManager &SM = FD->getASTContext().getSourceManager();
5180 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5181 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5182 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5183 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5184 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5185 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5186}
5187
5188
5189CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5190 unsigned PieceIndex) {
5191 RefNamePieces Pieces;
5192
5193 switch (C.kind) {
5194 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005195 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5197 E->getQualifierLoc().getSourceRange());
5198 break;
5199
5200 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005201 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5203 E->getQualifierLoc().getSourceRange(),
5204 E->getOptionalExplicitTemplateArgs());
5205 break;
5206
5207 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005208 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005210 const Expr *Callee = OCE->getCallee();
5211 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 Callee = ICE->getSubExpr();
5213
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005214 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5216 DRE->getQualifierLoc().getSourceRange());
5217 }
5218 break;
5219
5220 default:
5221 break;
5222 }
5223
5224 if (Pieces.empty()) {
5225 if (PieceIndex == 0)
5226 return clang_getCursorExtent(C);
5227 } else if (PieceIndex < Pieces.size()) {
5228 SourceRange R = Pieces[PieceIndex];
5229 if (R.isValid())
5230 return cxloc::translateSourceRange(getCursorContext(C), R);
5231 }
5232
5233 return clang_getNullRange();
5234}
5235
5236void clang_enableStackTraces(void) {
5237 llvm::sys::PrintStackTraceOnErrorSignal();
5238}
5239
5240void clang_executeOnThread(void (*fn)(void*), void *user_data,
5241 unsigned stack_size) {
5242 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5243}
5244
5245} // end: extern "C"
5246
5247//===----------------------------------------------------------------------===//
5248// Token-based Operations.
5249//===----------------------------------------------------------------------===//
5250
5251/* CXToken layout:
5252 * int_data[0]: a CXTokenKind
5253 * int_data[1]: starting token location
5254 * int_data[2]: token length
5255 * int_data[3]: reserved
5256 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5257 * otherwise unused.
5258 */
5259extern "C" {
5260
5261CXTokenKind clang_getTokenKind(CXToken CXTok) {
5262 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5263}
5264
5265CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5266 switch (clang_getTokenKind(CXTok)) {
5267 case CXToken_Identifier:
5268 case CXToken_Keyword:
5269 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005270 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005271 ->getNameStart());
5272
5273 case CXToken_Literal: {
5274 // We have stashed the starting pointer in the ptr_data field. Use it.
5275 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005276 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 }
5278
5279 case CXToken_Punctuation:
5280 case CXToken_Comment:
5281 break;
5282 }
5283
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005284 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005285 LOG_BAD_TU(TU);
5286 return cxstring::createEmpty();
5287 }
5288
Guy Benyei11169dd2012-12-18 14:30:41 +00005289 // We have to find the starting buffer pointer the hard way, by
5290 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005291 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005293 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005294
5295 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5296 std::pair<FileID, unsigned> LocInfo
5297 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5298 bool Invalid = false;
5299 StringRef Buffer
5300 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5301 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005302 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005303
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005304 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005305}
5306
5307CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005308 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005309 LOG_BAD_TU(TU);
5310 return clang_getNullLocation();
5311 }
5312
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005313 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 if (!CXXUnit)
5315 return clang_getNullLocation();
5316
5317 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5318 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5319}
5320
5321CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005322 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005323 LOG_BAD_TU(TU);
5324 return clang_getNullRange();
5325 }
5326
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005327 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 if (!CXXUnit)
5329 return clang_getNullRange();
5330
5331 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5332 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5333}
5334
5335static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5336 SmallVectorImpl<CXToken> &CXTokens) {
5337 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5338 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005339 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005341 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005342
5343 // Cannot tokenize across files.
5344 if (BeginLocInfo.first != EndLocInfo.first)
5345 return;
5346
5347 // Create a lexer
5348 bool Invalid = false;
5349 StringRef Buffer
5350 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5351 if (Invalid)
5352 return;
5353
5354 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5355 CXXUnit->getASTContext().getLangOpts(),
5356 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5357 Lex.SetCommentRetentionState(true);
5358
5359 // Lex tokens until we hit the end of the range.
5360 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5361 Token Tok;
5362 bool previousWasAt = false;
5363 do {
5364 // Lex the next token
5365 Lex.LexFromRawLexer(Tok);
5366 if (Tok.is(tok::eof))
5367 break;
5368
5369 // Initialize the CXToken.
5370 CXToken CXTok;
5371
5372 // - Common fields
5373 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5374 CXTok.int_data[2] = Tok.getLength();
5375 CXTok.int_data[3] = 0;
5376
5377 // - Kind-specific fields
5378 if (Tok.isLiteral()) {
5379 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005380 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005381 } else if (Tok.is(tok::raw_identifier)) {
5382 // Lookup the identifier to determine whether we have a keyword.
5383 IdentifierInfo *II
5384 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5385
5386 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5387 CXTok.int_data[0] = CXToken_Keyword;
5388 }
5389 else {
5390 CXTok.int_data[0] = Tok.is(tok::identifier)
5391 ? CXToken_Identifier
5392 : CXToken_Keyword;
5393 }
5394 CXTok.ptr_data = II;
5395 } else if (Tok.is(tok::comment)) {
5396 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005397 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005398 } else {
5399 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005400 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005401 }
5402 CXTokens.push_back(CXTok);
5403 previousWasAt = Tok.is(tok::at);
5404 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5405}
5406
5407void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5408 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005409 LOG_FUNC_SECTION {
5410 *Log << TU << ' ' << Range;
5411 }
5412
Guy Benyei11169dd2012-12-18 14:30:41 +00005413 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005414 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005415 if (NumTokens)
5416 *NumTokens = 0;
5417
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005418 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005419 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005420 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005421 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005422
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005423 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005424 if (!CXXUnit || !Tokens || !NumTokens)
5425 return;
5426
5427 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5428
5429 SourceRange R = cxloc::translateCXSourceRange(Range);
5430 if (R.isInvalid())
5431 return;
5432
5433 SmallVector<CXToken, 32> CXTokens;
5434 getTokens(CXXUnit, R, CXTokens);
5435
5436 if (CXTokens.empty())
5437 return;
5438
5439 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5440 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5441 *NumTokens = CXTokens.size();
5442}
5443
5444void clang_disposeTokens(CXTranslationUnit TU,
5445 CXToken *Tokens, unsigned NumTokens) {
5446 free(Tokens);
5447}
5448
5449} // end: extern "C"
5450
5451//===----------------------------------------------------------------------===//
5452// Token annotation APIs.
5453//===----------------------------------------------------------------------===//
5454
Guy Benyei11169dd2012-12-18 14:30:41 +00005455static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5456 CXCursor parent,
5457 CXClientData client_data);
5458static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5459 CXClientData client_data);
5460
5461namespace {
5462class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 CXToken *Tokens;
5464 CXCursor *Cursors;
5465 unsigned NumTokens;
5466 unsigned TokIdx;
5467 unsigned PreprocessingTokIdx;
5468 CursorVisitor AnnotateVis;
5469 SourceManager &SrcMgr;
5470 bool HasContextSensitiveKeywords;
5471
5472 struct PostChildrenInfo {
5473 CXCursor Cursor;
5474 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005475 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 unsigned BeforeChildrenTokenIdx;
5477 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005478 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005479
5480 CXToken &getTok(unsigned Idx) {
5481 assert(Idx < NumTokens);
5482 return Tokens[Idx];
5483 }
5484 const CXToken &getTok(unsigned Idx) const {
5485 assert(Idx < NumTokens);
5486 return Tokens[Idx];
5487 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005488 bool MoreTokens() const { return TokIdx < NumTokens; }
5489 unsigned NextToken() const { return TokIdx; }
5490 void AdvanceToken() { ++TokIdx; }
5491 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005492 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005493 }
5494 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005495 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005496 }
5497 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005498 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005499 }
5500
5501 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005502 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005503 SourceRange);
5504
5505public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005506 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005507 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005508 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005509 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005510 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 AnnotateTokensVisitor, this,
5512 /*VisitPreprocessorLast=*/true,
5513 /*VisitIncludedEntities=*/false,
5514 RegionOfInterest,
5515 /*VisitDeclsOnly=*/false,
5516 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005517 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005518 HasContextSensitiveKeywords(false) { }
5519
5520 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5521 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5522 bool postVisitChildren(CXCursor cursor);
5523 void AnnotateTokens();
5524
5525 /// \brief Determine whether the annotator saw any cursors that have
5526 /// context-sensitive keywords.
5527 bool hasContextSensitiveKeywords() const {
5528 return HasContextSensitiveKeywords;
5529 }
5530
5531 ~AnnotateTokensWorker() {
5532 assert(PostChildrenInfos.empty());
5533 }
5534};
5535}
5536
5537void AnnotateTokensWorker::AnnotateTokens() {
5538 // Walk the AST within the region of interest, annotating tokens
5539 // along the way.
5540 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005541}
Guy Benyei11169dd2012-12-18 14:30:41 +00005542
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005543static inline void updateCursorAnnotation(CXCursor &Cursor,
5544 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005545 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005547 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005548}
5549
5550/// \brief It annotates and advances tokens with a cursor until the comparison
5551//// between the cursor location and the source range is the same as
5552/// \arg compResult.
5553///
5554/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5555/// Pass RangeOverlap to annotate tokens inside a range.
5556void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5557 RangeComparisonResult compResult,
5558 SourceRange range) {
5559 while (MoreTokens()) {
5560 const unsigned I = NextToken();
5561 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005562 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5563 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005564
5565 SourceLocation TokLoc = GetTokenLoc(I);
5566 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005567 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005568 AdvanceToken();
5569 continue;
5570 }
5571 break;
5572 }
5573}
5574
5575/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005576/// \returns true if it advanced beyond all macro tokens, false otherwise.
5577bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005578 CXCursor updateC,
5579 RangeComparisonResult compResult,
5580 SourceRange range) {
5581 assert(MoreTokens());
5582 assert(isFunctionMacroToken(NextToken()) &&
5583 "Should be called only for macro arg tokens");
5584
5585 // This works differently than annotateAndAdvanceTokens; because expanded
5586 // macro arguments can have arbitrary translation-unit source order, we do not
5587 // advance the token index one by one until a token fails the range test.
5588 // We only advance once past all of the macro arg tokens if all of them
5589 // pass the range test. If one of them fails we keep the token index pointing
5590 // at the start of the macro arg tokens so that the failing token will be
5591 // annotated by a subsequent annotation try.
5592
5593 bool atLeastOneCompFail = false;
5594
5595 unsigned I = NextToken();
5596 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5597 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5598 if (TokLoc.isFileID())
5599 continue; // not macro arg token, it's parens or comma.
5600 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5601 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5602 Cursors[I] = updateC;
5603 } else
5604 atLeastOneCompFail = true;
5605 }
5606
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005607 if (atLeastOneCompFail)
5608 return false;
5609
5610 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5611 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005612}
5613
5614enum CXChildVisitResult
5615AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005616 SourceRange cursorRange = getRawCursorExtent(cursor);
5617 if (cursorRange.isInvalid())
5618 return CXChildVisit_Recurse;
5619
5620 if (!HasContextSensitiveKeywords) {
5621 // Objective-C properties can have context-sensitive keywords.
5622 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005623 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005624 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5625 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5626 }
5627 // Objective-C methods can have context-sensitive keywords.
5628 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5629 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005630 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005631 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5632 if (Method->getObjCDeclQualifier())
5633 HasContextSensitiveKeywords = true;
5634 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005635 for (const auto *P : Method->params()) {
5636 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 HasContextSensitiveKeywords = true;
5638 break;
5639 }
5640 }
5641 }
5642 }
5643 }
5644 // C++ methods can have context-sensitive keywords.
5645 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005646 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5648 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5649 HasContextSensitiveKeywords = true;
5650 }
5651 }
5652 // C++ classes can have context-sensitive keywords.
5653 else if (cursor.kind == CXCursor_StructDecl ||
5654 cursor.kind == CXCursor_ClassDecl ||
5655 cursor.kind == CXCursor_ClassTemplate ||
5656 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005657 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005658 if (D->hasAttr<FinalAttr>())
5659 HasContextSensitiveKeywords = true;
5660 }
5661 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005662
5663 // Don't override a property annotation with its getter/setter method.
5664 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5665 parent.kind == CXCursor_ObjCPropertyDecl)
5666 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005667
5668 if (clang_isPreprocessing(cursor.kind)) {
5669 // Items in the preprocessing record are kept separate from items in
5670 // declarations, so we keep a separate token index.
5671 unsigned SavedTokIdx = TokIdx;
5672 TokIdx = PreprocessingTokIdx;
5673
5674 // Skip tokens up until we catch up to the beginning of the preprocessing
5675 // entry.
5676 while (MoreTokens()) {
5677 const unsigned I = NextToken();
5678 SourceLocation TokLoc = GetTokenLoc(I);
5679 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5680 case RangeBefore:
5681 AdvanceToken();
5682 continue;
5683 case RangeAfter:
5684 case RangeOverlap:
5685 break;
5686 }
5687 break;
5688 }
5689
5690 // Look at all of the tokens within this range.
5691 while (MoreTokens()) {
5692 const unsigned I = NextToken();
5693 SourceLocation TokLoc = GetTokenLoc(I);
5694 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5695 case RangeBefore:
5696 llvm_unreachable("Infeasible");
5697 case RangeAfter:
5698 break;
5699 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005700 // For macro expansions, just note where the beginning of the macro
5701 // expansion occurs.
5702 if (cursor.kind == CXCursor_MacroExpansion) {
5703 if (TokLoc == cursorRange.getBegin())
5704 Cursors[I] = cursor;
5705 AdvanceToken();
5706 break;
5707 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005708 // We may have already annotated macro names inside macro definitions.
5709 if (Cursors[I].kind != CXCursor_MacroExpansion)
5710 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005711 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005712 continue;
5713 }
5714 break;
5715 }
5716
5717 // Save the preprocessing token index; restore the non-preprocessing
5718 // token index.
5719 PreprocessingTokIdx = TokIdx;
5720 TokIdx = SavedTokIdx;
5721 return CXChildVisit_Recurse;
5722 }
5723
5724 if (cursorRange.isInvalid())
5725 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005726
5727 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005728 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005729 const enum CXCursorKind K = clang_getCursorKind(parent);
5730 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005731 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5732 // Attributes are annotated out-of-order, skip tokens until we reach it.
5733 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 ? clang_getNullCursor() : parent;
5735
5736 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5737
5738 // Avoid having the cursor of an expression "overwrite" the annotation of the
5739 // variable declaration that it belongs to.
5740 // This can happen for C++ constructor expressions whose range generally
5741 // include the variable declaration, e.g.:
5742 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005743 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005744 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005745 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 const unsigned I = NextToken();
5747 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5748 E->getLocStart() == D->getLocation() &&
5749 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005750 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005751 AdvanceToken();
5752 }
5753 }
5754 }
5755
5756 // Before recursing into the children keep some state that we are going
5757 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5758 // extra work after the child nodes are visited.
5759 // Note that we don't call VisitChildren here to avoid traversing statements
5760 // code-recursively which can blow the stack.
5761
5762 PostChildrenInfo Info;
5763 Info.Cursor = cursor;
5764 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005765 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005766 Info.BeforeChildrenTokenIdx = NextToken();
5767 PostChildrenInfos.push_back(Info);
5768
5769 return CXChildVisit_Recurse;
5770}
5771
5772bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5773 if (PostChildrenInfos.empty())
5774 return false;
5775 const PostChildrenInfo &Info = PostChildrenInfos.back();
5776 if (!clang_equalCursors(Info.Cursor, cursor))
5777 return false;
5778
5779 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5780 const unsigned AfterChildren = NextToken();
5781 SourceRange cursorRange = Info.CursorRange;
5782
5783 // Scan the tokens that are at the end of the cursor, but are not captured
5784 // but the child cursors.
5785 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5786
5787 // Scan the tokens that are at the beginning of the cursor, but are not
5788 // capture by the child cursors.
5789 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5790 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5791 break;
5792
5793 Cursors[I] = cursor;
5794 }
5795
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005796 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5797 // encountered the attribute cursor.
5798 if (clang_isAttribute(cursor.kind))
5799 TokIdx = Info.BeforeReachingCursorIdx;
5800
Guy Benyei11169dd2012-12-18 14:30:41 +00005801 PostChildrenInfos.pop_back();
5802 return false;
5803}
5804
5805static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5806 CXCursor parent,
5807 CXClientData client_data) {
5808 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5809}
5810
5811static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5812 CXClientData client_data) {
5813 return static_cast<AnnotateTokensWorker*>(client_data)->
5814 postVisitChildren(cursor);
5815}
5816
5817namespace {
5818
5819/// \brief Uses the macro expansions in the preprocessing record to find
5820/// and mark tokens that are macro arguments. This info is used by the
5821/// AnnotateTokensWorker.
5822class MarkMacroArgTokensVisitor {
5823 SourceManager &SM;
5824 CXToken *Tokens;
5825 unsigned NumTokens;
5826 unsigned CurIdx;
5827
5828public:
5829 MarkMacroArgTokensVisitor(SourceManager &SM,
5830 CXToken *tokens, unsigned numTokens)
5831 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5832
5833 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5834 if (cursor.kind != CXCursor_MacroExpansion)
5835 return CXChildVisit_Continue;
5836
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005837 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005838 if (macroRange.getBegin() == macroRange.getEnd())
5839 return CXChildVisit_Continue; // it's not a function macro.
5840
5841 for (; CurIdx < NumTokens; ++CurIdx) {
5842 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5843 macroRange.getBegin()))
5844 break;
5845 }
5846
5847 if (CurIdx == NumTokens)
5848 return CXChildVisit_Break;
5849
5850 for (; CurIdx < NumTokens; ++CurIdx) {
5851 SourceLocation tokLoc = getTokenLoc(CurIdx);
5852 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5853 break;
5854
5855 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5856 }
5857
5858 if (CurIdx == NumTokens)
5859 return CXChildVisit_Break;
5860
5861 return CXChildVisit_Continue;
5862 }
5863
5864private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005865 CXToken &getTok(unsigned Idx) {
5866 assert(Idx < NumTokens);
5867 return Tokens[Idx];
5868 }
5869 const CXToken &getTok(unsigned Idx) const {
5870 assert(Idx < NumTokens);
5871 return Tokens[Idx];
5872 }
5873
Guy Benyei11169dd2012-12-18 14:30:41 +00005874 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005875 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005876 }
5877
5878 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5879 // The third field is reserved and currently not used. Use it here
5880 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005881 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005882 }
5883};
5884
5885} // end anonymous namespace
5886
5887static CXChildVisitResult
5888MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5889 CXClientData client_data) {
5890 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5891 parent);
5892}
5893
5894namespace {
5895 struct clang_annotateTokens_Data {
5896 CXTranslationUnit TU;
5897 ASTUnit *CXXUnit;
5898 CXToken *Tokens;
5899 unsigned NumTokens;
5900 CXCursor *Cursors;
5901 };
5902}
5903
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005904/// \brief Used by \c annotatePreprocessorTokens.
5905/// \returns true if lexing was finished, false otherwise.
5906static bool lexNext(Lexer &Lex, Token &Tok,
5907 unsigned &NextIdx, unsigned NumTokens) {
5908 if (NextIdx >= NumTokens)
5909 return true;
5910
5911 ++NextIdx;
5912 Lex.LexFromRawLexer(Tok);
5913 if (Tok.is(tok::eof))
5914 return true;
5915
5916 return false;
5917}
5918
Guy Benyei11169dd2012-12-18 14:30:41 +00005919static void annotatePreprocessorTokens(CXTranslationUnit TU,
5920 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005921 CXCursor *Cursors,
5922 CXToken *Tokens,
5923 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005924 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005925
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005926 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005927 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5928 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005929 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005930 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005931 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005932
5933 if (BeginLocInfo.first != EndLocInfo.first)
5934 return;
5935
5936 StringRef Buffer;
5937 bool Invalid = false;
5938 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5939 if (Buffer.empty() || Invalid)
5940 return;
5941
5942 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5943 CXXUnit->getASTContext().getLangOpts(),
5944 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5945 Buffer.end());
5946 Lex.SetCommentRetentionState(true);
5947
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005948 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005949 // Lex tokens in raw mode until we hit the end of the range, to avoid
5950 // entering #includes or expanding macros.
5951 while (true) {
5952 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005953 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5954 break;
5955 unsigned TokIdx = NextIdx-1;
5956 assert(Tok.getLocation() ==
5957 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005958
5959 reprocess:
5960 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005961 // We have found a preprocessing directive. Annotate the tokens
5962 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005963 //
5964 // FIXME: Some simple tests here could identify macro definitions and
5965 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005966
5967 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005968 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5969 break;
5970
Craig Topper69186e72014-06-08 08:38:04 +00005971 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005972 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005973 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5974 break;
5975
5976 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005977 IdentifierInfo &II =
5978 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005979 SourceLocation MappedTokLoc =
5980 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5981 MI = getMacroInfo(II, MappedTokLoc, TU);
5982 }
5983 }
5984
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005985 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005986 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005987 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5988 finished = true;
5989 break;
5990 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005991 // If we are in a macro definition, check if the token was ever a
5992 // macro name and annotate it if that's the case.
5993 if (MI) {
5994 SourceLocation SaveLoc = Tok.getLocation();
5995 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5996 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5997 Tok.setLocation(SaveLoc);
5998 if (MacroDef)
5999 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6000 Tok.getLocation(), TU);
6001 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006002 } while (!Tok.isAtStartOfLine());
6003
6004 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6005 assert(TokIdx <= LastIdx);
6006 SourceLocation EndLoc =
6007 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6008 CXCursor Cursor =
6009 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6010
6011 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006012 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006013
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006014 if (finished)
6015 break;
6016 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006017 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 }
6019}
6020
6021// This gets run a separate thread to avoid stack blowout.
6022static void clang_annotateTokensImpl(void *UserData) {
6023 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6024 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6025 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6026 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6027 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6028
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006029 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006030 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6031 setThreadBackgroundPriority();
6032
6033 // Determine the region of interest, which contains all of the tokens.
6034 SourceRange RegionOfInterest;
6035 RegionOfInterest.setBegin(
6036 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6037 RegionOfInterest.setEnd(
6038 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6039 Tokens[NumTokens-1])));
6040
Guy Benyei11169dd2012-12-18 14:30:41 +00006041 // Relex the tokens within the source range to look for preprocessing
6042 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006043 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006044
6045 // If begin location points inside a macro argument, set it to the expansion
6046 // location so we can have the full context when annotating semantically.
6047 {
6048 SourceManager &SM = CXXUnit->getSourceManager();
6049 SourceLocation Loc =
6050 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6051 if (Loc.isMacroID())
6052 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6053 }
6054
Guy Benyei11169dd2012-12-18 14:30:41 +00006055 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6056 // Search and mark tokens that are macro argument expansions.
6057 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6058 Tokens, NumTokens);
6059 CursorVisitor MacroArgMarker(TU,
6060 MarkMacroArgTokensVisitorDelegate, &Visitor,
6061 /*VisitPreprocessorLast=*/true,
6062 /*VisitIncludedEntities=*/false,
6063 RegionOfInterest);
6064 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6065 }
6066
6067 // Annotate all of the source locations in the region of interest that map to
6068 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006069 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006070
6071 // FIXME: We use a ridiculous stack size here because the data-recursion
6072 // algorithm uses a large stack frame than the non-data recursive version,
6073 // and AnnotationTokensWorker currently transforms the data-recursion
6074 // algorithm back into a traditional recursion by explicitly calling
6075 // VisitChildren(). We will need to remove this explicit recursive call.
6076 W.AnnotateTokens();
6077
6078 // If we ran into any entities that involve context-sensitive keywords,
6079 // take another pass through the tokens to mark them as such.
6080 if (W.hasContextSensitiveKeywords()) {
6081 for (unsigned I = 0; I != NumTokens; ++I) {
6082 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6083 continue;
6084
6085 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6086 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006087 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006088 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6089 if (Property->getPropertyAttributesAsWritten() != 0 &&
6090 llvm::StringSwitch<bool>(II->getName())
6091 .Case("readonly", true)
6092 .Case("assign", true)
6093 .Case("unsafe_unretained", true)
6094 .Case("readwrite", true)
6095 .Case("retain", true)
6096 .Case("copy", true)
6097 .Case("nonatomic", true)
6098 .Case("atomic", true)
6099 .Case("getter", true)
6100 .Case("setter", true)
6101 .Case("strong", true)
6102 .Case("weak", true)
6103 .Default(false))
6104 Tokens[I].int_data[0] = CXToken_Keyword;
6105 }
6106 continue;
6107 }
6108
6109 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6110 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6111 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6112 if (llvm::StringSwitch<bool>(II->getName())
6113 .Case("in", true)
6114 .Case("out", true)
6115 .Case("inout", true)
6116 .Case("oneway", true)
6117 .Case("bycopy", true)
6118 .Case("byref", true)
6119 .Default(false))
6120 Tokens[I].int_data[0] = CXToken_Keyword;
6121 continue;
6122 }
6123
6124 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6125 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6126 Tokens[I].int_data[0] = CXToken_Keyword;
6127 continue;
6128 }
6129 }
6130 }
6131}
6132
6133extern "C" {
6134
6135void clang_annotateTokens(CXTranslationUnit TU,
6136 CXToken *Tokens, unsigned NumTokens,
6137 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006138 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006139 LOG_BAD_TU(TU);
6140 return;
6141 }
6142 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006143 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006144 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006145 }
6146
6147 LOG_FUNC_SECTION {
6148 *Log << TU << ' ';
6149 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6150 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6151 *Log << clang_getRange(bloc, eloc);
6152 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006153
6154 // Any token we don't specifically annotate will have a NULL cursor.
6155 CXCursor C = clang_getNullCursor();
6156 for (unsigned I = 0; I != NumTokens; ++I)
6157 Cursors[I] = C;
6158
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006159 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006160 if (!CXXUnit)
6161 return;
6162
6163 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6164
6165 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6166 llvm::CrashRecoveryContext CRC;
6167 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6168 GetSafetyThreadStackSize() * 2)) {
6169 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6170 }
6171}
6172
6173} // end: extern "C"
6174
6175//===----------------------------------------------------------------------===//
6176// Operations for querying linkage of a cursor.
6177//===----------------------------------------------------------------------===//
6178
6179extern "C" {
6180CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6181 if (!clang_isDeclaration(cursor.kind))
6182 return CXLinkage_Invalid;
6183
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006184 const Decl *D = cxcursor::getCursorDecl(cursor);
6185 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006186 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006187 case NoLinkage:
6188 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006189 case InternalLinkage: return CXLinkage_Internal;
6190 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6191 case ExternalLinkage: return CXLinkage_External;
6192 };
6193
6194 return CXLinkage_Invalid;
6195}
6196} // end: extern "C"
6197
6198//===----------------------------------------------------------------------===//
6199// Operations for querying language of a cursor.
6200//===----------------------------------------------------------------------===//
6201
6202static CXLanguageKind getDeclLanguage(const Decl *D) {
6203 if (!D)
6204 return CXLanguage_C;
6205
6206 switch (D->getKind()) {
6207 default:
6208 break;
6209 case Decl::ImplicitParam:
6210 case Decl::ObjCAtDefsField:
6211 case Decl::ObjCCategory:
6212 case Decl::ObjCCategoryImpl:
6213 case Decl::ObjCCompatibleAlias:
6214 case Decl::ObjCImplementation:
6215 case Decl::ObjCInterface:
6216 case Decl::ObjCIvar:
6217 case Decl::ObjCMethod:
6218 case Decl::ObjCProperty:
6219 case Decl::ObjCPropertyImpl:
6220 case Decl::ObjCProtocol:
6221 return CXLanguage_ObjC;
6222 case Decl::CXXConstructor:
6223 case Decl::CXXConversion:
6224 case Decl::CXXDestructor:
6225 case Decl::CXXMethod:
6226 case Decl::CXXRecord:
6227 case Decl::ClassTemplate:
6228 case Decl::ClassTemplatePartialSpecialization:
6229 case Decl::ClassTemplateSpecialization:
6230 case Decl::Friend:
6231 case Decl::FriendTemplate:
6232 case Decl::FunctionTemplate:
6233 case Decl::LinkageSpec:
6234 case Decl::Namespace:
6235 case Decl::NamespaceAlias:
6236 case Decl::NonTypeTemplateParm:
6237 case Decl::StaticAssert:
6238 case Decl::TemplateTemplateParm:
6239 case Decl::TemplateTypeParm:
6240 case Decl::UnresolvedUsingTypename:
6241 case Decl::UnresolvedUsingValue:
6242 case Decl::Using:
6243 case Decl::UsingDirective:
6244 case Decl::UsingShadow:
6245 return CXLanguage_CPlusPlus;
6246 }
6247
6248 return CXLanguage_C;
6249}
6250
6251extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006252
6253static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6254 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6255 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006256
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006257 switch (D->getAvailability()) {
6258 case AR_Available:
6259 case AR_NotYetIntroduced:
6260 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006261 return getCursorAvailabilityForDecl(
6262 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006263 return CXAvailability_Available;
6264
6265 case AR_Deprecated:
6266 return CXAvailability_Deprecated;
6267
6268 case AR_Unavailable:
6269 return CXAvailability_NotAvailable;
6270 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006271
6272 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006273}
6274
Guy Benyei11169dd2012-12-18 14:30:41 +00006275enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6276 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006277 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6278 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006279
6280 return CXAvailability_Available;
6281}
6282
6283static CXVersion convertVersion(VersionTuple In) {
6284 CXVersion Out = { -1, -1, -1 };
6285 if (In.empty())
6286 return Out;
6287
6288 Out.Major = In.getMajor();
6289
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006290 Optional<unsigned> Minor = In.getMinor();
6291 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006292 Out.Minor = *Minor;
6293 else
6294 return Out;
6295
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006296 Optional<unsigned> Subminor = In.getSubminor();
6297 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006298 Out.Subminor = *Subminor;
6299
6300 return Out;
6301}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006302
6303static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6304 int *always_deprecated,
6305 CXString *deprecated_message,
6306 int *always_unavailable,
6307 CXString *unavailable_message,
6308 CXPlatformAvailability *availability,
6309 int availability_size) {
6310 bool HadAvailAttr = false;
6311 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006312 for (auto A : D->attrs()) {
6313 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006314 HadAvailAttr = true;
6315 if (always_deprecated)
6316 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006317 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006318 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006319 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006320 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006321 continue;
6322 }
6323
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006324 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006325 HadAvailAttr = true;
6326 if (always_unavailable)
6327 *always_unavailable = 1;
6328 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006329 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006330 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6331 }
6332 continue;
6333 }
6334
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006335 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006336 HadAvailAttr = true;
6337 if (N < availability_size) {
6338 availability[N].Platform
6339 = cxstring::createDup(Avail->getPlatform()->getName());
6340 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6341 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6342 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6343 availability[N].Unavailable = Avail->getUnavailable();
6344 availability[N].Message = cxstring::createDup(Avail->getMessage());
6345 }
6346 ++N;
6347 }
6348 }
6349
6350 if (!HadAvailAttr)
6351 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6352 return getCursorPlatformAvailabilityForDecl(
6353 cast<Decl>(EnumConst->getDeclContext()),
6354 always_deprecated,
6355 deprecated_message,
6356 always_unavailable,
6357 unavailable_message,
6358 availability,
6359 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006360
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006361 return N;
6362}
6363
Guy Benyei11169dd2012-12-18 14:30:41 +00006364int clang_getCursorPlatformAvailability(CXCursor cursor,
6365 int *always_deprecated,
6366 CXString *deprecated_message,
6367 int *always_unavailable,
6368 CXString *unavailable_message,
6369 CXPlatformAvailability *availability,
6370 int availability_size) {
6371 if (always_deprecated)
6372 *always_deprecated = 0;
6373 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006374 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006375 if (always_unavailable)
6376 *always_unavailable = 0;
6377 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006378 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006379
Guy Benyei11169dd2012-12-18 14:30:41 +00006380 if (!clang_isDeclaration(cursor.kind))
6381 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006382
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006383 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006384 if (!D)
6385 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006386
6387 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6388 deprecated_message,
6389 always_unavailable,
6390 unavailable_message,
6391 availability,
6392 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006393}
6394
6395void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6396 clang_disposeString(availability->Platform);
6397 clang_disposeString(availability->Message);
6398}
6399
6400CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6401 if (clang_isDeclaration(cursor.kind))
6402 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6403
6404 return CXLanguage_Invalid;
6405}
6406
6407 /// \brief If the given cursor is the "templated" declaration
6408 /// descibing a class or function template, return the class or
6409 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006410static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006411 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006412 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006413
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006414 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006415 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6416 return FunTmpl;
6417
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006418 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006419 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6420 return ClassTmpl;
6421
6422 return D;
6423}
6424
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006425
6426enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6427 StorageClass sc = SC_None;
6428 const Decl *D = getCursorDecl(C);
6429 if (D) {
6430 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6431 sc = FD->getStorageClass();
6432 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6433 sc = VD->getStorageClass();
6434 } else {
6435 return CX_SC_Invalid;
6436 }
6437 } else {
6438 return CX_SC_Invalid;
6439 }
6440 switch (sc) {
6441 case SC_None:
6442 return CX_SC_None;
6443 case SC_Extern:
6444 return CX_SC_Extern;
6445 case SC_Static:
6446 return CX_SC_Static;
6447 case SC_PrivateExtern:
6448 return CX_SC_PrivateExtern;
6449 case SC_OpenCLWorkGroupLocal:
6450 return CX_SC_OpenCLWorkGroupLocal;
6451 case SC_Auto:
6452 return CX_SC_Auto;
6453 case SC_Register:
6454 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006455 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006456 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006457}
6458
Guy Benyei11169dd2012-12-18 14:30:41 +00006459CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6460 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006461 if (const Decl *D = getCursorDecl(cursor)) {
6462 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006463 if (!DC)
6464 return clang_getNullCursor();
6465
6466 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6467 getCursorTU(cursor));
6468 }
6469 }
6470
6471 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006472 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006473 return MakeCXCursor(D, getCursorTU(cursor));
6474 }
6475
6476 return clang_getNullCursor();
6477}
6478
6479CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6480 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006481 if (const Decl *D = getCursorDecl(cursor)) {
6482 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006483 if (!DC)
6484 return clang_getNullCursor();
6485
6486 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6487 getCursorTU(cursor));
6488 }
6489 }
6490
6491 // FIXME: Note that we can't easily compute the lexical context of a
6492 // statement or expression, so we return nothing.
6493 return clang_getNullCursor();
6494}
6495
6496CXFile clang_getIncludedFile(CXCursor cursor) {
6497 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006498 return nullptr;
6499
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006500 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006501 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006502}
6503
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006504unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6505 if (C.kind != CXCursor_ObjCPropertyDecl)
6506 return CXObjCPropertyAttr_noattr;
6507
6508 unsigned Result = CXObjCPropertyAttr_noattr;
6509 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6510 ObjCPropertyDecl::PropertyAttributeKind Attr =
6511 PD->getPropertyAttributesAsWritten();
6512
6513#define SET_CXOBJCPROP_ATTR(A) \
6514 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6515 Result |= CXObjCPropertyAttr_##A
6516 SET_CXOBJCPROP_ATTR(readonly);
6517 SET_CXOBJCPROP_ATTR(getter);
6518 SET_CXOBJCPROP_ATTR(assign);
6519 SET_CXOBJCPROP_ATTR(readwrite);
6520 SET_CXOBJCPROP_ATTR(retain);
6521 SET_CXOBJCPROP_ATTR(copy);
6522 SET_CXOBJCPROP_ATTR(nonatomic);
6523 SET_CXOBJCPROP_ATTR(setter);
6524 SET_CXOBJCPROP_ATTR(atomic);
6525 SET_CXOBJCPROP_ATTR(weak);
6526 SET_CXOBJCPROP_ATTR(strong);
6527 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6528#undef SET_CXOBJCPROP_ATTR
6529
6530 return Result;
6531}
6532
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006533unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6534 if (!clang_isDeclaration(C.kind))
6535 return CXObjCDeclQualifier_None;
6536
6537 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6538 const Decl *D = getCursorDecl(C);
6539 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6540 QT = MD->getObjCDeclQualifier();
6541 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6542 QT = PD->getObjCDeclQualifier();
6543 if (QT == Decl::OBJC_TQ_None)
6544 return CXObjCDeclQualifier_None;
6545
6546 unsigned Result = CXObjCDeclQualifier_None;
6547 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6548 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6549 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6550 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6551 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6552 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6553
6554 return Result;
6555}
6556
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006557unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6558 if (!clang_isDeclaration(C.kind))
6559 return 0;
6560
6561 const Decl *D = getCursorDecl(C);
6562 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6563 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6564 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6565 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6566
6567 return 0;
6568}
6569
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006570unsigned clang_Cursor_isVariadic(CXCursor C) {
6571 if (!clang_isDeclaration(C.kind))
6572 return 0;
6573
6574 const Decl *D = getCursorDecl(C);
6575 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6576 return FD->isVariadic();
6577 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6578 return MD->isVariadic();
6579
6580 return 0;
6581}
6582
Guy Benyei11169dd2012-12-18 14:30:41 +00006583CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6584 if (!clang_isDeclaration(C.kind))
6585 return clang_getNullRange();
6586
6587 const Decl *D = getCursorDecl(C);
6588 ASTContext &Context = getCursorContext(C);
6589 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6590 if (!RC)
6591 return clang_getNullRange();
6592
6593 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6594}
6595
6596CXString clang_Cursor_getRawCommentText(CXCursor C) {
6597 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006598 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006599
6600 const Decl *D = getCursorDecl(C);
6601 ASTContext &Context = getCursorContext(C);
6602 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6603 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6604 StringRef();
6605
6606 // Don't duplicate the string because RawText points directly into source
6607 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006608 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006609}
6610
6611CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6612 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006613 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006614
6615 const Decl *D = getCursorDecl(C);
6616 const ASTContext &Context = getCursorContext(C);
6617 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6618
6619 if (RC) {
6620 StringRef BriefText = RC->getBriefText(Context);
6621
6622 // Don't duplicate the string because RawComment ensures that this memory
6623 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006624 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006625 }
6626
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006627 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006628}
6629
Guy Benyei11169dd2012-12-18 14:30:41 +00006630CXModule clang_Cursor_getModule(CXCursor C) {
6631 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006632 if (const ImportDecl *ImportD =
6633 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006634 return ImportD->getImportedModule();
6635 }
6636
Craig Topper69186e72014-06-08 08:38:04 +00006637 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006638}
6639
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006640CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6641 if (isNotUsableTU(TU)) {
6642 LOG_BAD_TU(TU);
6643 return nullptr;
6644 }
6645 if (!File)
6646 return nullptr;
6647 FileEntry *FE = static_cast<FileEntry *>(File);
6648
6649 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6650 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6651 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6652
6653 if (Module *Mod = Header.getModule()) {
6654 if (Header.getRole() != ModuleMap::ExcludedHeader)
6655 return Mod;
6656 }
6657 return nullptr;
6658}
6659
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006660CXFile clang_Module_getASTFile(CXModule CXMod) {
6661 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006662 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006663 Module *Mod = static_cast<Module*>(CXMod);
6664 return const_cast<FileEntry *>(Mod->getASTFile());
6665}
6666
Guy Benyei11169dd2012-12-18 14:30:41 +00006667CXModule clang_Module_getParent(CXModule CXMod) {
6668 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006669 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006670 Module *Mod = static_cast<Module*>(CXMod);
6671 return Mod->Parent;
6672}
6673
6674CXString clang_Module_getName(CXModule CXMod) {
6675 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006676 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006677 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006678 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006679}
6680
6681CXString clang_Module_getFullName(CXModule CXMod) {
6682 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006683 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006684 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006685 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006686}
6687
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006688int clang_Module_isSystem(CXModule CXMod) {
6689 if (!CXMod)
6690 return 0;
6691 Module *Mod = static_cast<Module*>(CXMod);
6692 return Mod->IsSystem;
6693}
6694
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006695unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6696 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006697 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006698 LOG_BAD_TU(TU);
6699 return 0;
6700 }
6701 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006702 return 0;
6703 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006704 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6705 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6706 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006707}
6708
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006709CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6710 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006711 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006712 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006713 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006714 }
6715 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006716 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006717 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006718 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006719
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006720 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6721 if (Index < TopHeaders.size())
6722 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006723
Craig Topper69186e72014-06-08 08:38:04 +00006724 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006725}
6726
6727} // end: extern "C"
6728
6729//===----------------------------------------------------------------------===//
6730// C++ AST instrospection.
6731//===----------------------------------------------------------------------===//
6732
6733extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006734unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6735 if (!clang_isDeclaration(C.kind))
6736 return 0;
6737
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006738 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006739 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006740 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006741 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6742}
6743
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006744unsigned clang_CXXMethod_isConst(CXCursor C) {
6745 if (!clang_isDeclaration(C.kind))
6746 return 0;
6747
6748 const Decl *D = cxcursor::getCursorDecl(C);
6749 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006750 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006751 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6752}
6753
Guy Benyei11169dd2012-12-18 14:30:41 +00006754unsigned clang_CXXMethod_isStatic(CXCursor C) {
6755 if (!clang_isDeclaration(C.kind))
6756 return 0;
6757
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006758 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006759 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006760 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006761 return (Method && Method->isStatic()) ? 1 : 0;
6762}
6763
6764unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6765 if (!clang_isDeclaration(C.kind))
6766 return 0;
6767
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006768 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006769 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006770 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006771 return (Method && Method->isVirtual()) ? 1 : 0;
6772}
6773} // end: extern "C"
6774
6775//===----------------------------------------------------------------------===//
6776// Attribute introspection.
6777//===----------------------------------------------------------------------===//
6778
6779extern "C" {
6780CXType clang_getIBOutletCollectionType(CXCursor C) {
6781 if (C.kind != CXCursor_IBOutletCollectionAttr)
6782 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6783
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006784 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006785 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6786
6787 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6788}
6789} // end: extern "C"
6790
6791//===----------------------------------------------------------------------===//
6792// Inspecting memory usage.
6793//===----------------------------------------------------------------------===//
6794
6795typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6796
6797static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6798 enum CXTUResourceUsageKind k,
6799 unsigned long amount) {
6800 CXTUResourceUsageEntry entry = { k, amount };
6801 entries.push_back(entry);
6802}
6803
6804extern "C" {
6805
6806const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6807 const char *str = "";
6808 switch (kind) {
6809 case CXTUResourceUsage_AST:
6810 str = "ASTContext: expressions, declarations, and types";
6811 break;
6812 case CXTUResourceUsage_Identifiers:
6813 str = "ASTContext: identifiers";
6814 break;
6815 case CXTUResourceUsage_Selectors:
6816 str = "ASTContext: selectors";
6817 break;
6818 case CXTUResourceUsage_GlobalCompletionResults:
6819 str = "Code completion: cached global results";
6820 break;
6821 case CXTUResourceUsage_SourceManagerContentCache:
6822 str = "SourceManager: content cache allocator";
6823 break;
6824 case CXTUResourceUsage_AST_SideTables:
6825 str = "ASTContext: side tables";
6826 break;
6827 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6828 str = "SourceManager: malloc'ed memory buffers";
6829 break;
6830 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6831 str = "SourceManager: mmap'ed memory buffers";
6832 break;
6833 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6834 str = "ExternalASTSource: malloc'ed memory buffers";
6835 break;
6836 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6837 str = "ExternalASTSource: mmap'ed memory buffers";
6838 break;
6839 case CXTUResourceUsage_Preprocessor:
6840 str = "Preprocessor: malloc'ed memory";
6841 break;
6842 case CXTUResourceUsage_PreprocessingRecord:
6843 str = "Preprocessor: PreprocessingRecord";
6844 break;
6845 case CXTUResourceUsage_SourceManager_DataStructures:
6846 str = "SourceManager: data structures and tables";
6847 break;
6848 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6849 str = "Preprocessor: header search tables";
6850 break;
6851 }
6852 return str;
6853}
6854
6855CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006856 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006857 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006858 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006859 return usage;
6860 }
6861
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006862 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006863 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006864 ASTContext &astContext = astUnit->getASTContext();
6865
6866 // How much memory is used by AST nodes and types?
6867 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6868 (unsigned long) astContext.getASTAllocatedMemory());
6869
6870 // How much memory is used by identifiers?
6871 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6872 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6873
6874 // How much memory is used for selectors?
6875 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6876 (unsigned long) astContext.Selectors.getTotalMemory());
6877
6878 // How much memory is used by ASTContext's side tables?
6879 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6880 (unsigned long) astContext.getSideTableAllocatedMemory());
6881
6882 // How much memory is used for caching global code completion results?
6883 unsigned long completionBytes = 0;
6884 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006885 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006886 completionBytes = completionAllocator->getTotalMemory();
6887 }
6888 createCXTUResourceUsageEntry(*entries,
6889 CXTUResourceUsage_GlobalCompletionResults,
6890 completionBytes);
6891
6892 // How much memory is being used by SourceManager's content cache?
6893 createCXTUResourceUsageEntry(*entries,
6894 CXTUResourceUsage_SourceManagerContentCache,
6895 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6896
6897 // How much memory is being used by the MemoryBuffer's in SourceManager?
6898 const SourceManager::MemoryBufferSizes &srcBufs =
6899 astUnit->getSourceManager().getMemoryBufferSizes();
6900
6901 createCXTUResourceUsageEntry(*entries,
6902 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6903 (unsigned long) srcBufs.malloc_bytes);
6904 createCXTUResourceUsageEntry(*entries,
6905 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6906 (unsigned long) srcBufs.mmap_bytes);
6907 createCXTUResourceUsageEntry(*entries,
6908 CXTUResourceUsage_SourceManager_DataStructures,
6909 (unsigned long) astContext.getSourceManager()
6910 .getDataStructureSizes());
6911
6912 // How much memory is being used by the ExternalASTSource?
6913 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6914 const ExternalASTSource::MemoryBufferSizes &sizes =
6915 esrc->getMemoryBufferSizes();
6916
6917 createCXTUResourceUsageEntry(*entries,
6918 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6919 (unsigned long) sizes.malloc_bytes);
6920 createCXTUResourceUsageEntry(*entries,
6921 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6922 (unsigned long) sizes.mmap_bytes);
6923 }
6924
6925 // How much memory is being used by the Preprocessor?
6926 Preprocessor &pp = astUnit->getPreprocessor();
6927 createCXTUResourceUsageEntry(*entries,
6928 CXTUResourceUsage_Preprocessor,
6929 pp.getTotalMemory());
6930
6931 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6932 createCXTUResourceUsageEntry(*entries,
6933 CXTUResourceUsage_PreprocessingRecord,
6934 pRec->getTotalMemory());
6935 }
6936
6937 createCXTUResourceUsageEntry(*entries,
6938 CXTUResourceUsage_Preprocessor_HeaderSearch,
6939 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006940
Guy Benyei11169dd2012-12-18 14:30:41 +00006941 CXTUResourceUsage usage = { (void*) entries.get(),
6942 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006943 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006944 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006945 return usage;
6946}
6947
6948void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6949 if (usage.data)
6950 delete (MemUsageEntries*) usage.data;
6951}
6952
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006953CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6954 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006955 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006956 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006957
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006958 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006959 LOG_BAD_TU(TU);
6960 return skipped;
6961 }
6962
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006963 if (!file)
6964 return skipped;
6965
6966 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6967 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6968 if (!ppRec)
6969 return skipped;
6970
6971 ASTContext &Ctx = astUnit->getASTContext();
6972 SourceManager &sm = Ctx.getSourceManager();
6973 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6974 FileID wantedFileID = sm.translateFile(fileEntry);
6975
6976 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6977 std::vector<SourceRange> wantedRanges;
6978 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6979 i != ei; ++i) {
6980 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6981 wantedRanges.push_back(*i);
6982 }
6983
6984 skipped->count = wantedRanges.size();
6985 skipped->ranges = new CXSourceRange[skipped->count];
6986 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6987 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6988
6989 return skipped;
6990}
6991
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006992void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6993 if (ranges) {
6994 delete[] ranges->ranges;
6995 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006996 }
6997}
6998
Guy Benyei11169dd2012-12-18 14:30:41 +00006999} // end extern "C"
7000
7001void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7002 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7003 for (unsigned I = 0; I != Usage.numEntries; ++I)
7004 fprintf(stderr, " %s: %lu\n",
7005 clang_getTUResourceUsageName(Usage.entries[I].kind),
7006 Usage.entries[I].amount);
7007
7008 clang_disposeCXTUResourceUsage(Usage);
7009}
7010
7011//===----------------------------------------------------------------------===//
7012// Misc. utility functions.
7013//===----------------------------------------------------------------------===//
7014
7015/// Default to using an 8 MB stack size on "safety" threads.
7016static unsigned SafetyStackThreadSize = 8 << 20;
7017
7018namespace clang {
7019
7020bool RunSafely(llvm::CrashRecoveryContext &CRC,
7021 void (*Fn)(void*), void *UserData,
7022 unsigned Size) {
7023 if (!Size)
7024 Size = GetSafetyThreadStackSize();
7025 if (Size)
7026 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7027 return CRC.RunSafely(Fn, UserData);
7028}
7029
7030unsigned GetSafetyThreadStackSize() {
7031 return SafetyStackThreadSize;
7032}
7033
7034void SetSafetyThreadStackSize(unsigned Value) {
7035 SafetyStackThreadSize = Value;
7036}
7037
7038}
7039
7040void clang::setThreadBackgroundPriority() {
7041 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7042 return;
7043
Alp Toker1a86ad22014-07-06 06:24:00 +00007044#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007045 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7046#endif
7047}
7048
7049void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7050 if (!Unit)
7051 return;
7052
7053 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7054 DEnd = Unit->stored_diag_end();
7055 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007056 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007057 CXString Msg = clang_formatDiagnostic(&Diag,
7058 clang_defaultDiagnosticDisplayOptions());
7059 fprintf(stderr, "%s\n", clang_getCString(Msg));
7060 clang_disposeString(Msg);
7061 }
7062#ifdef LLVM_ON_WIN32
7063 // On Windows, force a flush, since there may be multiple copies of
7064 // stderr and stdout in the file system, all with different buffers
7065 // but writing to the same device.
7066 fflush(stderr);
7067#endif
7068}
7069
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007070MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7071 SourceLocation MacroDefLoc,
7072 CXTranslationUnit TU){
7073 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007074 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007075 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007076 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007077
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007078 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007079 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007080 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007081 if (MD) {
7082 for (MacroDirective::DefInfo
7083 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7084 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7085 return Def.getMacroInfo();
7086 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007087 }
7088
Craig Topper69186e72014-06-08 08:38:04 +00007089 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007090}
7091
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007092const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7093 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007094 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007095 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007096 const IdentifierInfo *II = MacroDef->getName();
7097 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007098 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007099
7100 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7101}
7102
7103MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7104 const Token &Tok,
7105 CXTranslationUnit TU) {
7106 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007107 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007108 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007109 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007110
7111 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007112 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007113 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7114 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007115 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007116
7117 // Check that the token is inside the definition and not its argument list.
7118 SourceManager &SM = Unit->getSourceManager();
7119 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007120 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007121 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007122 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007123
7124 Preprocessor &PP = Unit->getPreprocessor();
7125 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7126 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007127 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007128
Alp Toker2d57cea2014-05-17 04:53:25 +00007129 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007130 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007131 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007132
7133 // Check that the identifier is not one of the macro arguments.
7134 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007135 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007136
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007137 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7138 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007139 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007140
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007141 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007142}
7143
7144MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7145 SourceLocation Loc,
7146 CXTranslationUnit TU) {
7147 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007148 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007149
7150 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007151 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007152 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007153 Preprocessor &PP = Unit->getPreprocessor();
7154 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007155 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007156 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7157 Token Tok;
7158 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007159 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007160
7161 return checkForMacroInMacroDefinition(MI, Tok, TU);
7162}
7163
Guy Benyei11169dd2012-12-18 14:30:41 +00007164extern "C" {
7165
7166CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007167 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007168}
7169
7170} // end: extern "C"
7171
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007172Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7173 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007174 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007175 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007176 if (Unit->isMainFileAST())
7177 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007178 return *this;
7179 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007180 } else {
7181 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007182 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007183 return *this;
7184}
7185
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007186Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7187 *this << FE->getName();
7188 return *this;
7189}
7190
7191Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7192 CXString cursorName = clang_getCursorDisplayName(cursor);
7193 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7194 clang_disposeString(cursorName);
7195 return *this;
7196}
7197
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007198Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7199 CXFile File;
7200 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007201 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007202 CXString FileName = clang_getFileName(File);
7203 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7204 clang_disposeString(FileName);
7205 return *this;
7206}
7207
7208Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7209 CXSourceLocation BLoc = clang_getRangeStart(range);
7210 CXSourceLocation ELoc = clang_getRangeEnd(range);
7211
7212 CXFile BFile;
7213 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007214 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007215
7216 CXFile EFile;
7217 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007218 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007219
7220 CXString BFileName = clang_getFileName(BFile);
7221 if (BFile == EFile) {
7222 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7223 BLine, BColumn, ELine, EColumn);
7224 } else {
7225 CXString EFileName = clang_getFileName(EFile);
7226 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7227 BLine, BColumn)
7228 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7229 ELine, EColumn);
7230 clang_disposeString(EFileName);
7231 }
7232 clang_disposeString(BFileName);
7233 return *this;
7234}
7235
7236Logger &cxindex::Logger::operator<<(CXString Str) {
7237 *this << clang_getCString(Str);
7238 return *this;
7239}
7240
7241Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7242 LogOS << Fmt;
7243 return *this;
7244}
7245
Chandler Carruth37ad2582014-06-27 15:14:39 +00007246static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7247
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007248cxindex::Logger::~Logger() {
7249 LogOS.flush();
7250
Chandler Carruth37ad2582014-06-27 15:14:39 +00007251 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007252
7253 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7254
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007255 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007256 OS << "[libclang:" << Name << ':';
7257
Alp Toker1a86ad22014-07-06 06:24:00 +00007258#ifdef USE_DARWIN_THREADS
7259 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007260 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7261 OS << tid << ':';
7262#endif
7263
7264 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7265 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7266 OS << Msg.str() << '\n';
7267
7268 if (Trace) {
7269 llvm::sys::PrintStackTrace(stderr);
7270 OS << "--------------------------------------------------\n";
7271 }
7272}