blob: eab289206e105148fa37fa2d7e0b5e40f2942ef6 [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) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002007 for (const auto *I : Node->varlists())
2008 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00002009}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002010
2011void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002012 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002013}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002014void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2015 const OMPFirstprivateClause *C) {
2016 VisitOMPClauseList(C);
2017}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002018void OMPClauseEnqueue::VisitOMPLastprivateClause(
2019 const OMPLastprivateClause *C) {
2020 VisitOMPClauseList(C);
2021}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002022void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002023 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002024}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002025void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2026 VisitOMPClauseList(C);
2027}
Alexander Musman8dba6642014-04-22 13:09:42 +00002028void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2029 VisitOMPClauseList(C);
2030 Visitor->AddStmt(C->getStep());
2031}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002032void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2033 VisitOMPClauseList(C);
2034 Visitor->AddStmt(C->getAlignment());
2035}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002036void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2037 VisitOMPClauseList(C);
2038}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002039void
2040OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2041 VisitOMPClauseList(C);
2042}
Alexey Bataev6125da92014-07-21 11:26:11 +00002043void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2044 VisitOMPClauseList(C);
2045}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002046}
Alexey Bataev756c1962013-09-24 03:17:45 +00002047
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002048void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2049 unsigned size = WL.size();
2050 OMPClauseEnqueue Visitor(this);
2051 Visitor.Visit(S);
2052 if (size == WL.size())
2053 return;
2054 // Now reverse the entries we just added. This will match the DFS
2055 // ordering performed by the worklist.
2056 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2057 std::reverse(I, E);
2058}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2061}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002063 AddDecl(B->getBlockDecl());
2064}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 EnqueueChildren(E);
2067 AddTypeLoc(E->getTypeSourceInfo());
2068}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2070 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002071 E = S->body_rend(); I != E; ++I) {
2072 AddStmt(*I);
2073 }
2074}
2075void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002076VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002077 AddStmt(S->getSubStmt());
2078 AddDeclarationNameInfo(S);
2079 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2080 AddNestedNameSpecifierLoc(QualifierLoc);
2081}
2082
2083void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002084VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002085 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2086 AddDeclarationNameInfo(E);
2087 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2088 AddNestedNameSpecifierLoc(QualifierLoc);
2089 if (!E->isImplicitAccess())
2090 AddStmt(E->getBase());
2091}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002093 // Enqueue the initializer , if any.
2094 AddStmt(E->getInitializer());
2095 // Enqueue the array size, if any.
2096 AddStmt(E->getArraySize());
2097 // Enqueue the allocated type.
2098 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2099 // Enqueue the placement arguments.
2100 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2101 AddStmt(E->getPlacementArg(I-1));
2102}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002103void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002104 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2105 AddStmt(CE->getArg(I-1));
2106 AddStmt(CE->getCallee());
2107 AddStmt(CE->getArg(0));
2108}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2110 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 // Visit the name of the type being destroyed.
2112 AddTypeLoc(E->getDestroyedTypeInfo());
2113 // Visit the scope type that looks disturbingly like the nested-name-specifier
2114 // but isn't.
2115 AddTypeLoc(E->getScopeTypeInfo());
2116 // Visit the nested-name-specifier.
2117 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2118 AddNestedNameSpecifierLoc(QualifierLoc);
2119 // Visit base expression.
2120 AddStmt(E->getBase());
2121}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2123 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 AddTypeLoc(E->getTypeSourceInfo());
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2127 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 EnqueueChildren(E);
2129 AddTypeLoc(E->getTypeSourceInfo());
2130}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 EnqueueChildren(E);
2133 if (E->isTypeOperand())
2134 AddTypeLoc(E->getTypeOperandSourceInfo());
2135}
2136
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2138 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 EnqueueChildren(E);
2140 AddTypeLoc(E->getTypeSourceInfo());
2141}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 EnqueueChildren(E);
2144 if (E->isTypeOperand())
2145 AddTypeLoc(E->getTypeOperandSourceInfo());
2146}
2147
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002149 EnqueueChildren(S);
2150 AddDecl(S->getExceptionDecl());
2151}
2152
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 if (DR->hasExplicitTemplateArgs()) {
2155 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2156 }
2157 WL.push_back(DeclRefExprParts(DR, Parent));
2158}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002159void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2160 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002161 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2162 AddDeclarationNameInfo(E);
2163 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2164}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002165void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002166 unsigned size = WL.size();
2167 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002168 for (const auto *D : S->decls()) {
2169 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002170 isFirst = false;
2171 }
2172 if (size == WL.size())
2173 return;
2174 // Now reverse the entries we just added. This will match the DFS
2175 // ordering performed by the worklist.
2176 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2177 std::reverse(I, E);
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 D = E->designators_rbegin(), DEnd = E->designators_rend();
2183 D != DEnd; ++D) {
2184 if (D->isFieldDesignator()) {
2185 if (FieldDecl *Field = D->getField())
2186 AddMemberRef(Field, D->getFieldLoc());
2187 continue;
2188 }
2189 if (D->isArrayDesignator()) {
2190 AddStmt(E->getArrayIndex(*D));
2191 continue;
2192 }
2193 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2194 AddStmt(E->getArrayRangeEnd(*D));
2195 AddStmt(E->getArrayRangeStart(*D));
2196 }
2197}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 EnqueueChildren(E);
2200 AddTypeLoc(E->getTypeInfoAsWritten());
2201}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 AddStmt(FS->getBody());
2204 AddStmt(FS->getInc());
2205 AddStmt(FS->getCond());
2206 AddDecl(FS->getConditionVariable());
2207 AddStmt(FS->getInit());
2208}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2211}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 AddStmt(If->getElse());
2214 AddStmt(If->getThen());
2215 AddStmt(If->getCond());
2216 AddDecl(If->getConditionVariable());
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 // We care about the syntactic form of the initializer list, only.
2220 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2221 IE = Syntactic;
2222 EnqueueChildren(IE);
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 WL.push_back(MemberExprParts(M, Parent));
2226
2227 // If the base of the member access expression is an implicit 'this', don't
2228 // visit it.
2229 // FIXME: If we ever want to show these implicit accesses, this will be
2230 // unfortunate. However, clang_getCursor() relies on this behavior.
2231 if (!M->isImplicitAccess())
2232 AddStmt(M->getBase());
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 AddTypeLoc(E->getEncodedTypeSourceInfo());
2236}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002238 EnqueueChildren(M);
2239 AddTypeLoc(M->getClassReceiverTypeInfo());
2240}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002241void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002242 // Visit the components of the offsetof expression.
2243 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2244 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2245 const OffsetOfNode &Node = E->getComponent(I-1);
2246 switch (Node.getKind()) {
2247 case OffsetOfNode::Array:
2248 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2249 break;
2250 case OffsetOfNode::Field:
2251 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2252 break;
2253 case OffsetOfNode::Identifier:
2254 case OffsetOfNode::Base:
2255 continue;
2256 }
2257 }
2258 // Visit the type into which we're computing the offset.
2259 AddTypeLoc(E->getTypeSourceInfo());
2260}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2263 WL.push_back(OverloadExprParts(E, Parent));
2264}
2265void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002266 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002267 EnqueueChildren(E);
2268 if (E->isArgumentType())
2269 AddTypeLoc(E->getArgumentTypeInfo());
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 EnqueueChildren(S);
2273}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 AddStmt(S->getBody());
2276 AddStmt(S->getCond());
2277 AddDecl(S->getConditionVariable());
2278}
2279
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 AddStmt(W->getBody());
2282 AddStmt(W->getCond());
2283 AddDecl(W->getConditionVariable());
2284}
2285
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 for (unsigned I = E->getNumArgs(); I > 0; --I)
2288 AddTypeLoc(E->getArg(I-1));
2289}
2290
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 AddTypeLoc(E->getQueriedTypeSourceInfo());
2293}
2294
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002295void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002296 EnqueueChildren(E);
2297}
2298
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002299void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002300 VisitOverloadExpr(U);
2301 if (!U->isImplicitAccess())
2302 AddStmt(U->getBase());
2303}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002304void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002305 AddStmt(E->getSubExpr());
2306 AddTypeLoc(E->getWrittenTypeInfo());
2307}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 WL.push_back(SizeOfPackExprParts(E, Parent));
2310}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002311void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 // If the opaque value has a source expression, just transparently
2313 // visit that. This is useful for (e.g.) pseudo-object expressions.
2314 if (Expr *SourceExpr = E->getSourceExpr())
2315 return Visit(SourceExpr);
2316}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002317void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002318 AddStmt(E->getBody());
2319 WL.push_back(LambdaExprParts(E, Parent));
2320}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002321void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002322 // Treat the expression like its syntactic form.
2323 Visit(E->getSyntacticForm());
2324}
2325
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002326void EnqueueVisitor::VisitOMPExecutableDirective(
2327 const OMPExecutableDirective *D) {
2328 EnqueueChildren(D);
2329 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2330 E = D->clauses().end();
2331 I != E; ++I)
2332 EnqueueChildren(*I);
2333}
2334
Alexander Musman3aaab662014-08-19 11:27:13 +00002335void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2336 VisitOMPExecutableDirective(D);
2337}
2338
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002339void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2340 VisitOMPExecutableDirective(D);
2341}
2342
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002343void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002344 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002345}
2346
Alexey Bataevf29276e2014-06-18 04:14:57 +00002347void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002348 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002349}
2350
Alexander Musmanf82886e2014-09-18 05:12:34 +00002351void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2352 VisitOMPLoopDirective(D);
2353}
2354
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002355void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2356 VisitOMPExecutableDirective(D);
2357}
2358
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002359void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2360 VisitOMPExecutableDirective(D);
2361}
2362
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002363void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2364 VisitOMPExecutableDirective(D);
2365}
2366
Alexander Musman80c22892014-07-17 08:54:58 +00002367void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2368 VisitOMPExecutableDirective(D);
2369}
2370
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002371void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2372 VisitOMPExecutableDirective(D);
2373 AddDeclarationNameInfo(D);
2374}
2375
Alexey Bataev4acb8592014-07-07 13:01:15 +00002376void
2377EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002378 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002379}
2380
Alexander Musmane4e893b2014-09-23 09:33:00 +00002381void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2382 const OMPParallelForSimdDirective *D) {
2383 VisitOMPLoopDirective(D);
2384}
2385
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002386void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2387 const OMPParallelSectionsDirective *D) {
2388 VisitOMPExecutableDirective(D);
2389}
2390
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002391void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2392 VisitOMPExecutableDirective(D);
2393}
2394
Alexey Bataev68446b72014-07-18 07:47:19 +00002395void
2396EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2397 VisitOMPExecutableDirective(D);
2398}
2399
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002400void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2401 VisitOMPExecutableDirective(D);
2402}
2403
Alexey Bataev2df347a2014-07-18 10:17:07 +00002404void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2405 VisitOMPExecutableDirective(D);
2406}
2407
Alexey Bataev6125da92014-07-21 11:26:11 +00002408void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2409 VisitOMPExecutableDirective(D);
2410}
2411
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002412void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2413 VisitOMPExecutableDirective(D);
2414}
2415
Alexey Bataev0162e452014-07-22 10:10:35 +00002416void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2417 VisitOMPExecutableDirective(D);
2418}
2419
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002420void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2421 VisitOMPExecutableDirective(D);
2422}
2423
Alexey Bataev13314bf2014-10-09 04:18:56 +00002424void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2425 VisitOMPExecutableDirective(D);
2426}
2427
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002428void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002429 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2430}
2431
2432bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2433 if (RegionOfInterest.isValid()) {
2434 SourceRange Range = getRawCursorExtent(C);
2435 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2436 return false;
2437 }
2438 return true;
2439}
2440
2441bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2442 while (!WL.empty()) {
2443 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002444 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002445
2446 // Set the Parent field, then back to its old value once we're done.
2447 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2448
2449 switch (LI.getKind()) {
2450 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002451 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 if (!D)
2453 continue;
2454
2455 // For now, perform default visitation for Decls.
2456 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2457 cast<DeclVisit>(&LI)->isFirst())))
2458 return true;
2459
2460 continue;
2461 }
2462 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2463 const ASTTemplateArgumentListInfo *ArgList =
2464 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2465 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2466 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2467 Arg != ArgEnd; ++Arg) {
2468 if (VisitTemplateArgumentLoc(*Arg))
2469 return true;
2470 }
2471 continue;
2472 }
2473 case VisitorJob::TypeLocVisitKind: {
2474 // Perform default visitation for TypeLocs.
2475 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2476 return true;
2477 continue;
2478 }
2479 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002480 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002481 if (LabelStmt *stmt = LS->getStmt()) {
2482 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2483 TU))) {
2484 return true;
2485 }
2486 }
2487 continue;
2488 }
2489
2490 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2491 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2492 if (VisitNestedNameSpecifierLoc(V->get()))
2493 return true;
2494 continue;
2495 }
2496
2497 case VisitorJob::DeclarationNameInfoVisitKind: {
2498 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2499 ->get()))
2500 return true;
2501 continue;
2502 }
2503 case VisitorJob::MemberRefVisitKind: {
2504 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2505 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2506 return true;
2507 continue;
2508 }
2509 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002510 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002511 if (!S)
2512 continue;
2513
2514 // Update the current cursor.
2515 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2516 if (!IsInRegionOfInterest(Cursor))
2517 continue;
2518 switch (Visitor(Cursor, Parent, ClientData)) {
2519 case CXChildVisit_Break: return true;
2520 case CXChildVisit_Continue: break;
2521 case CXChildVisit_Recurse:
2522 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002523 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002524 EnqueueWorkList(WL, S);
2525 break;
2526 }
2527 continue;
2528 }
2529 case VisitorJob::MemberExprPartsKind: {
2530 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002531 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002532
2533 // Visit the nested-name-specifier
2534 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2535 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2536 return true;
2537
2538 // Visit the declaration name.
2539 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2540 return true;
2541
2542 // Visit the explicitly-specified template arguments, if any.
2543 if (M->hasExplicitTemplateArgs()) {
2544 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2545 *ArgEnd = Arg + M->getNumTemplateArgs();
2546 Arg != ArgEnd; ++Arg) {
2547 if (VisitTemplateArgumentLoc(*Arg))
2548 return true;
2549 }
2550 }
2551 continue;
2552 }
2553 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002554 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002555 // Visit nested-name-specifier, if present.
2556 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2557 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2558 return true;
2559 // Visit declaration name.
2560 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2561 return true;
2562 continue;
2563 }
2564 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002565 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002566 // Visit the nested-name-specifier.
2567 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2568 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2569 return true;
2570 // Visit the declaration name.
2571 if (VisitDeclarationNameInfo(O->getNameInfo()))
2572 return true;
2573 // Visit the overloaded declaration reference.
2574 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2575 return true;
2576 continue;
2577 }
2578 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002579 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002580 NamedDecl *Pack = E->getPack();
2581 if (isa<TemplateTypeParmDecl>(Pack)) {
2582 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2583 E->getPackLoc(), TU)))
2584 return true;
2585
2586 continue;
2587 }
2588
2589 if (isa<TemplateTemplateParmDecl>(Pack)) {
2590 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2591 E->getPackLoc(), TU)))
2592 return true;
2593
2594 continue;
2595 }
2596
2597 // Non-type template parameter packs and function parameter packs are
2598 // treated like DeclRefExpr cursors.
2599 continue;
2600 }
2601
2602 case VisitorJob::LambdaExprPartsKind: {
2603 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002604 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002605 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2606 CEnd = E->explicit_capture_end();
2607 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002608 // FIXME: Lambda init-captures.
2609 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002610 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002611
Guy Benyei11169dd2012-12-18 14:30:41 +00002612 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2613 C->getLocation(),
2614 TU)))
2615 return true;
2616 }
2617
2618 // Visit parameters and return type, if present.
2619 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2620 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2621 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2622 // Visit the whole type.
2623 if (Visit(TL))
2624 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002625 } else if (FunctionProtoTypeLoc Proto =
2626 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002627 if (E->hasExplicitParameters()) {
2628 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002629 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2630 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002631 return true;
2632 } else {
2633 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002634 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002635 return true;
2636 }
2637 }
2638 }
2639 break;
2640 }
2641
2642 case VisitorJob::PostChildrenVisitKind:
2643 if (PostChildrenVisitor(Parent, ClientData))
2644 return true;
2645 break;
2646 }
2647 }
2648 return false;
2649}
2650
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002651bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002652 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002653 if (!WorkListFreeList.empty()) {
2654 WL = WorkListFreeList.back();
2655 WL->clear();
2656 WorkListFreeList.pop_back();
2657 }
2658 else {
2659 WL = new VisitorWorkList();
2660 WorkListCache.push_back(WL);
2661 }
2662 EnqueueWorkList(*WL, S);
2663 bool result = RunVisitorWorkList(*WL);
2664 WorkListFreeList.push_back(WL);
2665 return result;
2666}
2667
2668namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002669typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002670RefNamePieces
2671buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2672 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2673 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002674 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2675 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2676 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2677
2678 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2679
2680 RefNamePieces Pieces;
2681
2682 if (WantQualifier && QLoc.isValid())
2683 Pieces.push_back(QLoc);
2684
2685 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2686 Pieces.push_back(NI.getLoc());
2687
2688 if (WantTemplateArgs && TemplateArgs)
2689 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2690 TemplateArgs->RAngleLoc));
2691
2692 if (Kind == DeclarationName::CXXOperatorName) {
2693 Pieces.push_back(SourceLocation::getFromRawEncoding(
2694 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2695 Pieces.push_back(SourceLocation::getFromRawEncoding(
2696 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2697 }
2698
2699 if (WantSinglePiece) {
2700 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2701 Pieces.clear();
2702 Pieces.push_back(R);
2703 }
2704
2705 return Pieces;
2706}
2707}
2708
2709//===----------------------------------------------------------------------===//
2710// Misc. API hooks.
2711//===----------------------------------------------------------------------===//
2712
Chad Rosier05c71aa2013-03-27 18:28:23 +00002713static void fatal_error_handler(void *user_data, const std::string& reason,
2714 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002715 // Write the result out to stderr avoiding errs() because raw_ostreams can
2716 // call report_fatal_error.
2717 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2718 ::abort();
2719}
2720
Chandler Carruth66660742014-06-27 16:37:27 +00002721namespace {
2722struct RegisterFatalErrorHandler {
2723 RegisterFatalErrorHandler() {
2724 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2725 }
2726};
2727}
2728
2729static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2730
Guy Benyei11169dd2012-12-18 14:30:41 +00002731extern "C" {
2732CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2733 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002734 // We use crash recovery to make some of our APIs more reliable, implicitly
2735 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002736 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2737 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002738
Chandler Carruth66660742014-06-27 16:37:27 +00002739 // Look through the managed static to trigger construction of the managed
2740 // static which registers our fatal error handler. This ensures it is only
2741 // registered once.
2742 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002743
2744 CIndexer *CIdxr = new CIndexer();
2745 if (excludeDeclarationsFromPCH)
2746 CIdxr->setOnlyLocalDecls();
2747 if (displayDiagnostics)
2748 CIdxr->setDisplayDiagnostics();
2749
2750 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2751 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2752 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2753 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2754 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2755 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2756
2757 return CIdxr;
2758}
2759
2760void clang_disposeIndex(CXIndex CIdx) {
2761 if (CIdx)
2762 delete static_cast<CIndexer *>(CIdx);
2763}
2764
2765void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2766 if (CIdx)
2767 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2768}
2769
2770unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2771 if (CIdx)
2772 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2773 return 0;
2774}
2775
2776void clang_toggleCrashRecovery(unsigned isEnabled) {
2777 if (isEnabled)
2778 llvm::CrashRecoveryContext::Enable();
2779 else
2780 llvm::CrashRecoveryContext::Disable();
2781}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002782
Guy Benyei11169dd2012-12-18 14:30:41 +00002783CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2784 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002785 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002786 enum CXErrorCode Result =
2787 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002788 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002789 assert((TU && Result == CXError_Success) ||
2790 (!TU && Result != CXError_Success));
2791 return TU;
2792}
2793
2794enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2795 const char *ast_filename,
2796 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002797 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002798 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002799
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002800 if (!CIdx || !ast_filename || !out_TU)
2801 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002802
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002803 LOG_FUNC_SECTION {
2804 *Log << ast_filename;
2805 }
2806
Guy Benyei11169dd2012-12-18 14:30:41 +00002807 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2808 FileSystemOptions FileSystemOpts;
2809
2810 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
David Blaikie6f7382d2014-08-10 19:08:04 +00002811 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2812 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2813 /*CaptureDiagnostics=*/true,
2814 /*AllowPCHWithCompilerErrors=*/true,
2815 /*UserFilesAreVolatile=*/true);
2816 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002817 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002818}
2819
2820unsigned clang_defaultEditingTranslationUnitOptions() {
2821 return CXTranslationUnit_PrecompiledPreamble |
2822 CXTranslationUnit_CacheCompletionResults;
2823}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002824
Guy Benyei11169dd2012-12-18 14:30:41 +00002825CXTranslationUnit
2826clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2827 const char *source_filename,
2828 int num_command_line_args,
2829 const char * const *command_line_args,
2830 unsigned num_unsaved_files,
2831 struct CXUnsavedFile *unsaved_files) {
2832 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2833 return clang_parseTranslationUnit(CIdx, source_filename,
2834 command_line_args, num_command_line_args,
2835 unsaved_files, num_unsaved_files,
2836 Options);
2837}
2838
2839struct ParseTranslationUnitInfo {
2840 CXIndex CIdx;
2841 const char *source_filename;
2842 const char *const *command_line_args;
2843 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002844 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002845 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002846 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002847 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002848};
2849static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002850 const ParseTranslationUnitInfo *PTUI =
2851 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002852 CXIndex CIdx = PTUI->CIdx;
2853 const char *source_filename = PTUI->source_filename;
2854 const char * const *command_line_args = PTUI->command_line_args;
2855 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002857 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002858
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002859 // Set up the initial return values.
2860 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002861 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002862
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002863 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002864 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002865 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002866 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002867 }
2868
Guy Benyei11169dd2012-12-18 14:30:41 +00002869 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2870
2871 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2872 setThreadBackgroundPriority();
2873
2874 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2875 // FIXME: Add a flag for modules.
2876 TranslationUnitKind TUKind
2877 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002878 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002879 = options & CXTranslationUnit_CacheCompletionResults;
2880 bool IncludeBriefCommentsInCodeCompletion
2881 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2882 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2883 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2884
2885 // Configure the diagnostics.
2886 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002887 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002888
2889 // Recover resources if we crash before exiting this function.
2890 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2891 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002892 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002893
Ahmed Charlesb8984322014-03-07 20:03:18 +00002894 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2895 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002896
2897 // Recover resources if we crash before exiting this function.
2898 llvm::CrashRecoveryContextCleanupRegistrar<
2899 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2900
Alp Toker9d85b182014-07-07 01:23:14 +00002901 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002902 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002903 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002904 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 }
2906
Ahmed Charlesb8984322014-03-07 20:03:18 +00002907 std::unique_ptr<std::vector<const char *>> Args(
2908 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002909
2910 // Recover resources if we crash before exiting this method.
2911 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2912 ArgsCleanup(Args.get());
2913
2914 // Since the Clang C library is primarily used by batch tools dealing with
2915 // (often very broken) source code, where spell-checking can have a
2916 // significant negative impact on performance (particularly when
2917 // precompiled headers are involved), we disable it by default.
2918 // Only do this if we haven't found a spell-checking-related argument.
2919 bool FoundSpellCheckingArgument = false;
2920 for (int I = 0; I != num_command_line_args; ++I) {
2921 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2922 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2923 FoundSpellCheckingArgument = true;
2924 break;
2925 }
2926 }
2927 if (!FoundSpellCheckingArgument)
2928 Args->push_back("-fno-spell-checking");
2929
2930 Args->insert(Args->end(), command_line_args,
2931 command_line_args + num_command_line_args);
2932
2933 // The 'source_filename' argument is optional. If the caller does not
2934 // specify it then it is assumed that the source file is specified
2935 // in the actual argument list.
2936 // Put the source file after command_line_args otherwise if '-x' flag is
2937 // present it will be unused.
2938 if (source_filename)
2939 Args->push_back(source_filename);
2940
2941 // Do we need the detailed preprocessing record?
2942 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2943 Args->push_back("-Xclang");
2944 Args->push_back("-detailed-preprocessing-record");
2945 }
2946
2947 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002948 std::unique_ptr<ASTUnit> ErrUnit;
2949 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002950 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002951 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2952 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2953 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2954 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2955 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2956 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002957
2958 if (NumErrors != Diags->getClient()->getNumErrors()) {
2959 // Make sure to check that 'Unit' is non-NULL.
2960 if (CXXIdx->getDisplayDiagnostics())
2961 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2962 }
2963
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002964 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2965 PTUI->result = CXError_ASTReadError;
2966 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002967 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002968 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2969 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002970}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002971
2972CXTranslationUnit
2973clang_parseTranslationUnit(CXIndex CIdx,
2974 const char *source_filename,
2975 const char *const *command_line_args,
2976 int num_command_line_args,
2977 struct CXUnsavedFile *unsaved_files,
2978 unsigned num_unsaved_files,
2979 unsigned options) {
2980 CXTranslationUnit TU;
2981 enum CXErrorCode Result = clang_parseTranslationUnit2(
2982 CIdx, source_filename, command_line_args, num_command_line_args,
2983 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002984 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002985 assert((TU && Result == CXError_Success) ||
2986 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002987 return TU;
2988}
2989
2990enum CXErrorCode clang_parseTranslationUnit2(
2991 CXIndex CIdx,
2992 const char *source_filename,
2993 const char *const *command_line_args,
2994 int num_command_line_args,
2995 struct CXUnsavedFile *unsaved_files,
2996 unsigned num_unsaved_files,
2997 unsigned options,
2998 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002999 LOG_FUNC_SECTION {
3000 *Log << source_filename << ": ";
3001 for (int i = 0; i != num_command_line_args; ++i)
3002 *Log << command_line_args[i] << " ";
3003 }
3004
Alp Toker9d85b182014-07-07 01:23:14 +00003005 if (num_unsaved_files && !unsaved_files)
3006 return CXError_InvalidArguments;
3007
Alp Toker5c532982014-07-07 22:42:03 +00003008 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003009 ParseTranslationUnitInfo PTUI = {
3010 CIdx,
3011 source_filename,
3012 command_line_args,
3013 num_command_line_args,
3014 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3015 options,
3016 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003017 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003018 llvm::CrashRecoveryContext CRC;
3019
3020 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3021 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3022 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3023 fprintf(stderr, " 'command_line_args' : [");
3024 for (int i = 0; i != num_command_line_args; ++i) {
3025 if (i)
3026 fprintf(stderr, ", ");
3027 fprintf(stderr, "'%s'", command_line_args[i]);
3028 }
3029 fprintf(stderr, "],\n");
3030 fprintf(stderr, " 'unsaved_files' : [");
3031 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3032 if (i)
3033 fprintf(stderr, ", ");
3034 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3035 unsaved_files[i].Length);
3036 }
3037 fprintf(stderr, "],\n");
3038 fprintf(stderr, " 'options' : %d,\n", options);
3039 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003040
3041 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003042 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003043 if (CXTranslationUnit *TU = PTUI.out_TU)
3044 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003045 }
Alp Toker5c532982014-07-07 22:42:03 +00003046
3047 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003048}
3049
3050unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3051 return CXSaveTranslationUnit_None;
3052}
3053
3054namespace {
3055
3056struct SaveTranslationUnitInfo {
3057 CXTranslationUnit TU;
3058 const char *FileName;
3059 unsigned options;
3060 CXSaveError result;
3061};
3062
3063}
3064
3065static void clang_saveTranslationUnit_Impl(void *UserData) {
3066 SaveTranslationUnitInfo *STUI =
3067 static_cast<SaveTranslationUnitInfo*>(UserData);
3068
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003069 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003070 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3071 setThreadBackgroundPriority();
3072
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003073 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003074 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3075}
3076
3077int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3078 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003079 LOG_FUNC_SECTION {
3080 *Log << TU << ' ' << FileName;
3081 }
3082
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003083 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003084 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003085 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003086 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003087
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003088 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003089 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3090 if (!CXXUnit->hasSema())
3091 return CXSaveError_InvalidTU;
3092
3093 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3094
3095 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3096 getenv("LIBCLANG_NOTHREADS")) {
3097 clang_saveTranslationUnit_Impl(&STUI);
3098
3099 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3100 PrintLibclangResourceUsage(TU);
3101
3102 return STUI.result;
3103 }
3104
3105 // We have an AST that has invalid nodes due to compiler errors.
3106 // Use a crash recovery thread for protection.
3107
3108 llvm::CrashRecoveryContext CRC;
3109
3110 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3111 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3112 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3113 fprintf(stderr, " 'options' : %d,\n", options);
3114 fprintf(stderr, "}\n");
3115
3116 return CXSaveError_Unknown;
3117
3118 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3119 PrintLibclangResourceUsage(TU);
3120 }
3121
3122 return STUI.result;
3123}
3124
3125void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3126 if (CTUnit) {
3127 // If the translation unit has been marked as unsafe to free, just discard
3128 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003129 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3130 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003131 return;
3132
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003133 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003134 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003135 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3136 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003137 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 delete CTUnit;
3139 }
3140}
3141
3142unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3143 return CXReparse_None;
3144}
3145
3146struct ReparseTranslationUnitInfo {
3147 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003148 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003150 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003151};
3152
3153static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003154 const ReparseTranslationUnitInfo *RTUI =
3155 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003157 unsigned options = RTUI->options;
3158 (void) options;
3159
3160 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003161 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003162 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003163 RTUI->result = CXError_InvalidArguments;
3164 return;
3165 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003166
3167 // Reset the associated diagnostics.
3168 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003169 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003170
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003171 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003172 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3173 setThreadBackgroundPriority();
3174
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003175 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003177
3178 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3179 new std::vector<ASTUnit::RemappedFile>());
3180
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 // Recover resources if we crash before exiting this function.
3182 llvm::CrashRecoveryContextCleanupRegistrar<
3183 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003184
3185 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003186 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003187 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003188 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003190
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003191 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003192 RTUI->result = CXError_Success;
3193 else if (isASTReadError(CXXUnit))
3194 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003195}
3196
3197int clang_reparseTranslationUnit(CXTranslationUnit TU,
3198 unsigned num_unsaved_files,
3199 struct CXUnsavedFile *unsaved_files,
3200 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003201 LOG_FUNC_SECTION {
3202 *Log << TU;
3203 }
3204
Alp Toker9d85b182014-07-07 01:23:14 +00003205 if (num_unsaved_files && !unsaved_files)
3206 return CXError_InvalidArguments;
3207
Alp Toker5c532982014-07-07 22:42:03 +00003208 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003209 ReparseTranslationUnitInfo RTUI = {
3210 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003211 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003212
3213 if (getenv("LIBCLANG_NOTHREADS")) {
3214 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003215 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 }
3217
3218 llvm::CrashRecoveryContext CRC;
3219
3220 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3221 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003222 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003223 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003224 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3225 PrintLibclangResourceUsage(TU);
3226
Alp Toker5c532982014-07-07 22:42:03 +00003227 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003228}
3229
3230
3231CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003232 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003233 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003234 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003235 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003236
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003237 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003238 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003239}
3240
3241CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003242 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003243 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003244 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003245 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003246
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003247 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003248 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3249}
3250
3251} // end: extern "C"
3252
3253//===----------------------------------------------------------------------===//
3254// CXFile Operations.
3255//===----------------------------------------------------------------------===//
3256
3257extern "C" {
3258CXString clang_getFileName(CXFile SFile) {
3259 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003260 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003261
3262 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003263 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003264}
3265
3266time_t clang_getFileTime(CXFile SFile) {
3267 if (!SFile)
3268 return 0;
3269
3270 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3271 return FEnt->getModificationTime();
3272}
3273
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003274CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003275 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003276 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003277 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003278 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003279
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003280 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003281
3282 FileManager &FMgr = CXXUnit->getFileManager();
3283 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3284}
3285
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003286unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3287 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003288 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003289 LOG_BAD_TU(TU);
3290 return 0;
3291 }
3292
3293 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003294 return 0;
3295
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003296 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 FileEntry *FEnt = static_cast<FileEntry *>(file);
3298 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3299 .isFileMultipleIncludeGuarded(FEnt);
3300}
3301
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003302int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3303 if (!file || !outID)
3304 return 1;
3305
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003306 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003307 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3308 outID->data[0] = ID.getDevice();
3309 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003310 outID->data[2] = FEnt->getModificationTime();
3311 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003312}
3313
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003314int clang_File_isEqual(CXFile file1, CXFile file2) {
3315 if (file1 == file2)
3316 return true;
3317
3318 if (!file1 || !file2)
3319 return false;
3320
3321 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3322 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3323 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3324}
3325
Guy Benyei11169dd2012-12-18 14:30:41 +00003326} // end: extern "C"
3327
3328//===----------------------------------------------------------------------===//
3329// CXCursor Operations.
3330//===----------------------------------------------------------------------===//
3331
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003332static const Decl *getDeclFromExpr(const Stmt *E) {
3333 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 return getDeclFromExpr(CE->getSubExpr());
3335
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003336 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003338 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003340 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003342 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 if (PRE->isExplicitProperty())
3344 return PRE->getExplicitProperty();
3345 // It could be messaging both getter and setter as in:
3346 // ++myobj.myprop;
3347 // in which case prefer to associate the setter since it is less obvious
3348 // from inspecting the source that the setter is going to get called.
3349 if (PRE->isMessagingSetter())
3350 return PRE->getImplicitPropertySetter();
3351 return PRE->getImplicitPropertyGetter();
3352 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003353 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003355 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003356 if (Expr *Src = OVE->getSourceExpr())
3357 return getDeclFromExpr(Src);
3358
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003359 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003361 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 if (!CE->isElidable())
3363 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003364 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 return OME->getMethodDecl();
3366
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003367 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003369 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3371 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003372 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3374 isa<ParmVarDecl>(SizeOfPack->getPack()))
3375 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003376
3377 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003378}
3379
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003380static SourceLocation getLocationFromExpr(const Expr *E) {
3381 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 return getLocationFromExpr(CE->getSubExpr());
3383
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003384 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003385 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003386 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003388 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003390 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003392 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003394 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003395 return PropRef->getLocation();
3396
3397 return E->getLocStart();
3398}
3399
3400extern "C" {
3401
3402unsigned clang_visitChildren(CXCursor parent,
3403 CXCursorVisitor visitor,
3404 CXClientData client_data) {
3405 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3406 /*VisitPreprocessorLast=*/false);
3407 return CursorVis.VisitChildren(parent);
3408}
3409
3410#ifndef __has_feature
3411#define __has_feature(x) 0
3412#endif
3413#if __has_feature(blocks)
3414typedef enum CXChildVisitResult
3415 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3416
3417static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3418 CXClientData client_data) {
3419 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3420 return block(cursor, parent);
3421}
3422#else
3423// If we are compiled with a compiler that doesn't have native blocks support,
3424// define and call the block manually, so the
3425typedef struct _CXChildVisitResult
3426{
3427 void *isa;
3428 int flags;
3429 int reserved;
3430 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3431 CXCursor);
3432} *CXCursorVisitorBlock;
3433
3434static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3435 CXClientData client_data) {
3436 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3437 return block->invoke(block, cursor, parent);
3438}
3439#endif
3440
3441
3442unsigned clang_visitChildrenWithBlock(CXCursor parent,
3443 CXCursorVisitorBlock block) {
3444 return clang_visitChildren(parent, visitWithBlock, block);
3445}
3446
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003447static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003449 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003450
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003451 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003453 if (const ObjCPropertyImplDecl *PropImpl =
3454 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003456 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003457
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003458 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003460 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003461
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003462 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 }
3464
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003465 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003466 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003467
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003468 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3470 // and returns different names. NamedDecl returns the class name and
3471 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003472 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003473
3474 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003475 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003476
3477 SmallString<1024> S;
3478 llvm::raw_svector_ostream os(S);
3479 ND->printName(os);
3480
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003481 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003482}
3483
3484CXString clang_getCursorSpelling(CXCursor C) {
3485 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003486 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003487
3488 if (clang_isReference(C.kind)) {
3489 switch (C.kind) {
3490 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003491 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003492 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 }
3494 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003495 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003496 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 }
3498 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003499 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003501 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 }
3503 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003504 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003505 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 }
3507 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003508 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 assert(Type && "Missing type decl");
3510
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003511 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 getAsString());
3513 }
3514 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003515 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 assert(Template && "Missing template decl");
3517
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003518 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 }
3520
3521 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003522 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 assert(NS && "Missing namespace decl");
3524
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003525 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 }
3527
3528 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003529 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 assert(Field && "Missing member decl");
3531
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003532 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 }
3534
3535 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003536 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 assert(Label && "Missing label");
3538
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003539 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 }
3541
3542 case CXCursor_OverloadedDeclRef: {
3543 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003544 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3545 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003546 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003547 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003549 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003550 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 OverloadedTemplateStorage *Ovl
3552 = Storage.get<OverloadedTemplateStorage*>();
3553 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003554 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003555 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 }
3557
3558 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003559 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 assert(Var && "Missing variable decl");
3561
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003562 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 }
3564
3565 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003566 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 }
3568 }
3569
3570 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003571 const Expr *E = getCursorExpr(C);
3572
3573 if (C.kind == CXCursor_ObjCStringLiteral ||
3574 C.kind == CXCursor_StringLiteral) {
3575 const StringLiteral *SLit;
3576 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3577 SLit = OSL->getString();
3578 } else {
3579 SLit = cast<StringLiteral>(E);
3580 }
3581 SmallString<256> Buf;
3582 llvm::raw_svector_ostream OS(Buf);
3583 SLit->outputString(OS);
3584 return cxstring::createDup(OS.str());
3585 }
3586
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003587 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 if (D)
3589 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003590 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 }
3592
3593 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003594 const Stmt *S = getCursorStmt(C);
3595 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003596 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003597
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003598 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 }
3600
3601 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003602 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 ->getNameStart());
3604
3605 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003606 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 ->getNameStart());
3608
3609 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003610 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003611
3612 if (clang_isDeclaration(C.kind))
3613 return getDeclSpelling(getCursorDecl(C));
3614
3615 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003616 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003617 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 }
3619
3620 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003621 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003622 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 }
3624
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003625 if (C.kind == CXCursor_PackedAttr) {
3626 return cxstring::createRef("packed");
3627 }
3628
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003629 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003630}
3631
3632CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3633 unsigned pieceIndex,
3634 unsigned options) {
3635 if (clang_Cursor_isNull(C))
3636 return clang_getNullRange();
3637
3638 ASTContext &Ctx = getCursorContext(C);
3639
3640 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003641 const Stmt *S = getCursorStmt(C);
3642 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 if (pieceIndex > 0)
3644 return clang_getNullRange();
3645 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3646 }
3647
3648 return clang_getNullRange();
3649 }
3650
3651 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003652 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3654 if (pieceIndex >= ME->getNumSelectorLocs())
3655 return clang_getNullRange();
3656 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3657 }
3658 }
3659
3660 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3661 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003662 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3664 if (pieceIndex >= MD->getNumSelectorLocs())
3665 return clang_getNullRange();
3666 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3667 }
3668 }
3669
3670 if (C.kind == CXCursor_ObjCCategoryDecl ||
3671 C.kind == CXCursor_ObjCCategoryImplDecl) {
3672 if (pieceIndex > 0)
3673 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003674 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3676 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003677 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3679 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3680 }
3681
3682 if (C.kind == CXCursor_ModuleImportDecl) {
3683 if (pieceIndex > 0)
3684 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003685 if (const ImportDecl *ImportD =
3686 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3688 if (!Locs.empty())
3689 return cxloc::translateSourceRange(Ctx,
3690 SourceRange(Locs.front(), Locs.back()));
3691 }
3692 return clang_getNullRange();
3693 }
3694
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003695 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3696 C.kind == CXCursor_ConversionFunction) {
3697 if (pieceIndex > 0)
3698 return clang_getNullRange();
3699 if (const FunctionDecl *FD =
3700 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3701 DeclarationNameInfo FunctionName = FD->getNameInfo();
3702 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3703 }
3704 return clang_getNullRange();
3705 }
3706
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 // FIXME: A CXCursor_InclusionDirective should give the location of the
3708 // filename, but we don't keep track of this.
3709
3710 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3711 // but we don't keep track of this.
3712
3713 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3714 // but we don't keep track of this.
3715
3716 // Default handling, give the location of the cursor.
3717
3718 if (pieceIndex > 0)
3719 return clang_getNullRange();
3720
3721 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3722 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3723 return cxloc::translateSourceRange(Ctx, Loc);
3724}
3725
Eli Bendersky44a206f2014-07-31 18:04:56 +00003726CXString clang_Cursor_getMangling(CXCursor C) {
3727 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3728 return cxstring::createEmpty();
3729
Eli Bendersky44a206f2014-07-31 18:04:56 +00003730 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003731 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003732 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3733 return cxstring::createEmpty();
3734
Eli Bendersky79759592014-08-01 15:01:10 +00003735 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003736 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003737 ASTContext &Ctx = ND->getASTContext();
3738 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003739
Eli Bendersky79759592014-08-01 15:01:10 +00003740 std::string FrontendBuf;
3741 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3742 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003743
Eli Bendersky79759592014-08-01 15:01:10 +00003744 // Now apply backend mangling.
3745 std::unique_ptr<llvm::DataLayout> DL(
3746 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3747 llvm::Mangler BackendMangler(DL.get());
3748
3749 std::string FinalBuf;
3750 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3751 BackendMangler.getNameWithPrefix(FinalBufOS,
3752 llvm::Twine(FrontendBufOS.str()));
3753
3754 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003755}
3756
Guy Benyei11169dd2012-12-18 14:30:41 +00003757CXString clang_getCursorDisplayName(CXCursor C) {
3758 if (!clang_isDeclaration(C.kind))
3759 return clang_getCursorSpelling(C);
3760
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003761 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003763 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003764
3765 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003766 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 D = FunTmpl->getTemplatedDecl();
3768
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003769 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 SmallString<64> Str;
3771 llvm::raw_svector_ostream OS(Str);
3772 OS << *Function;
3773 if (Function->getPrimaryTemplate())
3774 OS << "<>";
3775 OS << "(";
3776 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3777 if (I)
3778 OS << ", ";
3779 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3780 }
3781
3782 if (Function->isVariadic()) {
3783 if (Function->getNumParams())
3784 OS << ", ";
3785 OS << "...";
3786 }
3787 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003788 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 }
3790
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003791 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 SmallString<64> Str;
3793 llvm::raw_svector_ostream OS(Str);
3794 OS << *ClassTemplate;
3795 OS << "<";
3796 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3797 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3798 if (I)
3799 OS << ", ";
3800
3801 NamedDecl *Param = Params->getParam(I);
3802 if (Param->getIdentifier()) {
3803 OS << Param->getIdentifier()->getName();
3804 continue;
3805 }
3806
3807 // There is no parameter name, which makes this tricky. Try to come up
3808 // with something useful that isn't too long.
3809 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3810 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3811 else if (NonTypeTemplateParmDecl *NTTP
3812 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3813 OS << NTTP->getType().getAsString(Policy);
3814 else
3815 OS << "template<...> class";
3816 }
3817
3818 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003819 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 }
3821
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003822 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3824 // If the type was explicitly written, use that.
3825 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003826 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003827
Benjamin Kramer9170e912013-02-22 15:46:01 +00003828 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 llvm::raw_svector_ostream OS(Str);
3830 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003831 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 ClassSpec->getTemplateArgs().data(),
3833 ClassSpec->getTemplateArgs().size(),
3834 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003835 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 }
3837
3838 return clang_getCursorSpelling(C);
3839}
3840
3841CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3842 switch (Kind) {
3843 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003971 case CXCursor_ObjCSelfExpr:
3972 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004061 case CXCursor_SEHLeaveStmt:
4062 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004091 case CXCursor_PackedAttr:
4092 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004093 case CXCursor_PureAttr:
4094 return cxstring::createRef("attribute(pure)");
4095 case CXCursor_ConstAttr:
4096 return cxstring::createRef("attribute(const)");
4097 case CXCursor_NoDuplicateAttr:
4098 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004099 case CXCursor_CUDAConstantAttr:
4100 return cxstring::createRef("attribute(constant)");
4101 case CXCursor_CUDADeviceAttr:
4102 return cxstring::createRef("attribute(device)");
4103 case CXCursor_CUDAGlobalAttr:
4104 return cxstring::createRef("attribute(global)");
4105 case CXCursor_CUDAHostAttr:
4106 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004107 case CXCursor_CUDASharedAttr:
4108 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004157 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004158 return cxstring::createRef("OMPParallelDirective");
4159 case CXCursor_OMPSimdDirective:
4160 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004161 case CXCursor_OMPForDirective:
4162 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004163 case CXCursor_OMPForSimdDirective:
4164 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004165 case CXCursor_OMPSectionsDirective:
4166 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004167 case CXCursor_OMPSectionDirective:
4168 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004169 case CXCursor_OMPSingleDirective:
4170 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004171 case CXCursor_OMPMasterDirective:
4172 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004173 case CXCursor_OMPCriticalDirective:
4174 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004175 case CXCursor_OMPParallelForDirective:
4176 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004177 case CXCursor_OMPParallelForSimdDirective:
4178 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004179 case CXCursor_OMPParallelSectionsDirective:
4180 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004181 case CXCursor_OMPTaskDirective:
4182 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004183 case CXCursor_OMPTaskyieldDirective:
4184 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004185 case CXCursor_OMPBarrierDirective:
4186 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004187 case CXCursor_OMPTaskwaitDirective:
4188 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004189 case CXCursor_OMPFlushDirective:
4190 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004191 case CXCursor_OMPOrderedDirective:
4192 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004193 case CXCursor_OMPAtomicDirective:
4194 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004195 case CXCursor_OMPTargetDirective:
4196 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004197 case CXCursor_OMPTeamsDirective:
4198 return cxstring::createRef("OMPTeamsDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 }
4200
4201 llvm_unreachable("Unhandled CXCursorKind");
4202}
4203
4204struct GetCursorData {
4205 SourceLocation TokenBeginLoc;
4206 bool PointsAtMacroArgExpansion;
4207 bool VisitedObjCPropertyImplDecl;
4208 SourceLocation VisitedDeclaratorDeclStartLoc;
4209 CXCursor &BestCursor;
4210
4211 GetCursorData(SourceManager &SM,
4212 SourceLocation tokenBegin, CXCursor &outputCursor)
4213 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4214 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4215 VisitedObjCPropertyImplDecl = false;
4216 }
4217};
4218
4219static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4220 CXCursor parent,
4221 CXClientData client_data) {
4222 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4223 CXCursor *BestCursor = &Data->BestCursor;
4224
4225 // If we point inside a macro argument we should provide info of what the
4226 // token is so use the actual cursor, don't replace it with a macro expansion
4227 // cursor.
4228 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4229 return CXChildVisit_Recurse;
4230
4231 if (clang_isDeclaration(cursor.kind)) {
4232 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004233 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4235 if (MD->isImplicit())
4236 return CXChildVisit_Break;
4237
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004238 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4240 // Check that when we have multiple @class references in the same line,
4241 // that later ones do not override the previous ones.
4242 // If we have:
4243 // @class Foo, Bar;
4244 // source ranges for both start at '@', so 'Bar' will end up overriding
4245 // 'Foo' even though the cursor location was at 'Foo'.
4246 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4247 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004248 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4250 if (PrevID != ID &&
4251 !PrevID->isThisDeclarationADefinition() &&
4252 !ID->isThisDeclarationADefinition())
4253 return CXChildVisit_Break;
4254 }
4255
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004256 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4258 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4259 // Check that when we have multiple declarators in the same line,
4260 // that later ones do not override the previous ones.
4261 // If we have:
4262 // int Foo, Bar;
4263 // source ranges for both start at 'int', so 'Bar' will end up overriding
4264 // 'Foo' even though the cursor location was at 'Foo'.
4265 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4266 return CXChildVisit_Break;
4267 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4268
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004269 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4271 (void)PropImp;
4272 // Check that when we have multiple @synthesize in the same line,
4273 // that later ones do not override the previous ones.
4274 // If we have:
4275 // @synthesize Foo, Bar;
4276 // source ranges for both start at '@', so 'Bar' will end up overriding
4277 // 'Foo' even though the cursor location was at 'Foo'.
4278 if (Data->VisitedObjCPropertyImplDecl)
4279 return CXChildVisit_Break;
4280 Data->VisitedObjCPropertyImplDecl = true;
4281 }
4282 }
4283
4284 if (clang_isExpression(cursor.kind) &&
4285 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004286 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 // Avoid having the cursor of an expression replace the declaration cursor
4288 // when the expression source range overlaps the declaration range.
4289 // This can happen for C++ constructor expressions whose range generally
4290 // include the variable declaration, e.g.:
4291 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4292 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4293 D->getLocation() == Data->TokenBeginLoc)
4294 return CXChildVisit_Break;
4295 }
4296 }
4297
4298 // If our current best cursor is the construction of a temporary object,
4299 // don't replace that cursor with a type reference, because we want
4300 // clang_getCursor() to point at the constructor.
4301 if (clang_isExpression(BestCursor->kind) &&
4302 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4303 cursor.kind == CXCursor_TypeRef) {
4304 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4305 // as having the actual point on the type reference.
4306 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4307 return CXChildVisit_Recurse;
4308 }
4309
4310 *BestCursor = cursor;
4311 return CXChildVisit_Recurse;
4312}
4313
4314CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004315 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004316 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004317 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004318 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004319
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004320 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004321 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4322
4323 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4324 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4325
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004326 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004327 CXFile SearchFile;
4328 unsigned SearchLine, SearchColumn;
4329 CXFile ResultFile;
4330 unsigned ResultLine, ResultColumn;
4331 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4332 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4333 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004334
4335 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4336 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004337 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004338 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004339 SearchFileName = clang_getFileName(SearchFile);
4340 ResultFileName = clang_getFileName(ResultFile);
4341 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4342 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004343 *Log << llvm::format("(%s:%d:%d) = %s",
4344 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4345 clang_getCString(KindSpelling))
4346 << llvm::format("(%s:%d:%d):%s%s",
4347 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4348 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004349 clang_disposeString(SearchFileName);
4350 clang_disposeString(ResultFileName);
4351 clang_disposeString(KindSpelling);
4352 clang_disposeString(USR);
4353
4354 CXCursor Definition = clang_getCursorDefinition(Result);
4355 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4356 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4357 CXString DefinitionKindSpelling
4358 = clang_getCursorKindSpelling(Definition.kind);
4359 CXFile DefinitionFile;
4360 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004361 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004362 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004363 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004364 *Log << llvm::format(" -> %s(%s:%d:%d)",
4365 clang_getCString(DefinitionKindSpelling),
4366 clang_getCString(DefinitionFileName),
4367 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004368 clang_disposeString(DefinitionFileName);
4369 clang_disposeString(DefinitionKindSpelling);
4370 }
4371 }
4372
4373 return Result;
4374}
4375
4376CXCursor clang_getNullCursor(void) {
4377 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4378}
4379
4380unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004381 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4382 // can't set consistently. For example, when visiting a DeclStmt we will set
4383 // it but we don't set it on the result of clang_getCursorDefinition for
4384 // a reference of the same declaration.
4385 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4386 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4387 // to provide that kind of info.
4388 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004389 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004390 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004391 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004392
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 return X == Y;
4394}
4395
4396unsigned clang_hashCursor(CXCursor C) {
4397 unsigned Index = 0;
4398 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4399 Index = 1;
4400
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004401 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 std::make_pair(C.kind, C.data[Index]));
4403}
4404
4405unsigned clang_isInvalid(enum CXCursorKind K) {
4406 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4407}
4408
4409unsigned clang_isDeclaration(enum CXCursorKind K) {
4410 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4411 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4412}
4413
4414unsigned clang_isReference(enum CXCursorKind K) {
4415 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4416}
4417
4418unsigned clang_isExpression(enum CXCursorKind K) {
4419 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4420}
4421
4422unsigned clang_isStatement(enum CXCursorKind K) {
4423 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4424}
4425
4426unsigned clang_isAttribute(enum CXCursorKind K) {
4427 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4428}
4429
4430unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4431 return K == CXCursor_TranslationUnit;
4432}
4433
4434unsigned clang_isPreprocessing(enum CXCursorKind K) {
4435 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4436}
4437
4438unsigned clang_isUnexposed(enum CXCursorKind K) {
4439 switch (K) {
4440 case CXCursor_UnexposedDecl:
4441 case CXCursor_UnexposedExpr:
4442 case CXCursor_UnexposedStmt:
4443 case CXCursor_UnexposedAttr:
4444 return true;
4445 default:
4446 return false;
4447 }
4448}
4449
4450CXCursorKind clang_getCursorKind(CXCursor C) {
4451 return C.kind;
4452}
4453
4454CXSourceLocation clang_getCursorLocation(CXCursor C) {
4455 if (clang_isReference(C.kind)) {
4456 switch (C.kind) {
4457 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004458 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 = getCursorObjCSuperClassRef(C);
4460 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4461 }
4462
4463 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004464 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004465 = getCursorObjCProtocolRef(C);
4466 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4467 }
4468
4469 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004470 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 = getCursorObjCClassRef(C);
4472 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4473 }
4474
4475 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004476 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004477 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4478 }
4479
4480 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004481 std::pair<const TemplateDecl *, SourceLocation> P =
4482 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4484 }
4485
4486 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004487 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4489 }
4490
4491 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004492 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4494 }
4495
4496 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004497 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004498 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4499 }
4500
4501 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004502 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 if (!BaseSpec)
4504 return clang_getNullLocation();
4505
4506 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4507 return cxloc::translateSourceLocation(getCursorContext(C),
4508 TSInfo->getTypeLoc().getBeginLoc());
4509
4510 return cxloc::translateSourceLocation(getCursorContext(C),
4511 BaseSpec->getLocStart());
4512 }
4513
4514 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004515 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4517 }
4518
4519 case CXCursor_OverloadedDeclRef:
4520 return cxloc::translateSourceLocation(getCursorContext(C),
4521 getCursorOverloadedDeclRef(C).second);
4522
4523 default:
4524 // FIXME: Need a way to enumerate all non-reference cases.
4525 llvm_unreachable("Missed a reference kind");
4526 }
4527 }
4528
4529 if (clang_isExpression(C.kind))
4530 return cxloc::translateSourceLocation(getCursorContext(C),
4531 getLocationFromExpr(getCursorExpr(C)));
4532
4533 if (clang_isStatement(C.kind))
4534 return cxloc::translateSourceLocation(getCursorContext(C),
4535 getCursorStmt(C)->getLocStart());
4536
4537 if (C.kind == CXCursor_PreprocessingDirective) {
4538 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4539 return cxloc::translateSourceLocation(getCursorContext(C), L);
4540 }
4541
4542 if (C.kind == CXCursor_MacroExpansion) {
4543 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004544 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 return cxloc::translateSourceLocation(getCursorContext(C), L);
4546 }
4547
4548 if (C.kind == CXCursor_MacroDefinition) {
4549 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4550 return cxloc::translateSourceLocation(getCursorContext(C), L);
4551 }
4552
4553 if (C.kind == CXCursor_InclusionDirective) {
4554 SourceLocation L
4555 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4556 return cxloc::translateSourceLocation(getCursorContext(C), L);
4557 }
4558
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004559 if (clang_isAttribute(C.kind)) {
4560 SourceLocation L
4561 = cxcursor::getCursorAttr(C)->getLocation();
4562 return cxloc::translateSourceLocation(getCursorContext(C), L);
4563 }
4564
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 if (!clang_isDeclaration(C.kind))
4566 return clang_getNullLocation();
4567
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004568 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 if (!D)
4570 return clang_getNullLocation();
4571
4572 SourceLocation Loc = D->getLocation();
4573 // FIXME: Multiple variables declared in a single declaration
4574 // currently lack the information needed to correctly determine their
4575 // ranges when accounting for the type-specifier. We use context
4576 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4577 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004578 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 if (!cxcursor::isFirstInDeclGroup(C))
4580 Loc = VD->getLocation();
4581 }
4582
4583 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004584 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 Loc = MD->getSelectorStartLoc();
4586
4587 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4588}
4589
4590} // end extern "C"
4591
4592CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4593 assert(TU);
4594
4595 // Guard against an invalid SourceLocation, or we may assert in one
4596 // of the following calls.
4597 if (SLoc.isInvalid())
4598 return clang_getNullCursor();
4599
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004600 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004601
4602 // Translate the given source location to make it point at the beginning of
4603 // the token under the cursor.
4604 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4605 CXXUnit->getASTContext().getLangOpts());
4606
4607 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4608 if (SLoc.isValid()) {
4609 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4610 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4611 /*VisitPreprocessorLast=*/true,
4612 /*VisitIncludedEntities=*/false,
4613 SourceLocation(SLoc));
4614 CursorVis.visitFileRegion();
4615 }
4616
4617 return Result;
4618}
4619
4620static SourceRange getRawCursorExtent(CXCursor C) {
4621 if (clang_isReference(C.kind)) {
4622 switch (C.kind) {
4623 case CXCursor_ObjCSuperClassRef:
4624 return getCursorObjCSuperClassRef(C).second;
4625
4626 case CXCursor_ObjCProtocolRef:
4627 return getCursorObjCProtocolRef(C).second;
4628
4629 case CXCursor_ObjCClassRef:
4630 return getCursorObjCClassRef(C).second;
4631
4632 case CXCursor_TypeRef:
4633 return getCursorTypeRef(C).second;
4634
4635 case CXCursor_TemplateRef:
4636 return getCursorTemplateRef(C).second;
4637
4638 case CXCursor_NamespaceRef:
4639 return getCursorNamespaceRef(C).second;
4640
4641 case CXCursor_MemberRef:
4642 return getCursorMemberRef(C).second;
4643
4644 case CXCursor_CXXBaseSpecifier:
4645 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4646
4647 case CXCursor_LabelRef:
4648 return getCursorLabelRef(C).second;
4649
4650 case CXCursor_OverloadedDeclRef:
4651 return getCursorOverloadedDeclRef(C).second;
4652
4653 case CXCursor_VariableRef:
4654 return getCursorVariableRef(C).second;
4655
4656 default:
4657 // FIXME: Need a way to enumerate all non-reference cases.
4658 llvm_unreachable("Missed a reference kind");
4659 }
4660 }
4661
4662 if (clang_isExpression(C.kind))
4663 return getCursorExpr(C)->getSourceRange();
4664
4665 if (clang_isStatement(C.kind))
4666 return getCursorStmt(C)->getSourceRange();
4667
4668 if (clang_isAttribute(C.kind))
4669 return getCursorAttr(C)->getRange();
4670
4671 if (C.kind == CXCursor_PreprocessingDirective)
4672 return cxcursor::getCursorPreprocessingDirective(C);
4673
4674 if (C.kind == CXCursor_MacroExpansion) {
4675 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004676 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 return TU->mapRangeFromPreamble(Range);
4678 }
4679
4680 if (C.kind == CXCursor_MacroDefinition) {
4681 ASTUnit *TU = getCursorASTUnit(C);
4682 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4683 return TU->mapRangeFromPreamble(Range);
4684 }
4685
4686 if (C.kind == CXCursor_InclusionDirective) {
4687 ASTUnit *TU = getCursorASTUnit(C);
4688 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4689 return TU->mapRangeFromPreamble(Range);
4690 }
4691
4692 if (C.kind == CXCursor_TranslationUnit) {
4693 ASTUnit *TU = getCursorASTUnit(C);
4694 FileID MainID = TU->getSourceManager().getMainFileID();
4695 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4696 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4697 return SourceRange(Start, End);
4698 }
4699
4700 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004701 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 if (!D)
4703 return SourceRange();
4704
4705 SourceRange R = D->getSourceRange();
4706 // FIXME: Multiple variables declared in a single declaration
4707 // currently lack the information needed to correctly determine their
4708 // ranges when accounting for the type-specifier. We use context
4709 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4710 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004711 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 if (!cxcursor::isFirstInDeclGroup(C))
4713 R.setBegin(VD->getLocation());
4714 }
4715 return R;
4716 }
4717 return SourceRange();
4718}
4719
4720/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4721/// the decl-specifier-seq for declarations.
4722static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4723 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004724 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 if (!D)
4726 return SourceRange();
4727
4728 SourceRange R = D->getSourceRange();
4729
4730 // Adjust the start of the location for declarations preceded by
4731 // declaration specifiers.
4732 SourceLocation StartLoc;
4733 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4734 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4735 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004736 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4738 StartLoc = TI->getTypeLoc().getLocStart();
4739 }
4740
4741 if (StartLoc.isValid() && R.getBegin().isValid() &&
4742 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4743 R.setBegin(StartLoc);
4744
4745 // FIXME: Multiple variables declared in a single declaration
4746 // currently lack the information needed to correctly determine their
4747 // ranges when accounting for the type-specifier. We use context
4748 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4749 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004750 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 if (!cxcursor::isFirstInDeclGroup(C))
4752 R.setBegin(VD->getLocation());
4753 }
4754
4755 return R;
4756 }
4757
4758 return getRawCursorExtent(C);
4759}
4760
4761extern "C" {
4762
4763CXSourceRange clang_getCursorExtent(CXCursor C) {
4764 SourceRange R = getRawCursorExtent(C);
4765 if (R.isInvalid())
4766 return clang_getNullRange();
4767
4768 return cxloc::translateSourceRange(getCursorContext(C), R);
4769}
4770
4771CXCursor clang_getCursorReferenced(CXCursor C) {
4772 if (clang_isInvalid(C.kind))
4773 return clang_getNullCursor();
4774
4775 CXTranslationUnit tu = getCursorTU(C);
4776 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004777 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004778 if (!D)
4779 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004780 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004782 if (const ObjCPropertyImplDecl *PropImpl =
4783 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4785 return MakeCXCursor(Property, tu);
4786
4787 return C;
4788 }
4789
4790 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004791 const Expr *E = getCursorExpr(C);
4792 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 if (D) {
4794 CXCursor declCursor = MakeCXCursor(D, tu);
4795 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4796 declCursor);
4797 return declCursor;
4798 }
4799
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004800 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 return MakeCursorOverloadedDeclRef(Ovl, tu);
4802
4803 return clang_getNullCursor();
4804 }
4805
4806 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004807 const Stmt *S = getCursorStmt(C);
4808 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004809 if (LabelDecl *label = Goto->getLabel())
4810 if (LabelStmt *labelS = label->getStmt())
4811 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4812
4813 return clang_getNullCursor();
4814 }
4815
4816 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004817 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 return MakeMacroDefinitionCursor(Def, tu);
4819 }
4820
4821 if (!clang_isReference(C.kind))
4822 return clang_getNullCursor();
4823
4824 switch (C.kind) {
4825 case CXCursor_ObjCSuperClassRef:
4826 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4827
4828 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004829 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4830 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004831 return MakeCXCursor(Def, tu);
4832
4833 return MakeCXCursor(Prot, tu);
4834 }
4835
4836 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004837 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4838 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004839 return MakeCXCursor(Def, tu);
4840
4841 return MakeCXCursor(Class, tu);
4842 }
4843
4844 case CXCursor_TypeRef:
4845 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4846
4847 case CXCursor_TemplateRef:
4848 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4849
4850 case CXCursor_NamespaceRef:
4851 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4852
4853 case CXCursor_MemberRef:
4854 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4855
4856 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004857 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004858 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4859 tu ));
4860 }
4861
4862 case CXCursor_LabelRef:
4863 // FIXME: We end up faking the "parent" declaration here because we
4864 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004865 return MakeCXCursor(getCursorLabelRef(C).first,
4866 cxtu::getASTUnit(tu)->getASTContext()
4867 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004868 tu);
4869
4870 case CXCursor_OverloadedDeclRef:
4871 return C;
4872
4873 case CXCursor_VariableRef:
4874 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4875
4876 default:
4877 // We would prefer to enumerate all non-reference cursor kinds here.
4878 llvm_unreachable("Unhandled reference cursor kind");
4879 }
4880}
4881
4882CXCursor clang_getCursorDefinition(CXCursor C) {
4883 if (clang_isInvalid(C.kind))
4884 return clang_getNullCursor();
4885
4886 CXTranslationUnit TU = getCursorTU(C);
4887
4888 bool WasReference = false;
4889 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4890 C = clang_getCursorReferenced(C);
4891 WasReference = true;
4892 }
4893
4894 if (C.kind == CXCursor_MacroExpansion)
4895 return clang_getCursorReferenced(C);
4896
4897 if (!clang_isDeclaration(C.kind))
4898 return clang_getNullCursor();
4899
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004900 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004901 if (!D)
4902 return clang_getNullCursor();
4903
4904 switch (D->getKind()) {
4905 // Declaration kinds that don't really separate the notions of
4906 // declaration and definition.
4907 case Decl::Namespace:
4908 case Decl::Typedef:
4909 case Decl::TypeAlias:
4910 case Decl::TypeAliasTemplate:
4911 case Decl::TemplateTypeParm:
4912 case Decl::EnumConstant:
4913 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004914 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 case Decl::IndirectField:
4916 case Decl::ObjCIvar:
4917 case Decl::ObjCAtDefsField:
4918 case Decl::ImplicitParam:
4919 case Decl::ParmVar:
4920 case Decl::NonTypeTemplateParm:
4921 case Decl::TemplateTemplateParm:
4922 case Decl::ObjCCategoryImpl:
4923 case Decl::ObjCImplementation:
4924 case Decl::AccessSpec:
4925 case Decl::LinkageSpec:
4926 case Decl::ObjCPropertyImpl:
4927 case Decl::FileScopeAsm:
4928 case Decl::StaticAssert:
4929 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004930 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004931 case Decl::Label: // FIXME: Is this right??
4932 case Decl::ClassScopeFunctionSpecialization:
4933 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004934 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 return C;
4936
4937 // Declaration kinds that don't make any sense here, but are
4938 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004939 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004940 case Decl::TranslationUnit:
4941 break;
4942
4943 // Declaration kinds for which the definition is not resolvable.
4944 case Decl::UnresolvedUsingTypename:
4945 case Decl::UnresolvedUsingValue:
4946 break;
4947
4948 case Decl::UsingDirective:
4949 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4950 TU);
4951
4952 case Decl::NamespaceAlias:
4953 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4954
4955 case Decl::Enum:
4956 case Decl::Record:
4957 case Decl::CXXRecord:
4958 case Decl::ClassTemplateSpecialization:
4959 case Decl::ClassTemplatePartialSpecialization:
4960 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4961 return MakeCXCursor(Def, TU);
4962 return clang_getNullCursor();
4963
4964 case Decl::Function:
4965 case Decl::CXXMethod:
4966 case Decl::CXXConstructor:
4967 case Decl::CXXDestructor:
4968 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004969 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004970 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004971 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004972 return clang_getNullCursor();
4973 }
4974
Larisse Voufo39a1e502013-08-06 01:03:05 +00004975 case Decl::Var:
4976 case Decl::VarTemplateSpecialization:
4977 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004978 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004979 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004980 return MakeCXCursor(Def, TU);
4981 return clang_getNullCursor();
4982 }
4983
4984 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004985 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004986 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4987 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4988 return clang_getNullCursor();
4989 }
4990
4991 case Decl::ClassTemplate: {
4992 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4993 ->getDefinition())
4994 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4995 TU);
4996 return clang_getNullCursor();
4997 }
4998
Larisse Voufo39a1e502013-08-06 01:03:05 +00004999 case Decl::VarTemplate: {
5000 if (VarDecl *Def =
5001 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5002 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5003 return clang_getNullCursor();
5004 }
5005
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 case Decl::Using:
5007 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5008 D->getLocation(), TU);
5009
5010 case Decl::UsingShadow:
5011 return clang_getCursorDefinition(
5012 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5013 TU));
5014
5015 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005016 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 if (Method->isThisDeclarationADefinition())
5018 return C;
5019
5020 // Dig out the method definition in the associated
5021 // @implementation, if we have it.
5022 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005023 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005024 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5025 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5026 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5027 Method->isInstanceMethod()))
5028 if (Def->isThisDeclarationADefinition())
5029 return MakeCXCursor(Def, TU);
5030
5031 return clang_getNullCursor();
5032 }
5033
5034 case Decl::ObjCCategory:
5035 if (ObjCCategoryImplDecl *Impl
5036 = cast<ObjCCategoryDecl>(D)->getImplementation())
5037 return MakeCXCursor(Impl, TU);
5038 return clang_getNullCursor();
5039
5040 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005041 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 return MakeCXCursor(Def, TU);
5043 return clang_getNullCursor();
5044
5045 case Decl::ObjCInterface: {
5046 // There are two notions of a "definition" for an Objective-C
5047 // class: the interface and its implementation. When we resolved a
5048 // reference to an Objective-C class, produce the @interface as
5049 // the definition; when we were provided with the interface,
5050 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005051 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005052 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005053 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005054 return MakeCXCursor(Def, TU);
5055 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5056 return MakeCXCursor(Impl, TU);
5057 return clang_getNullCursor();
5058 }
5059
5060 case Decl::ObjCProperty:
5061 // FIXME: We don't really know where to find the
5062 // ObjCPropertyImplDecls that implement this property.
5063 return clang_getNullCursor();
5064
5065 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005066 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005068 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 return MakeCXCursor(Def, TU);
5070
5071 return clang_getNullCursor();
5072
5073 case Decl::Friend:
5074 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5075 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5076 return clang_getNullCursor();
5077
5078 case Decl::FriendTemplate:
5079 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5080 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5081 return clang_getNullCursor();
5082 }
5083
5084 return clang_getNullCursor();
5085}
5086
5087unsigned clang_isCursorDefinition(CXCursor C) {
5088 if (!clang_isDeclaration(C.kind))
5089 return 0;
5090
5091 return clang_getCursorDefinition(C) == C;
5092}
5093
5094CXCursor clang_getCanonicalCursor(CXCursor C) {
5095 if (!clang_isDeclaration(C.kind))
5096 return C;
5097
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005098 if (const Decl *D = getCursorDecl(C)) {
5099 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5101 return MakeCXCursor(CatD, getCursorTU(C));
5102
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005103 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5104 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005105 return MakeCXCursor(IFD, getCursorTU(C));
5106
5107 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5108 }
5109
5110 return C;
5111}
5112
5113int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5114 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5115}
5116
5117unsigned clang_getNumOverloadedDecls(CXCursor C) {
5118 if (C.kind != CXCursor_OverloadedDeclRef)
5119 return 0;
5120
5121 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005122 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005123 return E->getNumDecls();
5124
5125 if (OverloadedTemplateStorage *S
5126 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5127 return S->size();
5128
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005129 const Decl *D = Storage.get<const Decl *>();
5130 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 return Using->shadow_size();
5132
5133 return 0;
5134}
5135
5136CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5137 if (cursor.kind != CXCursor_OverloadedDeclRef)
5138 return clang_getNullCursor();
5139
5140 if (index >= clang_getNumOverloadedDecls(cursor))
5141 return clang_getNullCursor();
5142
5143 CXTranslationUnit TU = getCursorTU(cursor);
5144 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005145 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 return MakeCXCursor(E->decls_begin()[index], TU);
5147
5148 if (OverloadedTemplateStorage *S
5149 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5150 return MakeCXCursor(S->begin()[index], TU);
5151
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005152 const Decl *D = Storage.get<const Decl *>();
5153 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005154 // FIXME: This is, unfortunately, linear time.
5155 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5156 std::advance(Pos, index);
5157 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5158 }
5159
5160 return clang_getNullCursor();
5161}
5162
5163void clang_getDefinitionSpellingAndExtent(CXCursor C,
5164 const char **startBuf,
5165 const char **endBuf,
5166 unsigned *startLine,
5167 unsigned *startColumn,
5168 unsigned *endLine,
5169 unsigned *endColumn) {
5170 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005171 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5173
5174 SourceManager &SM = FD->getASTContext().getSourceManager();
5175 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5176 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5177 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5178 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5179 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5180 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5181}
5182
5183
5184CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5185 unsigned PieceIndex) {
5186 RefNamePieces Pieces;
5187
5188 switch (C.kind) {
5189 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005190 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005191 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5192 E->getQualifierLoc().getSourceRange());
5193 break;
5194
5195 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005196 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005197 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5198 E->getQualifierLoc().getSourceRange(),
5199 E->getOptionalExplicitTemplateArgs());
5200 break;
5201
5202 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005203 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005205 const Expr *Callee = OCE->getCallee();
5206 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005207 Callee = ICE->getSubExpr();
5208
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005209 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5211 DRE->getQualifierLoc().getSourceRange());
5212 }
5213 break;
5214
5215 default:
5216 break;
5217 }
5218
5219 if (Pieces.empty()) {
5220 if (PieceIndex == 0)
5221 return clang_getCursorExtent(C);
5222 } else if (PieceIndex < Pieces.size()) {
5223 SourceRange R = Pieces[PieceIndex];
5224 if (R.isValid())
5225 return cxloc::translateSourceRange(getCursorContext(C), R);
5226 }
5227
5228 return clang_getNullRange();
5229}
5230
5231void clang_enableStackTraces(void) {
5232 llvm::sys::PrintStackTraceOnErrorSignal();
5233}
5234
5235void clang_executeOnThread(void (*fn)(void*), void *user_data,
5236 unsigned stack_size) {
5237 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5238}
5239
5240} // end: extern "C"
5241
5242//===----------------------------------------------------------------------===//
5243// Token-based Operations.
5244//===----------------------------------------------------------------------===//
5245
5246/* CXToken layout:
5247 * int_data[0]: a CXTokenKind
5248 * int_data[1]: starting token location
5249 * int_data[2]: token length
5250 * int_data[3]: reserved
5251 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5252 * otherwise unused.
5253 */
5254extern "C" {
5255
5256CXTokenKind clang_getTokenKind(CXToken CXTok) {
5257 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5258}
5259
5260CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5261 switch (clang_getTokenKind(CXTok)) {
5262 case CXToken_Identifier:
5263 case CXToken_Keyword:
5264 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005265 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 ->getNameStart());
5267
5268 case CXToken_Literal: {
5269 // We have stashed the starting pointer in the ptr_data field. Use it.
5270 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005271 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 }
5273
5274 case CXToken_Punctuation:
5275 case CXToken_Comment:
5276 break;
5277 }
5278
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005279 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005280 LOG_BAD_TU(TU);
5281 return cxstring::createEmpty();
5282 }
5283
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 // We have to find the starting buffer pointer the hard way, by
5285 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005286 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005287 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005288 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005289
5290 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5291 std::pair<FileID, unsigned> LocInfo
5292 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5293 bool Invalid = false;
5294 StringRef Buffer
5295 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5296 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005297 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005298
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005299 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005300}
5301
5302CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005303 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005304 LOG_BAD_TU(TU);
5305 return clang_getNullLocation();
5306 }
5307
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005308 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005309 if (!CXXUnit)
5310 return clang_getNullLocation();
5311
5312 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5313 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5314}
5315
5316CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005317 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005318 LOG_BAD_TU(TU);
5319 return clang_getNullRange();
5320 }
5321
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005322 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005323 if (!CXXUnit)
5324 return clang_getNullRange();
5325
5326 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5327 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5328}
5329
5330static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5331 SmallVectorImpl<CXToken> &CXTokens) {
5332 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5333 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005334 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005335 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005336 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005337
5338 // Cannot tokenize across files.
5339 if (BeginLocInfo.first != EndLocInfo.first)
5340 return;
5341
5342 // Create a lexer
5343 bool Invalid = false;
5344 StringRef Buffer
5345 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5346 if (Invalid)
5347 return;
5348
5349 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5350 CXXUnit->getASTContext().getLangOpts(),
5351 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5352 Lex.SetCommentRetentionState(true);
5353
5354 // Lex tokens until we hit the end of the range.
5355 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5356 Token Tok;
5357 bool previousWasAt = false;
5358 do {
5359 // Lex the next token
5360 Lex.LexFromRawLexer(Tok);
5361 if (Tok.is(tok::eof))
5362 break;
5363
5364 // Initialize the CXToken.
5365 CXToken CXTok;
5366
5367 // - Common fields
5368 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5369 CXTok.int_data[2] = Tok.getLength();
5370 CXTok.int_data[3] = 0;
5371
5372 // - Kind-specific fields
5373 if (Tok.isLiteral()) {
5374 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005375 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 } else if (Tok.is(tok::raw_identifier)) {
5377 // Lookup the identifier to determine whether we have a keyword.
5378 IdentifierInfo *II
5379 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5380
5381 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5382 CXTok.int_data[0] = CXToken_Keyword;
5383 }
5384 else {
5385 CXTok.int_data[0] = Tok.is(tok::identifier)
5386 ? CXToken_Identifier
5387 : CXToken_Keyword;
5388 }
5389 CXTok.ptr_data = II;
5390 } else if (Tok.is(tok::comment)) {
5391 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005392 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005393 } else {
5394 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005395 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005396 }
5397 CXTokens.push_back(CXTok);
5398 previousWasAt = Tok.is(tok::at);
5399 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5400}
5401
5402void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5403 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005404 LOG_FUNC_SECTION {
5405 *Log << TU << ' ' << Range;
5406 }
5407
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005409 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005410 if (NumTokens)
5411 *NumTokens = 0;
5412
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005413 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005414 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005415 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005416 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005417
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005418 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005419 if (!CXXUnit || !Tokens || !NumTokens)
5420 return;
5421
5422 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5423
5424 SourceRange R = cxloc::translateCXSourceRange(Range);
5425 if (R.isInvalid())
5426 return;
5427
5428 SmallVector<CXToken, 32> CXTokens;
5429 getTokens(CXXUnit, R, CXTokens);
5430
5431 if (CXTokens.empty())
5432 return;
5433
5434 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5435 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5436 *NumTokens = CXTokens.size();
5437}
5438
5439void clang_disposeTokens(CXTranslationUnit TU,
5440 CXToken *Tokens, unsigned NumTokens) {
5441 free(Tokens);
5442}
5443
5444} // end: extern "C"
5445
5446//===----------------------------------------------------------------------===//
5447// Token annotation APIs.
5448//===----------------------------------------------------------------------===//
5449
Guy Benyei11169dd2012-12-18 14:30:41 +00005450static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5451 CXCursor parent,
5452 CXClientData client_data);
5453static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5454 CXClientData client_data);
5455
5456namespace {
5457class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005458 CXToken *Tokens;
5459 CXCursor *Cursors;
5460 unsigned NumTokens;
5461 unsigned TokIdx;
5462 unsigned PreprocessingTokIdx;
5463 CursorVisitor AnnotateVis;
5464 SourceManager &SrcMgr;
5465 bool HasContextSensitiveKeywords;
5466
5467 struct PostChildrenInfo {
5468 CXCursor Cursor;
5469 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005470 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 unsigned BeforeChildrenTokenIdx;
5472 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005473 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005474
5475 CXToken &getTok(unsigned Idx) {
5476 assert(Idx < NumTokens);
5477 return Tokens[Idx];
5478 }
5479 const CXToken &getTok(unsigned Idx) const {
5480 assert(Idx < NumTokens);
5481 return Tokens[Idx];
5482 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005483 bool MoreTokens() const { return TokIdx < NumTokens; }
5484 unsigned NextToken() const { return TokIdx; }
5485 void AdvanceToken() { ++TokIdx; }
5486 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005487 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005488 }
5489 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005490 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 }
5492 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005493 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005494 }
5495
5496 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005497 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005498 SourceRange);
5499
5500public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005501 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005502 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005503 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005504 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005505 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005506 AnnotateTokensVisitor, this,
5507 /*VisitPreprocessorLast=*/true,
5508 /*VisitIncludedEntities=*/false,
5509 RegionOfInterest,
5510 /*VisitDeclsOnly=*/false,
5511 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005512 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005513 HasContextSensitiveKeywords(false) { }
5514
5515 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5516 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5517 bool postVisitChildren(CXCursor cursor);
5518 void AnnotateTokens();
5519
5520 /// \brief Determine whether the annotator saw any cursors that have
5521 /// context-sensitive keywords.
5522 bool hasContextSensitiveKeywords() const {
5523 return HasContextSensitiveKeywords;
5524 }
5525
5526 ~AnnotateTokensWorker() {
5527 assert(PostChildrenInfos.empty());
5528 }
5529};
5530}
5531
5532void AnnotateTokensWorker::AnnotateTokens() {
5533 // Walk the AST within the region of interest, annotating tokens
5534 // along the way.
5535 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005536}
Guy Benyei11169dd2012-12-18 14:30:41 +00005537
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005538static inline void updateCursorAnnotation(CXCursor &Cursor,
5539 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005540 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005541 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005542 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005543}
5544
5545/// \brief It annotates and advances tokens with a cursor until the comparison
5546//// between the cursor location and the source range is the same as
5547/// \arg compResult.
5548///
5549/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5550/// Pass RangeOverlap to annotate tokens inside a range.
5551void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5552 RangeComparisonResult compResult,
5553 SourceRange range) {
5554 while (MoreTokens()) {
5555 const unsigned I = NextToken();
5556 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005557 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5558 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005559
5560 SourceLocation TokLoc = GetTokenLoc(I);
5561 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005562 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005563 AdvanceToken();
5564 continue;
5565 }
5566 break;
5567 }
5568}
5569
5570/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005571/// \returns true if it advanced beyond all macro tokens, false otherwise.
5572bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005573 CXCursor updateC,
5574 RangeComparisonResult compResult,
5575 SourceRange range) {
5576 assert(MoreTokens());
5577 assert(isFunctionMacroToken(NextToken()) &&
5578 "Should be called only for macro arg tokens");
5579
5580 // This works differently than annotateAndAdvanceTokens; because expanded
5581 // macro arguments can have arbitrary translation-unit source order, we do not
5582 // advance the token index one by one until a token fails the range test.
5583 // We only advance once past all of the macro arg tokens if all of them
5584 // pass the range test. If one of them fails we keep the token index pointing
5585 // at the start of the macro arg tokens so that the failing token will be
5586 // annotated by a subsequent annotation try.
5587
5588 bool atLeastOneCompFail = false;
5589
5590 unsigned I = NextToken();
5591 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5592 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5593 if (TokLoc.isFileID())
5594 continue; // not macro arg token, it's parens or comma.
5595 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5596 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5597 Cursors[I] = updateC;
5598 } else
5599 atLeastOneCompFail = true;
5600 }
5601
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005602 if (atLeastOneCompFail)
5603 return false;
5604
5605 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5606 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005607}
5608
5609enum CXChildVisitResult
5610AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005611 SourceRange cursorRange = getRawCursorExtent(cursor);
5612 if (cursorRange.isInvalid())
5613 return CXChildVisit_Recurse;
5614
5615 if (!HasContextSensitiveKeywords) {
5616 // Objective-C properties can have context-sensitive keywords.
5617 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005618 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005619 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5620 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5621 }
5622 // Objective-C methods can have context-sensitive keywords.
5623 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5624 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005625 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005626 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5627 if (Method->getObjCDeclQualifier())
5628 HasContextSensitiveKeywords = true;
5629 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005630 for (const auto *P : Method->params()) {
5631 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005632 HasContextSensitiveKeywords = true;
5633 break;
5634 }
5635 }
5636 }
5637 }
5638 }
5639 // C++ methods can have context-sensitive keywords.
5640 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005641 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005642 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5643 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5644 HasContextSensitiveKeywords = true;
5645 }
5646 }
5647 // C++ classes can have context-sensitive keywords.
5648 else if (cursor.kind == CXCursor_StructDecl ||
5649 cursor.kind == CXCursor_ClassDecl ||
5650 cursor.kind == CXCursor_ClassTemplate ||
5651 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005652 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 if (D->hasAttr<FinalAttr>())
5654 HasContextSensitiveKeywords = true;
5655 }
5656 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005657
5658 // Don't override a property annotation with its getter/setter method.
5659 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5660 parent.kind == CXCursor_ObjCPropertyDecl)
5661 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005662
5663 if (clang_isPreprocessing(cursor.kind)) {
5664 // Items in the preprocessing record are kept separate from items in
5665 // declarations, so we keep a separate token index.
5666 unsigned SavedTokIdx = TokIdx;
5667 TokIdx = PreprocessingTokIdx;
5668
5669 // Skip tokens up until we catch up to the beginning of the preprocessing
5670 // entry.
5671 while (MoreTokens()) {
5672 const unsigned I = NextToken();
5673 SourceLocation TokLoc = GetTokenLoc(I);
5674 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5675 case RangeBefore:
5676 AdvanceToken();
5677 continue;
5678 case RangeAfter:
5679 case RangeOverlap:
5680 break;
5681 }
5682 break;
5683 }
5684
5685 // Look at all of the tokens within this range.
5686 while (MoreTokens()) {
5687 const unsigned I = NextToken();
5688 SourceLocation TokLoc = GetTokenLoc(I);
5689 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5690 case RangeBefore:
5691 llvm_unreachable("Infeasible");
5692 case RangeAfter:
5693 break;
5694 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005695 // For macro expansions, just note where the beginning of the macro
5696 // expansion occurs.
5697 if (cursor.kind == CXCursor_MacroExpansion) {
5698 if (TokLoc == cursorRange.getBegin())
5699 Cursors[I] = cursor;
5700 AdvanceToken();
5701 break;
5702 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005703 // We may have already annotated macro names inside macro definitions.
5704 if (Cursors[I].kind != CXCursor_MacroExpansion)
5705 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005706 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005707 continue;
5708 }
5709 break;
5710 }
5711
5712 // Save the preprocessing token index; restore the non-preprocessing
5713 // token index.
5714 PreprocessingTokIdx = TokIdx;
5715 TokIdx = SavedTokIdx;
5716 return CXChildVisit_Recurse;
5717 }
5718
5719 if (cursorRange.isInvalid())
5720 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005721
5722 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005723 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 const enum CXCursorKind K = clang_getCursorKind(parent);
5725 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005726 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5727 // Attributes are annotated out-of-order, skip tokens until we reach it.
5728 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005729 ? clang_getNullCursor() : parent;
5730
5731 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5732
5733 // Avoid having the cursor of an expression "overwrite" the annotation of the
5734 // variable declaration that it belongs to.
5735 // This can happen for C++ constructor expressions whose range generally
5736 // include the variable declaration, e.g.:
5737 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005738 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005739 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005740 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005741 const unsigned I = NextToken();
5742 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5743 E->getLocStart() == D->getLocation() &&
5744 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005745 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 AdvanceToken();
5747 }
5748 }
5749 }
5750
5751 // Before recursing into the children keep some state that we are going
5752 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5753 // extra work after the child nodes are visited.
5754 // Note that we don't call VisitChildren here to avoid traversing statements
5755 // code-recursively which can blow the stack.
5756
5757 PostChildrenInfo Info;
5758 Info.Cursor = cursor;
5759 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005760 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 Info.BeforeChildrenTokenIdx = NextToken();
5762 PostChildrenInfos.push_back(Info);
5763
5764 return CXChildVisit_Recurse;
5765}
5766
5767bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5768 if (PostChildrenInfos.empty())
5769 return false;
5770 const PostChildrenInfo &Info = PostChildrenInfos.back();
5771 if (!clang_equalCursors(Info.Cursor, cursor))
5772 return false;
5773
5774 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5775 const unsigned AfterChildren = NextToken();
5776 SourceRange cursorRange = Info.CursorRange;
5777
5778 // Scan the tokens that are at the end of the cursor, but are not captured
5779 // but the child cursors.
5780 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5781
5782 // Scan the tokens that are at the beginning of the cursor, but are not
5783 // capture by the child cursors.
5784 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5785 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5786 break;
5787
5788 Cursors[I] = cursor;
5789 }
5790
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005791 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5792 // encountered the attribute cursor.
5793 if (clang_isAttribute(cursor.kind))
5794 TokIdx = Info.BeforeReachingCursorIdx;
5795
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 PostChildrenInfos.pop_back();
5797 return false;
5798}
5799
5800static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5801 CXCursor parent,
5802 CXClientData client_data) {
5803 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5804}
5805
5806static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5807 CXClientData client_data) {
5808 return static_cast<AnnotateTokensWorker*>(client_data)->
5809 postVisitChildren(cursor);
5810}
5811
5812namespace {
5813
5814/// \brief Uses the macro expansions in the preprocessing record to find
5815/// and mark tokens that are macro arguments. This info is used by the
5816/// AnnotateTokensWorker.
5817class MarkMacroArgTokensVisitor {
5818 SourceManager &SM;
5819 CXToken *Tokens;
5820 unsigned NumTokens;
5821 unsigned CurIdx;
5822
5823public:
5824 MarkMacroArgTokensVisitor(SourceManager &SM,
5825 CXToken *tokens, unsigned numTokens)
5826 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5827
5828 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5829 if (cursor.kind != CXCursor_MacroExpansion)
5830 return CXChildVisit_Continue;
5831
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005832 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005833 if (macroRange.getBegin() == macroRange.getEnd())
5834 return CXChildVisit_Continue; // it's not a function macro.
5835
5836 for (; CurIdx < NumTokens; ++CurIdx) {
5837 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5838 macroRange.getBegin()))
5839 break;
5840 }
5841
5842 if (CurIdx == NumTokens)
5843 return CXChildVisit_Break;
5844
5845 for (; CurIdx < NumTokens; ++CurIdx) {
5846 SourceLocation tokLoc = getTokenLoc(CurIdx);
5847 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5848 break;
5849
5850 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5851 }
5852
5853 if (CurIdx == NumTokens)
5854 return CXChildVisit_Break;
5855
5856 return CXChildVisit_Continue;
5857 }
5858
5859private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005860 CXToken &getTok(unsigned Idx) {
5861 assert(Idx < NumTokens);
5862 return Tokens[Idx];
5863 }
5864 const CXToken &getTok(unsigned Idx) const {
5865 assert(Idx < NumTokens);
5866 return Tokens[Idx];
5867 }
5868
Guy Benyei11169dd2012-12-18 14:30:41 +00005869 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005870 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005871 }
5872
5873 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5874 // The third field is reserved and currently not used. Use it here
5875 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005876 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005877 }
5878};
5879
5880} // end anonymous namespace
5881
5882static CXChildVisitResult
5883MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5884 CXClientData client_data) {
5885 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5886 parent);
5887}
5888
5889namespace {
5890 struct clang_annotateTokens_Data {
5891 CXTranslationUnit TU;
5892 ASTUnit *CXXUnit;
5893 CXToken *Tokens;
5894 unsigned NumTokens;
5895 CXCursor *Cursors;
5896 };
5897}
5898
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005899/// \brief Used by \c annotatePreprocessorTokens.
5900/// \returns true if lexing was finished, false otherwise.
5901static bool lexNext(Lexer &Lex, Token &Tok,
5902 unsigned &NextIdx, unsigned NumTokens) {
5903 if (NextIdx >= NumTokens)
5904 return true;
5905
5906 ++NextIdx;
5907 Lex.LexFromRawLexer(Tok);
5908 if (Tok.is(tok::eof))
5909 return true;
5910
5911 return false;
5912}
5913
Guy Benyei11169dd2012-12-18 14:30:41 +00005914static void annotatePreprocessorTokens(CXTranslationUnit TU,
5915 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005916 CXCursor *Cursors,
5917 CXToken *Tokens,
5918 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005919 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005920
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005921 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5923 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005924 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005925 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005926 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005927
5928 if (BeginLocInfo.first != EndLocInfo.first)
5929 return;
5930
5931 StringRef Buffer;
5932 bool Invalid = false;
5933 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5934 if (Buffer.empty() || Invalid)
5935 return;
5936
5937 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5938 CXXUnit->getASTContext().getLangOpts(),
5939 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5940 Buffer.end());
5941 Lex.SetCommentRetentionState(true);
5942
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005943 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005944 // Lex tokens in raw mode until we hit the end of the range, to avoid
5945 // entering #includes or expanding macros.
5946 while (true) {
5947 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005948 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5949 break;
5950 unsigned TokIdx = NextIdx-1;
5951 assert(Tok.getLocation() ==
5952 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005953
5954 reprocess:
5955 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005956 // We have found a preprocessing directive. Annotate the tokens
5957 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005958 //
5959 // FIXME: Some simple tests here could identify macro definitions and
5960 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005961
5962 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005963 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5964 break;
5965
Craig Topper69186e72014-06-08 08:38:04 +00005966 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005967 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005968 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5969 break;
5970
5971 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005972 IdentifierInfo &II =
5973 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005974 SourceLocation MappedTokLoc =
5975 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5976 MI = getMacroInfo(II, MappedTokLoc, TU);
5977 }
5978 }
5979
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005980 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005981 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005982 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5983 finished = true;
5984 break;
5985 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005986 // If we are in a macro definition, check if the token was ever a
5987 // macro name and annotate it if that's the case.
5988 if (MI) {
5989 SourceLocation SaveLoc = Tok.getLocation();
5990 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5991 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5992 Tok.setLocation(SaveLoc);
5993 if (MacroDef)
5994 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5995 Tok.getLocation(), TU);
5996 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005997 } while (!Tok.isAtStartOfLine());
5998
5999 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6000 assert(TokIdx <= LastIdx);
6001 SourceLocation EndLoc =
6002 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6003 CXCursor Cursor =
6004 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6005
6006 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006007 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006008
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006009 if (finished)
6010 break;
6011 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006013 }
6014}
6015
6016// This gets run a separate thread to avoid stack blowout.
6017static void clang_annotateTokensImpl(void *UserData) {
6018 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6019 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6020 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6021 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6022 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6023
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006024 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006025 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6026 setThreadBackgroundPriority();
6027
6028 // Determine the region of interest, which contains all of the tokens.
6029 SourceRange RegionOfInterest;
6030 RegionOfInterest.setBegin(
6031 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6032 RegionOfInterest.setEnd(
6033 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6034 Tokens[NumTokens-1])));
6035
Guy Benyei11169dd2012-12-18 14:30:41 +00006036 // Relex the tokens within the source range to look for preprocessing
6037 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006038 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006039
6040 // If begin location points inside a macro argument, set it to the expansion
6041 // location so we can have the full context when annotating semantically.
6042 {
6043 SourceManager &SM = CXXUnit->getSourceManager();
6044 SourceLocation Loc =
6045 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6046 if (Loc.isMacroID())
6047 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6048 }
6049
Guy Benyei11169dd2012-12-18 14:30:41 +00006050 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6051 // Search and mark tokens that are macro argument expansions.
6052 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6053 Tokens, NumTokens);
6054 CursorVisitor MacroArgMarker(TU,
6055 MarkMacroArgTokensVisitorDelegate, &Visitor,
6056 /*VisitPreprocessorLast=*/true,
6057 /*VisitIncludedEntities=*/false,
6058 RegionOfInterest);
6059 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6060 }
6061
6062 // Annotate all of the source locations in the region of interest that map to
6063 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006064 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006065
6066 // FIXME: We use a ridiculous stack size here because the data-recursion
6067 // algorithm uses a large stack frame than the non-data recursive version,
6068 // and AnnotationTokensWorker currently transforms the data-recursion
6069 // algorithm back into a traditional recursion by explicitly calling
6070 // VisitChildren(). We will need to remove this explicit recursive call.
6071 W.AnnotateTokens();
6072
6073 // If we ran into any entities that involve context-sensitive keywords,
6074 // take another pass through the tokens to mark them as such.
6075 if (W.hasContextSensitiveKeywords()) {
6076 for (unsigned I = 0; I != NumTokens; ++I) {
6077 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6078 continue;
6079
6080 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6081 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006082 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006083 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6084 if (Property->getPropertyAttributesAsWritten() != 0 &&
6085 llvm::StringSwitch<bool>(II->getName())
6086 .Case("readonly", true)
6087 .Case("assign", true)
6088 .Case("unsafe_unretained", true)
6089 .Case("readwrite", true)
6090 .Case("retain", true)
6091 .Case("copy", true)
6092 .Case("nonatomic", true)
6093 .Case("atomic", true)
6094 .Case("getter", true)
6095 .Case("setter", true)
6096 .Case("strong", true)
6097 .Case("weak", true)
6098 .Default(false))
6099 Tokens[I].int_data[0] = CXToken_Keyword;
6100 }
6101 continue;
6102 }
6103
6104 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6105 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6106 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6107 if (llvm::StringSwitch<bool>(II->getName())
6108 .Case("in", true)
6109 .Case("out", true)
6110 .Case("inout", true)
6111 .Case("oneway", true)
6112 .Case("bycopy", true)
6113 .Case("byref", true)
6114 .Default(false))
6115 Tokens[I].int_data[0] = CXToken_Keyword;
6116 continue;
6117 }
6118
6119 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6120 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6121 Tokens[I].int_data[0] = CXToken_Keyword;
6122 continue;
6123 }
6124 }
6125 }
6126}
6127
6128extern "C" {
6129
6130void clang_annotateTokens(CXTranslationUnit TU,
6131 CXToken *Tokens, unsigned NumTokens,
6132 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006133 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006134 LOG_BAD_TU(TU);
6135 return;
6136 }
6137 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006138 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006140 }
6141
6142 LOG_FUNC_SECTION {
6143 *Log << TU << ' ';
6144 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6145 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6146 *Log << clang_getRange(bloc, eloc);
6147 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006148
6149 // Any token we don't specifically annotate will have a NULL cursor.
6150 CXCursor C = clang_getNullCursor();
6151 for (unsigned I = 0; I != NumTokens; ++I)
6152 Cursors[I] = C;
6153
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006154 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006155 if (!CXXUnit)
6156 return;
6157
6158 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6159
6160 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6161 llvm::CrashRecoveryContext CRC;
6162 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6163 GetSafetyThreadStackSize() * 2)) {
6164 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6165 }
6166}
6167
6168} // end: extern "C"
6169
6170//===----------------------------------------------------------------------===//
6171// Operations for querying linkage of a cursor.
6172//===----------------------------------------------------------------------===//
6173
6174extern "C" {
6175CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6176 if (!clang_isDeclaration(cursor.kind))
6177 return CXLinkage_Invalid;
6178
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006179 const Decl *D = cxcursor::getCursorDecl(cursor);
6180 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006181 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006182 case NoLinkage:
6183 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006184 case InternalLinkage: return CXLinkage_Internal;
6185 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6186 case ExternalLinkage: return CXLinkage_External;
6187 };
6188
6189 return CXLinkage_Invalid;
6190}
6191} // end: extern "C"
6192
6193//===----------------------------------------------------------------------===//
6194// Operations for querying language of a cursor.
6195//===----------------------------------------------------------------------===//
6196
6197static CXLanguageKind getDeclLanguage(const Decl *D) {
6198 if (!D)
6199 return CXLanguage_C;
6200
6201 switch (D->getKind()) {
6202 default:
6203 break;
6204 case Decl::ImplicitParam:
6205 case Decl::ObjCAtDefsField:
6206 case Decl::ObjCCategory:
6207 case Decl::ObjCCategoryImpl:
6208 case Decl::ObjCCompatibleAlias:
6209 case Decl::ObjCImplementation:
6210 case Decl::ObjCInterface:
6211 case Decl::ObjCIvar:
6212 case Decl::ObjCMethod:
6213 case Decl::ObjCProperty:
6214 case Decl::ObjCPropertyImpl:
6215 case Decl::ObjCProtocol:
6216 return CXLanguage_ObjC;
6217 case Decl::CXXConstructor:
6218 case Decl::CXXConversion:
6219 case Decl::CXXDestructor:
6220 case Decl::CXXMethod:
6221 case Decl::CXXRecord:
6222 case Decl::ClassTemplate:
6223 case Decl::ClassTemplatePartialSpecialization:
6224 case Decl::ClassTemplateSpecialization:
6225 case Decl::Friend:
6226 case Decl::FriendTemplate:
6227 case Decl::FunctionTemplate:
6228 case Decl::LinkageSpec:
6229 case Decl::Namespace:
6230 case Decl::NamespaceAlias:
6231 case Decl::NonTypeTemplateParm:
6232 case Decl::StaticAssert:
6233 case Decl::TemplateTemplateParm:
6234 case Decl::TemplateTypeParm:
6235 case Decl::UnresolvedUsingTypename:
6236 case Decl::UnresolvedUsingValue:
6237 case Decl::Using:
6238 case Decl::UsingDirective:
6239 case Decl::UsingShadow:
6240 return CXLanguage_CPlusPlus;
6241 }
6242
6243 return CXLanguage_C;
6244}
6245
6246extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006247
6248static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6249 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6250 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006251
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006252 switch (D->getAvailability()) {
6253 case AR_Available:
6254 case AR_NotYetIntroduced:
6255 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006256 return getCursorAvailabilityForDecl(
6257 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006258 return CXAvailability_Available;
6259
6260 case AR_Deprecated:
6261 return CXAvailability_Deprecated;
6262
6263 case AR_Unavailable:
6264 return CXAvailability_NotAvailable;
6265 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006266
6267 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006268}
6269
Guy Benyei11169dd2012-12-18 14:30:41 +00006270enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6271 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006272 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6273 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006274
6275 return CXAvailability_Available;
6276}
6277
6278static CXVersion convertVersion(VersionTuple In) {
6279 CXVersion Out = { -1, -1, -1 };
6280 if (In.empty())
6281 return Out;
6282
6283 Out.Major = In.getMajor();
6284
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006285 Optional<unsigned> Minor = In.getMinor();
6286 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006287 Out.Minor = *Minor;
6288 else
6289 return Out;
6290
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006291 Optional<unsigned> Subminor = In.getSubminor();
6292 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006293 Out.Subminor = *Subminor;
6294
6295 return Out;
6296}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006297
6298static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6299 int *always_deprecated,
6300 CXString *deprecated_message,
6301 int *always_unavailable,
6302 CXString *unavailable_message,
6303 CXPlatformAvailability *availability,
6304 int availability_size) {
6305 bool HadAvailAttr = false;
6306 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006307 for (auto A : D->attrs()) {
6308 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006309 HadAvailAttr = true;
6310 if (always_deprecated)
6311 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006312 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006313 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006314 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006315 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006316 continue;
6317 }
6318
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006319 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006320 HadAvailAttr = true;
6321 if (always_unavailable)
6322 *always_unavailable = 1;
6323 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006324 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006325 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6326 }
6327 continue;
6328 }
6329
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006330 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006331 HadAvailAttr = true;
6332 if (N < availability_size) {
6333 availability[N].Platform
6334 = cxstring::createDup(Avail->getPlatform()->getName());
6335 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6336 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6337 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6338 availability[N].Unavailable = Avail->getUnavailable();
6339 availability[N].Message = cxstring::createDup(Avail->getMessage());
6340 }
6341 ++N;
6342 }
6343 }
6344
6345 if (!HadAvailAttr)
6346 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6347 return getCursorPlatformAvailabilityForDecl(
6348 cast<Decl>(EnumConst->getDeclContext()),
6349 always_deprecated,
6350 deprecated_message,
6351 always_unavailable,
6352 unavailable_message,
6353 availability,
6354 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006355
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006356 return N;
6357}
6358
Guy Benyei11169dd2012-12-18 14:30:41 +00006359int clang_getCursorPlatformAvailability(CXCursor cursor,
6360 int *always_deprecated,
6361 CXString *deprecated_message,
6362 int *always_unavailable,
6363 CXString *unavailable_message,
6364 CXPlatformAvailability *availability,
6365 int availability_size) {
6366 if (always_deprecated)
6367 *always_deprecated = 0;
6368 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006369 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006370 if (always_unavailable)
6371 *always_unavailable = 0;
6372 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006373 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006374
Guy Benyei11169dd2012-12-18 14:30:41 +00006375 if (!clang_isDeclaration(cursor.kind))
6376 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006377
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006378 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006379 if (!D)
6380 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006381
6382 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6383 deprecated_message,
6384 always_unavailable,
6385 unavailable_message,
6386 availability,
6387 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006388}
6389
6390void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6391 clang_disposeString(availability->Platform);
6392 clang_disposeString(availability->Message);
6393}
6394
6395CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6396 if (clang_isDeclaration(cursor.kind))
6397 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6398
6399 return CXLanguage_Invalid;
6400}
6401
6402 /// \brief If the given cursor is the "templated" declaration
6403 /// descibing a class or function template, return the class or
6404 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006405static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006406 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006407 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006408
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006409 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006410 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6411 return FunTmpl;
6412
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006413 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6415 return ClassTmpl;
6416
6417 return D;
6418}
6419
6420CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6421 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006422 if (const Decl *D = getCursorDecl(cursor)) {
6423 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006424 if (!DC)
6425 return clang_getNullCursor();
6426
6427 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6428 getCursorTU(cursor));
6429 }
6430 }
6431
6432 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006433 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006434 return MakeCXCursor(D, getCursorTU(cursor));
6435 }
6436
6437 return clang_getNullCursor();
6438}
6439
6440CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6441 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006442 if (const Decl *D = getCursorDecl(cursor)) {
6443 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006444 if (!DC)
6445 return clang_getNullCursor();
6446
6447 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6448 getCursorTU(cursor));
6449 }
6450 }
6451
6452 // FIXME: Note that we can't easily compute the lexical context of a
6453 // statement or expression, so we return nothing.
6454 return clang_getNullCursor();
6455}
6456
6457CXFile clang_getIncludedFile(CXCursor cursor) {
6458 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006459 return nullptr;
6460
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006461 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006462 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006463}
6464
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006465unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6466 if (C.kind != CXCursor_ObjCPropertyDecl)
6467 return CXObjCPropertyAttr_noattr;
6468
6469 unsigned Result = CXObjCPropertyAttr_noattr;
6470 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6471 ObjCPropertyDecl::PropertyAttributeKind Attr =
6472 PD->getPropertyAttributesAsWritten();
6473
6474#define SET_CXOBJCPROP_ATTR(A) \
6475 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6476 Result |= CXObjCPropertyAttr_##A
6477 SET_CXOBJCPROP_ATTR(readonly);
6478 SET_CXOBJCPROP_ATTR(getter);
6479 SET_CXOBJCPROP_ATTR(assign);
6480 SET_CXOBJCPROP_ATTR(readwrite);
6481 SET_CXOBJCPROP_ATTR(retain);
6482 SET_CXOBJCPROP_ATTR(copy);
6483 SET_CXOBJCPROP_ATTR(nonatomic);
6484 SET_CXOBJCPROP_ATTR(setter);
6485 SET_CXOBJCPROP_ATTR(atomic);
6486 SET_CXOBJCPROP_ATTR(weak);
6487 SET_CXOBJCPROP_ATTR(strong);
6488 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6489#undef SET_CXOBJCPROP_ATTR
6490
6491 return Result;
6492}
6493
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006494unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6495 if (!clang_isDeclaration(C.kind))
6496 return CXObjCDeclQualifier_None;
6497
6498 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6499 const Decl *D = getCursorDecl(C);
6500 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6501 QT = MD->getObjCDeclQualifier();
6502 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6503 QT = PD->getObjCDeclQualifier();
6504 if (QT == Decl::OBJC_TQ_None)
6505 return CXObjCDeclQualifier_None;
6506
6507 unsigned Result = CXObjCDeclQualifier_None;
6508 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6509 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6510 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6511 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6512 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6513 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6514
6515 return Result;
6516}
6517
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006518unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6519 if (!clang_isDeclaration(C.kind))
6520 return 0;
6521
6522 const Decl *D = getCursorDecl(C);
6523 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6524 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6525 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6526 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6527
6528 return 0;
6529}
6530
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006531unsigned clang_Cursor_isVariadic(CXCursor C) {
6532 if (!clang_isDeclaration(C.kind))
6533 return 0;
6534
6535 const Decl *D = getCursorDecl(C);
6536 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6537 return FD->isVariadic();
6538 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6539 return MD->isVariadic();
6540
6541 return 0;
6542}
6543
Guy Benyei11169dd2012-12-18 14:30:41 +00006544CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6545 if (!clang_isDeclaration(C.kind))
6546 return clang_getNullRange();
6547
6548 const Decl *D = getCursorDecl(C);
6549 ASTContext &Context = getCursorContext(C);
6550 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6551 if (!RC)
6552 return clang_getNullRange();
6553
6554 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6555}
6556
6557CXString clang_Cursor_getRawCommentText(CXCursor C) {
6558 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006559 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006560
6561 const Decl *D = getCursorDecl(C);
6562 ASTContext &Context = getCursorContext(C);
6563 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6564 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6565 StringRef();
6566
6567 // Don't duplicate the string because RawText points directly into source
6568 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006569 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006570}
6571
6572CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6573 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006574 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006575
6576 const Decl *D = getCursorDecl(C);
6577 const ASTContext &Context = getCursorContext(C);
6578 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6579
6580 if (RC) {
6581 StringRef BriefText = RC->getBriefText(Context);
6582
6583 // Don't duplicate the string because RawComment ensures that this memory
6584 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006585 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006586 }
6587
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006588 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006589}
6590
Guy Benyei11169dd2012-12-18 14:30:41 +00006591CXModule clang_Cursor_getModule(CXCursor C) {
6592 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006593 if (const ImportDecl *ImportD =
6594 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006595 return ImportD->getImportedModule();
6596 }
6597
Craig Topper69186e72014-06-08 08:38:04 +00006598 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006599}
6600
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006601CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6602 if (isNotUsableTU(TU)) {
6603 LOG_BAD_TU(TU);
6604 return nullptr;
6605 }
6606 if (!File)
6607 return nullptr;
6608 FileEntry *FE = static_cast<FileEntry *>(File);
6609
6610 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6611 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6612 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6613
6614 if (Module *Mod = Header.getModule()) {
6615 if (Header.getRole() != ModuleMap::ExcludedHeader)
6616 return Mod;
6617 }
6618 return nullptr;
6619}
6620
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006621CXFile clang_Module_getASTFile(CXModule CXMod) {
6622 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006623 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006624 Module *Mod = static_cast<Module*>(CXMod);
6625 return const_cast<FileEntry *>(Mod->getASTFile());
6626}
6627
Guy Benyei11169dd2012-12-18 14:30:41 +00006628CXModule clang_Module_getParent(CXModule CXMod) {
6629 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006630 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006631 Module *Mod = static_cast<Module*>(CXMod);
6632 return Mod->Parent;
6633}
6634
6635CXString clang_Module_getName(CXModule CXMod) {
6636 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006637 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006638 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006639 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006640}
6641
6642CXString clang_Module_getFullName(CXModule CXMod) {
6643 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006644 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006645 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006646 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006647}
6648
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006649int clang_Module_isSystem(CXModule CXMod) {
6650 if (!CXMod)
6651 return 0;
6652 Module *Mod = static_cast<Module*>(CXMod);
6653 return Mod->IsSystem;
6654}
6655
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006656unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6657 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006658 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006659 LOG_BAD_TU(TU);
6660 return 0;
6661 }
6662 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006663 return 0;
6664 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006665 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6666 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6667 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006668}
6669
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006670CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6671 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006672 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006673 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006674 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006675 }
6676 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006677 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006678 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006679 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006680
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006681 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6682 if (Index < TopHeaders.size())
6683 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006684
Craig Topper69186e72014-06-08 08:38:04 +00006685 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006686}
6687
6688} // end: extern "C"
6689
6690//===----------------------------------------------------------------------===//
6691// C++ AST instrospection.
6692//===----------------------------------------------------------------------===//
6693
6694extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006695unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6696 if (!clang_isDeclaration(C.kind))
6697 return 0;
6698
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006699 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006700 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006701 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006702 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6703}
6704
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006705unsigned clang_CXXMethod_isConst(CXCursor C) {
6706 if (!clang_isDeclaration(C.kind))
6707 return 0;
6708
6709 const Decl *D = cxcursor::getCursorDecl(C);
6710 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006711 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006712 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6713}
6714
Guy Benyei11169dd2012-12-18 14:30:41 +00006715unsigned clang_CXXMethod_isStatic(CXCursor C) {
6716 if (!clang_isDeclaration(C.kind))
6717 return 0;
6718
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006719 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006720 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006721 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006722 return (Method && Method->isStatic()) ? 1 : 0;
6723}
6724
6725unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6726 if (!clang_isDeclaration(C.kind))
6727 return 0;
6728
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006729 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006730 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006731 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006732 return (Method && Method->isVirtual()) ? 1 : 0;
6733}
6734} // end: extern "C"
6735
6736//===----------------------------------------------------------------------===//
6737// Attribute introspection.
6738//===----------------------------------------------------------------------===//
6739
6740extern "C" {
6741CXType clang_getIBOutletCollectionType(CXCursor C) {
6742 if (C.kind != CXCursor_IBOutletCollectionAttr)
6743 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6744
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006745 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006746 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6747
6748 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6749}
6750} // end: extern "C"
6751
6752//===----------------------------------------------------------------------===//
6753// Inspecting memory usage.
6754//===----------------------------------------------------------------------===//
6755
6756typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6757
6758static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6759 enum CXTUResourceUsageKind k,
6760 unsigned long amount) {
6761 CXTUResourceUsageEntry entry = { k, amount };
6762 entries.push_back(entry);
6763}
6764
6765extern "C" {
6766
6767const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6768 const char *str = "";
6769 switch (kind) {
6770 case CXTUResourceUsage_AST:
6771 str = "ASTContext: expressions, declarations, and types";
6772 break;
6773 case CXTUResourceUsage_Identifiers:
6774 str = "ASTContext: identifiers";
6775 break;
6776 case CXTUResourceUsage_Selectors:
6777 str = "ASTContext: selectors";
6778 break;
6779 case CXTUResourceUsage_GlobalCompletionResults:
6780 str = "Code completion: cached global results";
6781 break;
6782 case CXTUResourceUsage_SourceManagerContentCache:
6783 str = "SourceManager: content cache allocator";
6784 break;
6785 case CXTUResourceUsage_AST_SideTables:
6786 str = "ASTContext: side tables";
6787 break;
6788 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6789 str = "SourceManager: malloc'ed memory buffers";
6790 break;
6791 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6792 str = "SourceManager: mmap'ed memory buffers";
6793 break;
6794 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6795 str = "ExternalASTSource: malloc'ed memory buffers";
6796 break;
6797 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6798 str = "ExternalASTSource: mmap'ed memory buffers";
6799 break;
6800 case CXTUResourceUsage_Preprocessor:
6801 str = "Preprocessor: malloc'ed memory";
6802 break;
6803 case CXTUResourceUsage_PreprocessingRecord:
6804 str = "Preprocessor: PreprocessingRecord";
6805 break;
6806 case CXTUResourceUsage_SourceManager_DataStructures:
6807 str = "SourceManager: data structures and tables";
6808 break;
6809 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6810 str = "Preprocessor: header search tables";
6811 break;
6812 }
6813 return str;
6814}
6815
6816CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006817 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006818 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006819 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006820 return usage;
6821 }
6822
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006823 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006824 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006825 ASTContext &astContext = astUnit->getASTContext();
6826
6827 // How much memory is used by AST nodes and types?
6828 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6829 (unsigned long) astContext.getASTAllocatedMemory());
6830
6831 // How much memory is used by identifiers?
6832 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6833 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6834
6835 // How much memory is used for selectors?
6836 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6837 (unsigned long) astContext.Selectors.getTotalMemory());
6838
6839 // How much memory is used by ASTContext's side tables?
6840 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6841 (unsigned long) astContext.getSideTableAllocatedMemory());
6842
6843 // How much memory is used for caching global code completion results?
6844 unsigned long completionBytes = 0;
6845 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006846 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006847 completionBytes = completionAllocator->getTotalMemory();
6848 }
6849 createCXTUResourceUsageEntry(*entries,
6850 CXTUResourceUsage_GlobalCompletionResults,
6851 completionBytes);
6852
6853 // How much memory is being used by SourceManager's content cache?
6854 createCXTUResourceUsageEntry(*entries,
6855 CXTUResourceUsage_SourceManagerContentCache,
6856 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6857
6858 // How much memory is being used by the MemoryBuffer's in SourceManager?
6859 const SourceManager::MemoryBufferSizes &srcBufs =
6860 astUnit->getSourceManager().getMemoryBufferSizes();
6861
6862 createCXTUResourceUsageEntry(*entries,
6863 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6864 (unsigned long) srcBufs.malloc_bytes);
6865 createCXTUResourceUsageEntry(*entries,
6866 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6867 (unsigned long) srcBufs.mmap_bytes);
6868 createCXTUResourceUsageEntry(*entries,
6869 CXTUResourceUsage_SourceManager_DataStructures,
6870 (unsigned long) astContext.getSourceManager()
6871 .getDataStructureSizes());
6872
6873 // How much memory is being used by the ExternalASTSource?
6874 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6875 const ExternalASTSource::MemoryBufferSizes &sizes =
6876 esrc->getMemoryBufferSizes();
6877
6878 createCXTUResourceUsageEntry(*entries,
6879 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6880 (unsigned long) sizes.malloc_bytes);
6881 createCXTUResourceUsageEntry(*entries,
6882 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6883 (unsigned long) sizes.mmap_bytes);
6884 }
6885
6886 // How much memory is being used by the Preprocessor?
6887 Preprocessor &pp = astUnit->getPreprocessor();
6888 createCXTUResourceUsageEntry(*entries,
6889 CXTUResourceUsage_Preprocessor,
6890 pp.getTotalMemory());
6891
6892 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6893 createCXTUResourceUsageEntry(*entries,
6894 CXTUResourceUsage_PreprocessingRecord,
6895 pRec->getTotalMemory());
6896 }
6897
6898 createCXTUResourceUsageEntry(*entries,
6899 CXTUResourceUsage_Preprocessor_HeaderSearch,
6900 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006901
Guy Benyei11169dd2012-12-18 14:30:41 +00006902 CXTUResourceUsage usage = { (void*) entries.get(),
6903 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006904 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006905 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006906 return usage;
6907}
6908
6909void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6910 if (usage.data)
6911 delete (MemUsageEntries*) usage.data;
6912}
6913
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006914CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6915 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006916 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006917 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006918
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006919 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006920 LOG_BAD_TU(TU);
6921 return skipped;
6922 }
6923
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006924 if (!file)
6925 return skipped;
6926
6927 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6928 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6929 if (!ppRec)
6930 return skipped;
6931
6932 ASTContext &Ctx = astUnit->getASTContext();
6933 SourceManager &sm = Ctx.getSourceManager();
6934 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6935 FileID wantedFileID = sm.translateFile(fileEntry);
6936
6937 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6938 std::vector<SourceRange> wantedRanges;
6939 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6940 i != ei; ++i) {
6941 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6942 wantedRanges.push_back(*i);
6943 }
6944
6945 skipped->count = wantedRanges.size();
6946 skipped->ranges = new CXSourceRange[skipped->count];
6947 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6948 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6949
6950 return skipped;
6951}
6952
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006953void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6954 if (ranges) {
6955 delete[] ranges->ranges;
6956 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006957 }
6958}
6959
Guy Benyei11169dd2012-12-18 14:30:41 +00006960} // end extern "C"
6961
6962void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6963 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6964 for (unsigned I = 0; I != Usage.numEntries; ++I)
6965 fprintf(stderr, " %s: %lu\n",
6966 clang_getTUResourceUsageName(Usage.entries[I].kind),
6967 Usage.entries[I].amount);
6968
6969 clang_disposeCXTUResourceUsage(Usage);
6970}
6971
6972//===----------------------------------------------------------------------===//
6973// Misc. utility functions.
6974//===----------------------------------------------------------------------===//
6975
6976/// Default to using an 8 MB stack size on "safety" threads.
6977static unsigned SafetyStackThreadSize = 8 << 20;
6978
6979namespace clang {
6980
6981bool RunSafely(llvm::CrashRecoveryContext &CRC,
6982 void (*Fn)(void*), void *UserData,
6983 unsigned Size) {
6984 if (!Size)
6985 Size = GetSafetyThreadStackSize();
6986 if (Size)
6987 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6988 return CRC.RunSafely(Fn, UserData);
6989}
6990
6991unsigned GetSafetyThreadStackSize() {
6992 return SafetyStackThreadSize;
6993}
6994
6995void SetSafetyThreadStackSize(unsigned Value) {
6996 SafetyStackThreadSize = Value;
6997}
6998
6999}
7000
7001void clang::setThreadBackgroundPriority() {
7002 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7003 return;
7004
Alp Toker1a86ad22014-07-06 06:24:00 +00007005#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007006 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7007#endif
7008}
7009
7010void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7011 if (!Unit)
7012 return;
7013
7014 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7015 DEnd = Unit->stored_diag_end();
7016 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007017 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007018 CXString Msg = clang_formatDiagnostic(&Diag,
7019 clang_defaultDiagnosticDisplayOptions());
7020 fprintf(stderr, "%s\n", clang_getCString(Msg));
7021 clang_disposeString(Msg);
7022 }
7023#ifdef LLVM_ON_WIN32
7024 // On Windows, force a flush, since there may be multiple copies of
7025 // stderr and stdout in the file system, all with different buffers
7026 // but writing to the same device.
7027 fflush(stderr);
7028#endif
7029}
7030
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007031MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7032 SourceLocation MacroDefLoc,
7033 CXTranslationUnit TU){
7034 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007035 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007036 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007037 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007038
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007039 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007040 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007041 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007042 if (MD) {
7043 for (MacroDirective::DefInfo
7044 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7045 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7046 return Def.getMacroInfo();
7047 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007048 }
7049
Craig Topper69186e72014-06-08 08:38:04 +00007050 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007051}
7052
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007053const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7054 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007055 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007056 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007057 const IdentifierInfo *II = MacroDef->getName();
7058 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007059 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007060
7061 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7062}
7063
7064MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7065 const Token &Tok,
7066 CXTranslationUnit TU) {
7067 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007068 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007069 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007070 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007071
7072 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007073 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007074 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7075 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007076 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007077
7078 // Check that the token is inside the definition and not its argument list.
7079 SourceManager &SM = Unit->getSourceManager();
7080 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007081 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007082 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007083 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007084
7085 Preprocessor &PP = Unit->getPreprocessor();
7086 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7087 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007088 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007089
Alp Toker2d57cea2014-05-17 04:53:25 +00007090 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007091 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007092 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007093
7094 // Check that the identifier is not one of the macro arguments.
7095 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007096 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007097
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007098 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7099 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007100 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007101
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007102 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007103}
7104
7105MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7106 SourceLocation Loc,
7107 CXTranslationUnit TU) {
7108 if (Loc.isInvalid() || !MI || !TU)
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;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007113 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007114 Preprocessor &PP = Unit->getPreprocessor();
7115 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007116 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007117 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7118 Token Tok;
7119 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007120 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007121
7122 return checkForMacroInMacroDefinition(MI, Tok, TU);
7123}
7124
Guy Benyei11169dd2012-12-18 14:30:41 +00007125extern "C" {
7126
7127CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007128 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007129}
7130
7131} // end: extern "C"
7132
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007133Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7134 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007135 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007136 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007137 if (Unit->isMainFileAST())
7138 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007139 return *this;
7140 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007141 } else {
7142 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007143 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007144 return *this;
7145}
7146
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007147Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7148 *this << FE->getName();
7149 return *this;
7150}
7151
7152Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7153 CXString cursorName = clang_getCursorDisplayName(cursor);
7154 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7155 clang_disposeString(cursorName);
7156 return *this;
7157}
7158
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007159Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7160 CXFile File;
7161 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007162 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007163 CXString FileName = clang_getFileName(File);
7164 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7165 clang_disposeString(FileName);
7166 return *this;
7167}
7168
7169Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7170 CXSourceLocation BLoc = clang_getRangeStart(range);
7171 CXSourceLocation ELoc = clang_getRangeEnd(range);
7172
7173 CXFile BFile;
7174 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007175 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007176
7177 CXFile EFile;
7178 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007179 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007180
7181 CXString BFileName = clang_getFileName(BFile);
7182 if (BFile == EFile) {
7183 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7184 BLine, BColumn, ELine, EColumn);
7185 } else {
7186 CXString EFileName = clang_getFileName(EFile);
7187 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7188 BLine, BColumn)
7189 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7190 ELine, EColumn);
7191 clang_disposeString(EFileName);
7192 }
7193 clang_disposeString(BFileName);
7194 return *this;
7195}
7196
7197Logger &cxindex::Logger::operator<<(CXString Str) {
7198 *this << clang_getCString(Str);
7199 return *this;
7200}
7201
7202Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7203 LogOS << Fmt;
7204 return *this;
7205}
7206
Chandler Carruth37ad2582014-06-27 15:14:39 +00007207static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7208
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007209cxindex::Logger::~Logger() {
7210 LogOS.flush();
7211
Chandler Carruth37ad2582014-06-27 15:14:39 +00007212 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007213
7214 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7215
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007216 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007217 OS << "[libclang:" << Name << ':';
7218
Alp Toker1a86ad22014-07-06 06:24:00 +00007219#ifdef USE_DARWIN_THREADS
7220 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007221 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7222 OS << tid << ':';
7223#endif
7224
7225 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7226 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7227 OS << Msg.str() << '\n';
7228
7229 if (Trace) {
7230 llvm::sys::PrintStackTrace(stderr);
7231 OS << "--------------------------------------------------\n";
7232 }
7233}