blob: b2a36a394ea8eeac491e10daa2151e95827ede6d [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:
1263 break;
1264 }
1265
1266 return false;
1267}
1268
1269bool
1270CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1271 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1272 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1273 Qualifiers.push_back(Qualifier);
1274
1275 while (!Qualifiers.empty()) {
1276 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1277 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1278 switch (NNS->getKind()) {
1279 case NestedNameSpecifier::Namespace:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::NamespaceAlias:
1288 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1289 Q.getLocalBeginLoc(),
1290 TU)))
1291 return true;
1292
1293 break;
1294
1295 case NestedNameSpecifier::TypeSpec:
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 if (Visit(Q.getTypeLoc()))
1298 return true;
1299
1300 break;
1301
1302 case NestedNameSpecifier::Global:
1303 case NestedNameSpecifier::Identifier:
1304 break;
1305 }
1306 }
1307
1308 return false;
1309}
1310
1311bool CursorVisitor::VisitTemplateParameters(
1312 const TemplateParameterList *Params) {
1313 if (!Params)
1314 return false;
1315
1316 for (TemplateParameterList::const_iterator P = Params->begin(),
1317 PEnd = Params->end();
1318 P != PEnd; ++P) {
1319 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1320 return true;
1321 }
1322
1323 return false;
1324}
1325
1326bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1327 switch (Name.getKind()) {
1328 case TemplateName::Template:
1329 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1330
1331 case TemplateName::OverloadedTemplate:
1332 // Visit the overloaded template set.
1333 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1334 return true;
1335
1336 return false;
1337
1338 case TemplateName::DependentTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return false;
1341
1342 case TemplateName::QualifiedTemplate:
1343 // FIXME: Visit nested-name-specifier.
1344 return Visit(MakeCursorTemplateRef(
1345 Name.getAsQualifiedTemplateName()->getDecl(),
1346 Loc, TU));
1347
1348 case TemplateName::SubstTemplateTemplateParm:
1349 return Visit(MakeCursorTemplateRef(
1350 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1351 Loc, TU));
1352
1353 case TemplateName::SubstTemplateTemplateParmPack:
1354 return Visit(MakeCursorTemplateRef(
1355 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1356 Loc, TU));
1357 }
1358
1359 llvm_unreachable("Invalid TemplateName::Kind!");
1360}
1361
1362bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1363 switch (TAL.getArgument().getKind()) {
1364 case TemplateArgument::Null:
1365 case TemplateArgument::Integral:
1366 case TemplateArgument::Pack:
1367 return false;
1368
1369 case TemplateArgument::Type:
1370 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1371 return Visit(TSInfo->getTypeLoc());
1372 return false;
1373
1374 case TemplateArgument::Declaration:
1375 if (Expr *E = TAL.getSourceDeclExpression())
1376 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1377 return false;
1378
1379 case TemplateArgument::NullPtr:
1380 if (Expr *E = TAL.getSourceNullPtrExpression())
1381 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1382 return false;
1383
1384 case TemplateArgument::Expression:
1385 if (Expr *E = TAL.getSourceExpression())
1386 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1387 return false;
1388
1389 case TemplateArgument::Template:
1390 case TemplateArgument::TemplateExpansion:
1391 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1392 return true;
1393
1394 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1395 TAL.getTemplateNameLoc());
1396 }
1397
1398 llvm_unreachable("Invalid TemplateArgument::Kind!");
1399}
1400
1401bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1402 return VisitDeclContext(D);
1403}
1404
1405bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1406 return Visit(TL.getUnqualifiedLoc());
1407}
1408
1409bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1410 ASTContext &Context = AU->getASTContext();
1411
1412 // Some builtin types (such as Objective-C's "id", "sel", and
1413 // "Class") have associated declarations. Create cursors for those.
1414 QualType VisitType;
1415 switch (TL.getTypePtr()->getKind()) {
1416
1417 case BuiltinType::Void:
1418 case BuiltinType::NullPtr:
1419 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001420 case BuiltinType::OCLImage1d:
1421 case BuiltinType::OCLImage1dArray:
1422 case BuiltinType::OCLImage1dBuffer:
1423 case BuiltinType::OCLImage2d:
1424 case BuiltinType::OCLImage2dArray:
1425 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001426 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001427 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001428#define BUILTIN_TYPE(Id, SingletonId)
1429#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#include "clang/AST/BuiltinTypes.def"
1434 break;
1435
1436 case BuiltinType::ObjCId:
1437 VisitType = Context.getObjCIdType();
1438 break;
1439
1440 case BuiltinType::ObjCClass:
1441 VisitType = Context.getObjCClassType();
1442 break;
1443
1444 case BuiltinType::ObjCSel:
1445 VisitType = Context.getObjCSelType();
1446 break;
1447 }
1448
1449 if (!VisitType.isNull()) {
1450 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1451 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1452 TU));
1453 }
1454
1455 return false;
1456}
1457
1458bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1463 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1464}
1465
1466bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1467 if (TL.isDefinition())
1468 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1469
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1474 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1475}
1476
1477bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1478 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1479 return true;
1480
1481 return false;
1482}
1483
1484bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1485 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1486 return true;
1487
1488 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1489 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1490 TU)))
1491 return true;
1492 }
1493
1494 return false;
1495}
1496
1497bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1502 return Visit(TL.getInnerLoc());
1503}
1504
1505bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1522 return Visit(TL.getPointeeLoc());
1523}
1524
1525bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1526 return Visit(TL.getModifiedLoc());
1527}
1528
1529bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1530 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001531 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 return true;
1533
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001534 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1535 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001536 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1537 return true;
1538
1539 return false;
1540}
1541
1542bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1543 if (Visit(TL.getElementLoc()))
1544 return true;
1545
1546 if (Expr *Size = TL.getSizeExpr())
1547 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1548
1549 return false;
1550}
1551
Reid Kleckner8a365022013-06-24 17:51:48 +00001552bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Reid Kleckner0503a872013-12-05 01:23:43 +00001556bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1557 return Visit(TL.getOriginalLoc());
1558}
1559
Guy Benyei11169dd2012-12-18 14:30:41 +00001560bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1561 TemplateSpecializationTypeLoc TL) {
1562 // Visit the template name.
1563 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1564 TL.getTemplateNameLoc()))
1565 return true;
1566
1567 // Visit the template arguments.
1568 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1569 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1570 return true;
1571
1572 return false;
1573}
1574
1575bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1576 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1577}
1578
1579bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1580 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1581 return Visit(TSInfo->getTypeLoc());
1582
1583 return false;
1584}
1585
1586bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1587 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1588 return Visit(TSInfo->getTypeLoc());
1589
1590 return false;
1591}
1592
1593bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1594 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1595 return true;
1596
1597 return false;
1598}
1599
1600bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1601 DependentTemplateSpecializationTypeLoc TL) {
1602 // Visit the nested-name-specifier, if there is one.
1603 if (TL.getQualifierLoc() &&
1604 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1605 return true;
1606
1607 // Visit the template arguments.
1608 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1609 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1610 return true;
1611
1612 return false;
1613}
1614
1615bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1616 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1617 return true;
1618
1619 return Visit(TL.getNamedTypeLoc());
1620}
1621
1622bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1623 return Visit(TL.getPatternLoc());
1624}
1625
1626bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1627 if (Expr *E = TL.getUnderlyingExpr())
1628 return Visit(MakeCXCursor(E, StmtParent, TU));
1629
1630 return false;
1631}
1632
1633bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1634 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1635}
1636
1637bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1638 return Visit(TL.getValueLoc());
1639}
1640
1641#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1642bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1643 return Visit##PARENT##Loc(TL); \
1644}
1645
1646DEFAULT_TYPELOC_IMPL(Complex, Type)
1647DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1648DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1652DEFAULT_TYPELOC_IMPL(Vector, Type)
1653DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1654DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1655DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1656DEFAULT_TYPELOC_IMPL(Record, TagType)
1657DEFAULT_TYPELOC_IMPL(Enum, TagType)
1658DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1659DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1660DEFAULT_TYPELOC_IMPL(Auto, Type)
1661
1662bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1663 // Visit the nested-name-specifier, if present.
1664 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1665 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1666 return true;
1667
1668 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001669 for (const auto &I : D->bases()) {
1670 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001671 return true;
1672 }
1673 }
1674
1675 return VisitTagDecl(D);
1676}
1677
1678bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001679 for (const auto *I : D->attrs())
1680 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001681 return true;
1682
1683 return false;
1684}
1685
1686//===----------------------------------------------------------------------===//
1687// Data-recursive visitor methods.
1688//===----------------------------------------------------------------------===//
1689
1690namespace {
1691#define DEF_JOB(NAME, DATA, KIND)\
1692class NAME : public VisitorJob {\
1693public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001694 NAME(const DATA *d, CXCursor parent) : \
1695 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001696 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001697 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001698};
1699
1700DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1701DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1702DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1703DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1704DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1705 ExplicitTemplateArgsVisitKind)
1706DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1707DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1708DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1709#undef DEF_JOB
1710
1711class DeclVisit : public VisitorJob {
1712public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001713 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001715 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 static bool classof(const VisitorJob *VJ) {
1717 return VJ->getKind() == DeclVisitKind;
1718 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001719 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001720 bool isFirst() const { return data[1] ? true : false; }
1721};
1722class TypeLocVisit : public VisitorJob {
1723public:
1724 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1725 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1726 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1727
1728 static bool classof(const VisitorJob *VJ) {
1729 return VJ->getKind() == TypeLocVisitKind;
1730 }
1731
1732 TypeLoc get() const {
1733 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001734 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 }
1736};
1737
1738class LabelRefVisit : public VisitorJob {
1739public:
1740 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1741 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1742 labelLoc.getPtrEncoding()) {}
1743
1744 static bool classof(const VisitorJob *VJ) {
1745 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1746 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 const LabelDecl *get() const {
1748 return static_cast<const LabelDecl *>(data[0]);
1749 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 SourceLocation getLoc() const {
1751 return SourceLocation::getFromPtrEncoding(data[1]); }
1752};
1753
1754class NestedNameSpecifierLocVisit : public VisitorJob {
1755public:
1756 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1757 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1758 Qualifier.getNestedNameSpecifier(),
1759 Qualifier.getOpaqueData()) { }
1760
1761 static bool classof(const VisitorJob *VJ) {
1762 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1763 }
1764
1765 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 return NestedNameSpecifierLoc(
1767 const_cast<NestedNameSpecifier *>(
1768 static_cast<const NestedNameSpecifier *>(data[0])),
1769 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 }
1771};
1772
1773class DeclarationNameInfoVisit : public VisitorJob {
1774public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001775 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001776 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001777 static bool classof(const VisitorJob *VJ) {
1778 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1779 }
1780 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001781 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 switch (S->getStmtClass()) {
1783 default:
1784 llvm_unreachable("Unhandled Stmt");
1785 case clang::Stmt::MSDependentExistsStmtClass:
1786 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1787 case Stmt::CXXDependentScopeMemberExprClass:
1788 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1789 case Stmt::DependentScopeDeclRefExprClass:
1790 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001791 case Stmt::OMPCriticalDirectiveClass:
1792 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 }
1794 }
1795};
1796class MemberRefVisit : public VisitorJob {
1797public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001799 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1800 L.getPtrEncoding()) {}
1801 static bool classof(const VisitorJob *VJ) {
1802 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1803 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804 const FieldDecl *get() const {
1805 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001806 }
1807 SourceLocation getLoc() const {
1808 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1809 }
1810};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001811class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001812 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001813 VisitorWorkList &WL;
1814 CXCursor Parent;
1815public:
1816 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1817 : WL(wl), Parent(parent) {}
1818
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001819 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1820 void VisitBlockExpr(const BlockExpr *B);
1821 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1822 void VisitCompoundStmt(const CompoundStmt *S);
1823 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1824 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1825 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1826 void VisitCXXNewExpr(const CXXNewExpr *E);
1827 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1828 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1829 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1830 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1831 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1832 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1833 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1834 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1835 void VisitDeclRefExpr(const DeclRefExpr *D);
1836 void VisitDeclStmt(const DeclStmt *S);
1837 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1838 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1839 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1840 void VisitForStmt(const ForStmt *FS);
1841 void VisitGotoStmt(const GotoStmt *GS);
1842 void VisitIfStmt(const IfStmt *If);
1843 void VisitInitListExpr(const InitListExpr *IE);
1844 void VisitMemberExpr(const MemberExpr *M);
1845 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1846 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1847 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1848 void VisitOverloadExpr(const OverloadExpr *E);
1849 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1850 void VisitStmt(const Stmt *S);
1851 void VisitSwitchStmt(const SwitchStmt *S);
1852 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1854 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1855 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1856 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1857 void VisitVAArgExpr(const VAArgExpr *E);
1858 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1859 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1860 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1861 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001862 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001863 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001865 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001866 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001867 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001868 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001869 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001870 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001871 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001872 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001873 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001874 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001875 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001876 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001877 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001878 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001879 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001880 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001881 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001882 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001883 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884
Guy Benyei11169dd2012-12-18 14:30:41 +00001885private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001886 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001887 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1888 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1890 void AddStmt(const Stmt *S);
1891 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001892 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001894 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001895};
1896} // end anonyous namespace
1897
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001898void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001899 // 'S' should always be non-null, since it comes from the
1900 // statement we are visiting.
1901 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1902}
1903
1904void
1905EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1906 if (Qualifier)
1907 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1908}
1909
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001910void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001911 if (S)
1912 WL.push_back(StmtVisit(S, Parent));
1913}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001914void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001915 if (D)
1916 WL.push_back(DeclVisit(D, Parent, isFirst));
1917}
1918void EnqueueVisitor::
1919 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1920 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001921 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001922}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001923void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001924 if (D)
1925 WL.push_back(MemberRefVisit(D, L, Parent));
1926}
1927void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1928 if (TI)
1929 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1930 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001931void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001932 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001933 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001934 AddStmt(*Child);
1935 }
1936 if (size == WL.size())
1937 return;
1938 // Now reverse the entries we just added. This will match the DFS
1939 // ordering performed by the worklist.
1940 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1941 std::reverse(I, E);
1942}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001943namespace {
1944class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1945 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001946 /// \brief Process clauses with list of variables.
1947 template <typename T>
1948 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001949public:
1950 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1951#define OPENMP_CLAUSE(Name, Class) \
1952 void Visit##Class(const Class *C);
1953#include "clang/Basic/OpenMPKinds.def"
1954};
1955
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001956void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1957 Visitor->AddStmt(C->getCondition());
1958}
1959
Alexey Bataev3778b602014-07-17 07:32:53 +00001960void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1961 Visitor->AddStmt(C->getCondition());
1962}
1963
Alexey Bataev568a8332014-03-06 06:15:19 +00001964void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1965 Visitor->AddStmt(C->getNumThreads());
1966}
1967
Alexey Bataev62c87d22014-03-21 04:51:18 +00001968void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1969 Visitor->AddStmt(C->getSafelen());
1970}
1971
Alexander Musman8bd31e62014-05-27 15:12:19 +00001972void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1973 Visitor->AddStmt(C->getNumForLoops());
1974}
1975
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001976void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001977
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001978void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1979
Alexey Bataev56dafe82014-06-20 07:16:17 +00001980void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1981 Visitor->AddStmt(C->getChunkSize());
1982}
1983
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001984void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1985
Alexey Bataev236070f2014-06-20 11:19:47 +00001986void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1987
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001988void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1989
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001990void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1991
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001992void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1993
Alexey Bataevdea47612014-07-23 07:46:59 +00001994void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1995
Alexey Bataev67a4f222014-07-23 10:25:33 +00001996void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
1997
Alexey Bataev459dec02014-07-24 06:46:57 +00001998void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
1999
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002000void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2001
Alexey Bataev756c1962013-09-24 03:17:45 +00002002template<typename T>
2003void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002004 for (const auto *I : Node->varlists())
2005 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00002006}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002007
2008void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002009 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002010}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002011void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2012 const OMPFirstprivateClause *C) {
2013 VisitOMPClauseList(C);
2014}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002015void OMPClauseEnqueue::VisitOMPLastprivateClause(
2016 const OMPLastprivateClause *C) {
2017 VisitOMPClauseList(C);
2018}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002019void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002020 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002021}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002022void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2023 VisitOMPClauseList(C);
2024}
Alexander Musman8dba6642014-04-22 13:09:42 +00002025void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2026 VisitOMPClauseList(C);
2027 Visitor->AddStmt(C->getStep());
2028}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002029void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2030 VisitOMPClauseList(C);
2031 Visitor->AddStmt(C->getAlignment());
2032}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002033void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2034 VisitOMPClauseList(C);
2035}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002036void
2037OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2038 VisitOMPClauseList(C);
2039}
Alexey Bataev6125da92014-07-21 11:26:11 +00002040void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2041 VisitOMPClauseList(C);
2042}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002043}
Alexey Bataev756c1962013-09-24 03:17:45 +00002044
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002045void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2046 unsigned size = WL.size();
2047 OMPClauseEnqueue Visitor(this);
2048 Visitor.Visit(S);
2049 if (size == WL.size())
2050 return;
2051 // Now reverse the entries we just added. This will match the DFS
2052 // ordering performed by the worklist.
2053 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2054 std::reverse(I, E);
2055}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002056void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002057 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2058}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 AddDecl(B->getBlockDecl());
2061}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002063 EnqueueChildren(E);
2064 AddTypeLoc(E->getTypeSourceInfo());
2065}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2067 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 E = S->body_rend(); I != E; ++I) {
2069 AddStmt(*I);
2070 }
2071}
2072void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 AddStmt(S->getSubStmt());
2075 AddDeclarationNameInfo(S);
2076 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2077 AddNestedNameSpecifierLoc(QualifierLoc);
2078}
2079
2080void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2083 AddDeclarationNameInfo(E);
2084 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2085 AddNestedNameSpecifierLoc(QualifierLoc);
2086 if (!E->isImplicitAccess())
2087 AddStmt(E->getBase());
2088}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002089void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002090 // Enqueue the initializer , if any.
2091 AddStmt(E->getInitializer());
2092 // Enqueue the array size, if any.
2093 AddStmt(E->getArraySize());
2094 // Enqueue the allocated type.
2095 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2096 // Enqueue the placement arguments.
2097 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2098 AddStmt(E->getPlacementArg(I-1));
2099}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002100void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2102 AddStmt(CE->getArg(I-1));
2103 AddStmt(CE->getCallee());
2104 AddStmt(CE->getArg(0));
2105}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002106void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2107 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002108 // Visit the name of the type being destroyed.
2109 AddTypeLoc(E->getDestroyedTypeInfo());
2110 // Visit the scope type that looks disturbingly like the nested-name-specifier
2111 // but isn't.
2112 AddTypeLoc(E->getScopeTypeInfo());
2113 // Visit the nested-name-specifier.
2114 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2115 AddNestedNameSpecifierLoc(QualifierLoc);
2116 // Visit base expression.
2117 AddStmt(E->getBase());
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2120 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 AddTypeLoc(E->getTypeSourceInfo());
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2124 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 EnqueueChildren(E);
2126 AddTypeLoc(E->getTypeSourceInfo());
2127}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002128void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002129 EnqueueChildren(E);
2130 if (E->isTypeOperand())
2131 AddTypeLoc(E->getTypeOperandSourceInfo());
2132}
2133
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2135 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 EnqueueChildren(E);
2137 AddTypeLoc(E->getTypeSourceInfo());
2138}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002139void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 EnqueueChildren(E);
2141 if (E->isTypeOperand())
2142 AddTypeLoc(E->getTypeOperandSourceInfo());
2143}
2144
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002145void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002146 EnqueueChildren(S);
2147 AddDecl(S->getExceptionDecl());
2148}
2149
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002150void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002151 if (DR->hasExplicitTemplateArgs()) {
2152 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2153 }
2154 WL.push_back(DeclRefExprParts(DR, Parent));
2155}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2157 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002158 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2159 AddDeclarationNameInfo(E);
2160 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2161}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002162void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002163 unsigned size = WL.size();
2164 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002165 for (const auto *D : S->decls()) {
2166 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002167 isFirst = false;
2168 }
2169 if (size == WL.size())
2170 return;
2171 // Now reverse the entries we just added. This will match the DFS
2172 // ordering performed by the worklist.
2173 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2174 std::reverse(I, E);
2175}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002176void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002177 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 D = E->designators_rbegin(), DEnd = E->designators_rend();
2180 D != DEnd; ++D) {
2181 if (D->isFieldDesignator()) {
2182 if (FieldDecl *Field = D->getField())
2183 AddMemberRef(Field, D->getFieldLoc());
2184 continue;
2185 }
2186 if (D->isArrayDesignator()) {
2187 AddStmt(E->getArrayIndex(*D));
2188 continue;
2189 }
2190 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2191 AddStmt(E->getArrayRangeEnd(*D));
2192 AddStmt(E->getArrayRangeStart(*D));
2193 }
2194}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002196 EnqueueChildren(E);
2197 AddTypeLoc(E->getTypeInfoAsWritten());
2198}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 AddStmt(FS->getBody());
2201 AddStmt(FS->getInc());
2202 AddStmt(FS->getCond());
2203 AddDecl(FS->getConditionVariable());
2204 AddStmt(FS->getInit());
2205}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2208}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 AddStmt(If->getElse());
2211 AddStmt(If->getThen());
2212 AddStmt(If->getCond());
2213 AddDecl(If->getConditionVariable());
2214}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 // We care about the syntactic form of the initializer list, only.
2217 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2218 IE = Syntactic;
2219 EnqueueChildren(IE);
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 WL.push_back(MemberExprParts(M, Parent));
2223
2224 // If the base of the member access expression is an implicit 'this', don't
2225 // visit it.
2226 // FIXME: If we ever want to show these implicit accesses, this will be
2227 // unfortunate. However, clang_getCursor() relies on this behavior.
2228 if (!M->isImplicitAccess())
2229 AddStmt(M->getBase());
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddTypeLoc(E->getEncodedTypeSourceInfo());
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 EnqueueChildren(M);
2236 AddTypeLoc(M->getClassReceiverTypeInfo());
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 // Visit the components of the offsetof expression.
2240 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2241 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2242 const OffsetOfNode &Node = E->getComponent(I-1);
2243 switch (Node.getKind()) {
2244 case OffsetOfNode::Array:
2245 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2246 break;
2247 case OffsetOfNode::Field:
2248 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2249 break;
2250 case OffsetOfNode::Identifier:
2251 case OffsetOfNode::Base:
2252 continue;
2253 }
2254 }
2255 // Visit the type into which we're computing the offset.
2256 AddTypeLoc(E->getTypeSourceInfo());
2257}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002258void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002259 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2260 WL.push_back(OverloadExprParts(E, Parent));
2261}
2262void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002263 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002264 EnqueueChildren(E);
2265 if (E->isArgumentType())
2266 AddTypeLoc(E->getArgumentTypeInfo());
2267}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 EnqueueChildren(S);
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 AddStmt(S->getBody());
2273 AddStmt(S->getCond());
2274 AddDecl(S->getConditionVariable());
2275}
2276
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 AddStmt(W->getBody());
2279 AddStmt(W->getCond());
2280 AddDecl(W->getConditionVariable());
2281}
2282
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002283void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 for (unsigned I = E->getNumArgs(); I > 0; --I)
2285 AddTypeLoc(E->getArg(I-1));
2286}
2287
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 AddTypeLoc(E->getQueriedTypeSourceInfo());
2290}
2291
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 EnqueueChildren(E);
2294}
2295
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002296void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002297 VisitOverloadExpr(U);
2298 if (!U->isImplicitAccess())
2299 AddStmt(U->getBase());
2300}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002301void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002302 AddStmt(E->getSubExpr());
2303 AddTypeLoc(E->getWrittenTypeInfo());
2304}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002305void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002306 WL.push_back(SizeOfPackExprParts(E, Parent));
2307}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 // If the opaque value has a source expression, just transparently
2310 // visit that. This is useful for (e.g.) pseudo-object expressions.
2311 if (Expr *SourceExpr = E->getSourceExpr())
2312 return Visit(SourceExpr);
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 AddStmt(E->getBody());
2316 WL.push_back(LambdaExprParts(E, Parent));
2317}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002319 // Treat the expression like its syntactic form.
2320 Visit(E->getSyntacticForm());
2321}
2322
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002323void EnqueueVisitor::VisitOMPExecutableDirective(
2324 const OMPExecutableDirective *D) {
2325 EnqueueChildren(D);
2326 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2327 E = D->clauses().end();
2328 I != E; ++I)
2329 EnqueueChildren(*I);
2330}
2331
Alexander Musman3aaab662014-08-19 11:27:13 +00002332void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2333 VisitOMPExecutableDirective(D);
2334}
2335
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002336void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2337 VisitOMPExecutableDirective(D);
2338}
2339
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002340void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002341 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002342}
2343
Alexey Bataevf29276e2014-06-18 04:14:57 +00002344void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002345 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002346}
2347
Alexander Musmanf82886e2014-09-18 05:12:34 +00002348void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2349 VisitOMPLoopDirective(D);
2350}
2351
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002352void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2353 VisitOMPExecutableDirective(D);
2354}
2355
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002356void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2357 VisitOMPExecutableDirective(D);
2358}
2359
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002360void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2361 VisitOMPExecutableDirective(D);
2362}
2363
Alexander Musman80c22892014-07-17 08:54:58 +00002364void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2365 VisitOMPExecutableDirective(D);
2366}
2367
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002368void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2369 VisitOMPExecutableDirective(D);
2370 AddDeclarationNameInfo(D);
2371}
2372
Alexey Bataev4acb8592014-07-07 13:01:15 +00002373void
2374EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002375 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002376}
2377
Alexander Musmane4e893b2014-09-23 09:33:00 +00002378void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2379 const OMPParallelForSimdDirective *D) {
2380 VisitOMPLoopDirective(D);
2381}
2382
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002383void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2384 const OMPParallelSectionsDirective *D) {
2385 VisitOMPExecutableDirective(D);
2386}
2387
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002388void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2389 VisitOMPExecutableDirective(D);
2390}
2391
Alexey Bataev68446b72014-07-18 07:47:19 +00002392void
2393EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2394 VisitOMPExecutableDirective(D);
2395}
2396
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002397void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2398 VisitOMPExecutableDirective(D);
2399}
2400
Alexey Bataev2df347a2014-07-18 10:17:07 +00002401void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2402 VisitOMPExecutableDirective(D);
2403}
2404
Alexey Bataev6125da92014-07-21 11:26:11 +00002405void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2406 VisitOMPExecutableDirective(D);
2407}
2408
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002409void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2410 VisitOMPExecutableDirective(D);
2411}
2412
Alexey Bataev0162e452014-07-22 10:10:35 +00002413void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2414 VisitOMPExecutableDirective(D);
2415}
2416
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002417void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2418 VisitOMPExecutableDirective(D);
2419}
2420
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002421void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002422 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2423}
2424
2425bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2426 if (RegionOfInterest.isValid()) {
2427 SourceRange Range = getRawCursorExtent(C);
2428 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2429 return false;
2430 }
2431 return true;
2432}
2433
2434bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2435 while (!WL.empty()) {
2436 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002437 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002438
2439 // Set the Parent field, then back to its old value once we're done.
2440 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2441
2442 switch (LI.getKind()) {
2443 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002444 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 if (!D)
2446 continue;
2447
2448 // For now, perform default visitation for Decls.
2449 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2450 cast<DeclVisit>(&LI)->isFirst())))
2451 return true;
2452
2453 continue;
2454 }
2455 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2456 const ASTTemplateArgumentListInfo *ArgList =
2457 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2458 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2459 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2460 Arg != ArgEnd; ++Arg) {
2461 if (VisitTemplateArgumentLoc(*Arg))
2462 return true;
2463 }
2464 continue;
2465 }
2466 case VisitorJob::TypeLocVisitKind: {
2467 // Perform default visitation for TypeLocs.
2468 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2469 return true;
2470 continue;
2471 }
2472 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002473 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002474 if (LabelStmt *stmt = LS->getStmt()) {
2475 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2476 TU))) {
2477 return true;
2478 }
2479 }
2480 continue;
2481 }
2482
2483 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2484 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2485 if (VisitNestedNameSpecifierLoc(V->get()))
2486 return true;
2487 continue;
2488 }
2489
2490 case VisitorJob::DeclarationNameInfoVisitKind: {
2491 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2492 ->get()))
2493 return true;
2494 continue;
2495 }
2496 case VisitorJob::MemberRefVisitKind: {
2497 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2498 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2499 return true;
2500 continue;
2501 }
2502 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002503 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002504 if (!S)
2505 continue;
2506
2507 // Update the current cursor.
2508 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2509 if (!IsInRegionOfInterest(Cursor))
2510 continue;
2511 switch (Visitor(Cursor, Parent, ClientData)) {
2512 case CXChildVisit_Break: return true;
2513 case CXChildVisit_Continue: break;
2514 case CXChildVisit_Recurse:
2515 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002516 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002517 EnqueueWorkList(WL, S);
2518 break;
2519 }
2520 continue;
2521 }
2522 case VisitorJob::MemberExprPartsKind: {
2523 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002524 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002525
2526 // Visit the nested-name-specifier
2527 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2528 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2529 return true;
2530
2531 // Visit the declaration name.
2532 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2533 return true;
2534
2535 // Visit the explicitly-specified template arguments, if any.
2536 if (M->hasExplicitTemplateArgs()) {
2537 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2538 *ArgEnd = Arg + M->getNumTemplateArgs();
2539 Arg != ArgEnd; ++Arg) {
2540 if (VisitTemplateArgumentLoc(*Arg))
2541 return true;
2542 }
2543 }
2544 continue;
2545 }
2546 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002547 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002548 // Visit nested-name-specifier, if present.
2549 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2550 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2551 return true;
2552 // Visit declaration name.
2553 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2554 return true;
2555 continue;
2556 }
2557 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002558 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002559 // Visit the nested-name-specifier.
2560 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2561 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2562 return true;
2563 // Visit the declaration name.
2564 if (VisitDeclarationNameInfo(O->getNameInfo()))
2565 return true;
2566 // Visit the overloaded declaration reference.
2567 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2568 return true;
2569 continue;
2570 }
2571 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002572 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002573 NamedDecl *Pack = E->getPack();
2574 if (isa<TemplateTypeParmDecl>(Pack)) {
2575 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2576 E->getPackLoc(), TU)))
2577 return true;
2578
2579 continue;
2580 }
2581
2582 if (isa<TemplateTemplateParmDecl>(Pack)) {
2583 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2584 E->getPackLoc(), TU)))
2585 return true;
2586
2587 continue;
2588 }
2589
2590 // Non-type template parameter packs and function parameter packs are
2591 // treated like DeclRefExpr cursors.
2592 continue;
2593 }
2594
2595 case VisitorJob::LambdaExprPartsKind: {
2596 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002597 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002598 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2599 CEnd = E->explicit_capture_end();
2600 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002601 // FIXME: Lambda init-captures.
2602 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002603 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002604
Guy Benyei11169dd2012-12-18 14:30:41 +00002605 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2606 C->getLocation(),
2607 TU)))
2608 return true;
2609 }
2610
2611 // Visit parameters and return type, if present.
2612 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2613 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2614 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2615 // Visit the whole type.
2616 if (Visit(TL))
2617 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002618 } else if (FunctionProtoTypeLoc Proto =
2619 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002620 if (E->hasExplicitParameters()) {
2621 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002622 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2623 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002624 return true;
2625 } else {
2626 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002627 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002628 return true;
2629 }
2630 }
2631 }
2632 break;
2633 }
2634
2635 case VisitorJob::PostChildrenVisitKind:
2636 if (PostChildrenVisitor(Parent, ClientData))
2637 return true;
2638 break;
2639 }
2640 }
2641 return false;
2642}
2643
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002644bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002645 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002646 if (!WorkListFreeList.empty()) {
2647 WL = WorkListFreeList.back();
2648 WL->clear();
2649 WorkListFreeList.pop_back();
2650 }
2651 else {
2652 WL = new VisitorWorkList();
2653 WorkListCache.push_back(WL);
2654 }
2655 EnqueueWorkList(*WL, S);
2656 bool result = RunVisitorWorkList(*WL);
2657 WorkListFreeList.push_back(WL);
2658 return result;
2659}
2660
2661namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002662typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002663RefNamePieces
2664buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2665 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2666 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002667 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2668 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2669 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2670
2671 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2672
2673 RefNamePieces Pieces;
2674
2675 if (WantQualifier && QLoc.isValid())
2676 Pieces.push_back(QLoc);
2677
2678 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2679 Pieces.push_back(NI.getLoc());
2680
2681 if (WantTemplateArgs && TemplateArgs)
2682 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2683 TemplateArgs->RAngleLoc));
2684
2685 if (Kind == DeclarationName::CXXOperatorName) {
2686 Pieces.push_back(SourceLocation::getFromRawEncoding(
2687 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2688 Pieces.push_back(SourceLocation::getFromRawEncoding(
2689 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2690 }
2691
2692 if (WantSinglePiece) {
2693 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2694 Pieces.clear();
2695 Pieces.push_back(R);
2696 }
2697
2698 return Pieces;
2699}
2700}
2701
2702//===----------------------------------------------------------------------===//
2703// Misc. API hooks.
2704//===----------------------------------------------------------------------===//
2705
Chad Rosier05c71aa2013-03-27 18:28:23 +00002706static void fatal_error_handler(void *user_data, const std::string& reason,
2707 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002708 // Write the result out to stderr avoiding errs() because raw_ostreams can
2709 // call report_fatal_error.
2710 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2711 ::abort();
2712}
2713
Chandler Carruth66660742014-06-27 16:37:27 +00002714namespace {
2715struct RegisterFatalErrorHandler {
2716 RegisterFatalErrorHandler() {
2717 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2718 }
2719};
2720}
2721
2722static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2723
Guy Benyei11169dd2012-12-18 14:30:41 +00002724extern "C" {
2725CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2726 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002727 // We use crash recovery to make some of our APIs more reliable, implicitly
2728 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002729 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2730 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002731
Chandler Carruth66660742014-06-27 16:37:27 +00002732 // Look through the managed static to trigger construction of the managed
2733 // static which registers our fatal error handler. This ensures it is only
2734 // registered once.
2735 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002736
2737 CIndexer *CIdxr = new CIndexer();
2738 if (excludeDeclarationsFromPCH)
2739 CIdxr->setOnlyLocalDecls();
2740 if (displayDiagnostics)
2741 CIdxr->setDisplayDiagnostics();
2742
2743 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2744 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2745 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2746 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2747 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2748 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2749
2750 return CIdxr;
2751}
2752
2753void clang_disposeIndex(CXIndex CIdx) {
2754 if (CIdx)
2755 delete static_cast<CIndexer *>(CIdx);
2756}
2757
2758void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2759 if (CIdx)
2760 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2761}
2762
2763unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2764 if (CIdx)
2765 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2766 return 0;
2767}
2768
2769void clang_toggleCrashRecovery(unsigned isEnabled) {
2770 if (isEnabled)
2771 llvm::CrashRecoveryContext::Enable();
2772 else
2773 llvm::CrashRecoveryContext::Disable();
2774}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002775
Guy Benyei11169dd2012-12-18 14:30:41 +00002776CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2777 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002778 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002779 enum CXErrorCode Result =
2780 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002781 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002782 assert((TU && Result == CXError_Success) ||
2783 (!TU && Result != CXError_Success));
2784 return TU;
2785}
2786
2787enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2788 const char *ast_filename,
2789 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002790 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002791 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002792
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002793 if (!CIdx || !ast_filename || !out_TU)
2794 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002795
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002796 LOG_FUNC_SECTION {
2797 *Log << ast_filename;
2798 }
2799
Guy Benyei11169dd2012-12-18 14:30:41 +00002800 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2801 FileSystemOptions FileSystemOpts;
2802
2803 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
David Blaikie6f7382d2014-08-10 19:08:04 +00002804 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2805 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2806 /*CaptureDiagnostics=*/true,
2807 /*AllowPCHWithCompilerErrors=*/true,
2808 /*UserFilesAreVolatile=*/true);
2809 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002810 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002811}
2812
2813unsigned clang_defaultEditingTranslationUnitOptions() {
2814 return CXTranslationUnit_PrecompiledPreamble |
2815 CXTranslationUnit_CacheCompletionResults;
2816}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002817
Guy Benyei11169dd2012-12-18 14:30:41 +00002818CXTranslationUnit
2819clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2820 const char *source_filename,
2821 int num_command_line_args,
2822 const char * const *command_line_args,
2823 unsigned num_unsaved_files,
2824 struct CXUnsavedFile *unsaved_files) {
2825 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2826 return clang_parseTranslationUnit(CIdx, source_filename,
2827 command_line_args, num_command_line_args,
2828 unsaved_files, num_unsaved_files,
2829 Options);
2830}
2831
2832struct ParseTranslationUnitInfo {
2833 CXIndex CIdx;
2834 const char *source_filename;
2835 const char *const *command_line_args;
2836 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002837 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002838 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002839 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002840 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002841};
2842static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002843 const ParseTranslationUnitInfo *PTUI =
2844 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002845 CXIndex CIdx = PTUI->CIdx;
2846 const char *source_filename = PTUI->source_filename;
2847 const char * const *command_line_args = PTUI->command_line_args;
2848 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002849 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002850 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002851
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002852 // Set up the initial return values.
2853 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002854 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002855
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002856 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002857 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002858 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002859 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002860 }
2861
Guy Benyei11169dd2012-12-18 14:30:41 +00002862 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2863
2864 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2865 setThreadBackgroundPriority();
2866
2867 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2868 // FIXME: Add a flag for modules.
2869 TranslationUnitKind TUKind
2870 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002871 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002872 = options & CXTranslationUnit_CacheCompletionResults;
2873 bool IncludeBriefCommentsInCodeCompletion
2874 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2875 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2876 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2877
2878 // Configure the diagnostics.
2879 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002880 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002881
2882 // Recover resources if we crash before exiting this function.
2883 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2884 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002885 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002886
Ahmed Charlesb8984322014-03-07 20:03:18 +00002887 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2888 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002889
2890 // Recover resources if we crash before exiting this function.
2891 llvm::CrashRecoveryContextCleanupRegistrar<
2892 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2893
Alp Toker9d85b182014-07-07 01:23:14 +00002894 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002895 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002896 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002897 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002898 }
2899
Ahmed Charlesb8984322014-03-07 20:03:18 +00002900 std::unique_ptr<std::vector<const char *>> Args(
2901 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002902
2903 // Recover resources if we crash before exiting this method.
2904 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2905 ArgsCleanup(Args.get());
2906
2907 // Since the Clang C library is primarily used by batch tools dealing with
2908 // (often very broken) source code, where spell-checking can have a
2909 // significant negative impact on performance (particularly when
2910 // precompiled headers are involved), we disable it by default.
2911 // Only do this if we haven't found a spell-checking-related argument.
2912 bool FoundSpellCheckingArgument = false;
2913 for (int I = 0; I != num_command_line_args; ++I) {
2914 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2915 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2916 FoundSpellCheckingArgument = true;
2917 break;
2918 }
2919 }
2920 if (!FoundSpellCheckingArgument)
2921 Args->push_back("-fno-spell-checking");
2922
2923 Args->insert(Args->end(), command_line_args,
2924 command_line_args + num_command_line_args);
2925
2926 // The 'source_filename' argument is optional. If the caller does not
2927 // specify it then it is assumed that the source file is specified
2928 // in the actual argument list.
2929 // Put the source file after command_line_args otherwise if '-x' flag is
2930 // present it will be unused.
2931 if (source_filename)
2932 Args->push_back(source_filename);
2933
2934 // Do we need the detailed preprocessing record?
2935 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2936 Args->push_back("-Xclang");
2937 Args->push_back("-detailed-preprocessing-record");
2938 }
2939
2940 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002941 std::unique_ptr<ASTUnit> ErrUnit;
2942 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002943 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002944 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2945 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2946 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2947 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2948 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2949 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002950
2951 if (NumErrors != Diags->getClient()->getNumErrors()) {
2952 // Make sure to check that 'Unit' is non-NULL.
2953 if (CXXIdx->getDisplayDiagnostics())
2954 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2955 }
2956
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002957 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2958 PTUI->result = CXError_ASTReadError;
2959 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002960 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002961 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2962 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002963}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002964
2965CXTranslationUnit
2966clang_parseTranslationUnit(CXIndex CIdx,
2967 const char *source_filename,
2968 const char *const *command_line_args,
2969 int num_command_line_args,
2970 struct CXUnsavedFile *unsaved_files,
2971 unsigned num_unsaved_files,
2972 unsigned options) {
2973 CXTranslationUnit TU;
2974 enum CXErrorCode Result = clang_parseTranslationUnit2(
2975 CIdx, source_filename, command_line_args, num_command_line_args,
2976 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002977 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002978 assert((TU && Result == CXError_Success) ||
2979 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002980 return TU;
2981}
2982
2983enum CXErrorCode clang_parseTranslationUnit2(
2984 CXIndex CIdx,
2985 const char *source_filename,
2986 const char *const *command_line_args,
2987 int num_command_line_args,
2988 struct CXUnsavedFile *unsaved_files,
2989 unsigned num_unsaved_files,
2990 unsigned options,
2991 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002992 LOG_FUNC_SECTION {
2993 *Log << source_filename << ": ";
2994 for (int i = 0; i != num_command_line_args; ++i)
2995 *Log << command_line_args[i] << " ";
2996 }
2997
Alp Toker9d85b182014-07-07 01:23:14 +00002998 if (num_unsaved_files && !unsaved_files)
2999 return CXError_InvalidArguments;
3000
Alp Toker5c532982014-07-07 22:42:03 +00003001 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003002 ParseTranslationUnitInfo PTUI = {
3003 CIdx,
3004 source_filename,
3005 command_line_args,
3006 num_command_line_args,
3007 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3008 options,
3009 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003010 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 llvm::CrashRecoveryContext CRC;
3012
3013 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3014 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3015 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3016 fprintf(stderr, " 'command_line_args' : [");
3017 for (int i = 0; i != num_command_line_args; ++i) {
3018 if (i)
3019 fprintf(stderr, ", ");
3020 fprintf(stderr, "'%s'", command_line_args[i]);
3021 }
3022 fprintf(stderr, "],\n");
3023 fprintf(stderr, " 'unsaved_files' : [");
3024 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3025 if (i)
3026 fprintf(stderr, ", ");
3027 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3028 unsaved_files[i].Length);
3029 }
3030 fprintf(stderr, "],\n");
3031 fprintf(stderr, " 'options' : %d,\n", options);
3032 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003033
3034 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003035 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003036 if (CXTranslationUnit *TU = PTUI.out_TU)
3037 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003038 }
Alp Toker5c532982014-07-07 22:42:03 +00003039
3040 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003041}
3042
3043unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3044 return CXSaveTranslationUnit_None;
3045}
3046
3047namespace {
3048
3049struct SaveTranslationUnitInfo {
3050 CXTranslationUnit TU;
3051 const char *FileName;
3052 unsigned options;
3053 CXSaveError result;
3054};
3055
3056}
3057
3058static void clang_saveTranslationUnit_Impl(void *UserData) {
3059 SaveTranslationUnitInfo *STUI =
3060 static_cast<SaveTranslationUnitInfo*>(UserData);
3061
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003062 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003063 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3064 setThreadBackgroundPriority();
3065
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003066 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003067 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3068}
3069
3070int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3071 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003072 LOG_FUNC_SECTION {
3073 *Log << TU << ' ' << FileName;
3074 }
3075
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003076 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003077 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003078 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003079 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003080
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003081 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003082 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3083 if (!CXXUnit->hasSema())
3084 return CXSaveError_InvalidTU;
3085
3086 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3087
3088 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3089 getenv("LIBCLANG_NOTHREADS")) {
3090 clang_saveTranslationUnit_Impl(&STUI);
3091
3092 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3093 PrintLibclangResourceUsage(TU);
3094
3095 return STUI.result;
3096 }
3097
3098 // We have an AST that has invalid nodes due to compiler errors.
3099 // Use a crash recovery thread for protection.
3100
3101 llvm::CrashRecoveryContext CRC;
3102
3103 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3104 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3105 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3106 fprintf(stderr, " 'options' : %d,\n", options);
3107 fprintf(stderr, "}\n");
3108
3109 return CXSaveError_Unknown;
3110
3111 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3112 PrintLibclangResourceUsage(TU);
3113 }
3114
3115 return STUI.result;
3116}
3117
3118void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3119 if (CTUnit) {
3120 // If the translation unit has been marked as unsafe to free, just discard
3121 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003122 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3123 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003124 return;
3125
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003126 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003127 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3129 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003130 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003131 delete CTUnit;
3132 }
3133}
3134
3135unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3136 return CXReparse_None;
3137}
3138
3139struct ReparseTranslationUnitInfo {
3140 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003141 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003142 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003143 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003144};
3145
3146static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003147 const ReparseTranslationUnitInfo *RTUI =
3148 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003150 unsigned options = RTUI->options;
3151 (void) options;
3152
3153 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003154 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003155 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003156 RTUI->result = CXError_InvalidArguments;
3157 return;
3158 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003159
3160 // Reset the associated diagnostics.
3161 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003162 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003163
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003164 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3166 setThreadBackgroundPriority();
3167
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003168 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003169 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003170
3171 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3172 new std::vector<ASTUnit::RemappedFile>());
3173
Guy Benyei11169dd2012-12-18 14:30:41 +00003174 // Recover resources if we crash before exiting this function.
3175 llvm::CrashRecoveryContextCleanupRegistrar<
3176 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003177
3178 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003179 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003180 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003181 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003183
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003184 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003185 RTUI->result = CXError_Success;
3186 else if (isASTReadError(CXXUnit))
3187 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003188}
3189
3190int clang_reparseTranslationUnit(CXTranslationUnit TU,
3191 unsigned num_unsaved_files,
3192 struct CXUnsavedFile *unsaved_files,
3193 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003194 LOG_FUNC_SECTION {
3195 *Log << TU;
3196 }
3197
Alp Toker9d85b182014-07-07 01:23:14 +00003198 if (num_unsaved_files && !unsaved_files)
3199 return CXError_InvalidArguments;
3200
Alp Toker5c532982014-07-07 22:42:03 +00003201 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003202 ReparseTranslationUnitInfo RTUI = {
3203 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003204 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003205
3206 if (getenv("LIBCLANG_NOTHREADS")) {
3207 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003208 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 }
3210
3211 llvm::CrashRecoveryContext CRC;
3212
3213 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3214 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003215 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003216 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3218 PrintLibclangResourceUsage(TU);
3219
Alp Toker5c532982014-07-07 22:42:03 +00003220 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003221}
3222
3223
3224CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003225 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003226 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003227 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003228 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003229
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003230 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003231 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003232}
3233
3234CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003235 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003236 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003237 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003238 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003239
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003240 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003241 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3242}
3243
3244} // end: extern "C"
3245
3246//===----------------------------------------------------------------------===//
3247// CXFile Operations.
3248//===----------------------------------------------------------------------===//
3249
3250extern "C" {
3251CXString clang_getFileName(CXFile SFile) {
3252 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003253 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003254
3255 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003256 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003257}
3258
3259time_t clang_getFileTime(CXFile SFile) {
3260 if (!SFile)
3261 return 0;
3262
3263 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3264 return FEnt->getModificationTime();
3265}
3266
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003267CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003268 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003269 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003270 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003271 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003272
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003273 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003274
3275 FileManager &FMgr = CXXUnit->getFileManager();
3276 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3277}
3278
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003279unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3280 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003281 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003282 LOG_BAD_TU(TU);
3283 return 0;
3284 }
3285
3286 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 return 0;
3288
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003289 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 FileEntry *FEnt = static_cast<FileEntry *>(file);
3291 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3292 .isFileMultipleIncludeGuarded(FEnt);
3293}
3294
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003295int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3296 if (!file || !outID)
3297 return 1;
3298
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003299 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003300 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3301 outID->data[0] = ID.getDevice();
3302 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003303 outID->data[2] = FEnt->getModificationTime();
3304 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003305}
3306
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003307int clang_File_isEqual(CXFile file1, CXFile file2) {
3308 if (file1 == file2)
3309 return true;
3310
3311 if (!file1 || !file2)
3312 return false;
3313
3314 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3315 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3316 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3317}
3318
Guy Benyei11169dd2012-12-18 14:30:41 +00003319} // end: extern "C"
3320
3321//===----------------------------------------------------------------------===//
3322// CXCursor Operations.
3323//===----------------------------------------------------------------------===//
3324
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003325static const Decl *getDeclFromExpr(const Stmt *E) {
3326 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 return getDeclFromExpr(CE->getSubExpr());
3328
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003329 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003331 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003333 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003335 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 if (PRE->isExplicitProperty())
3337 return PRE->getExplicitProperty();
3338 // It could be messaging both getter and setter as in:
3339 // ++myobj.myprop;
3340 // in which case prefer to associate the setter since it is less obvious
3341 // from inspecting the source that the setter is going to get called.
3342 if (PRE->isMessagingSetter())
3343 return PRE->getImplicitPropertySetter();
3344 return PRE->getImplicitPropertyGetter();
3345 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003346 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003348 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 if (Expr *Src = OVE->getSourceExpr())
3350 return getDeclFromExpr(Src);
3351
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003352 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003354 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 if (!CE->isElidable())
3356 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003357 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 return OME->getMethodDecl();
3359
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003360 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003362 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3364 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003365 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3367 isa<ParmVarDecl>(SizeOfPack->getPack()))
3368 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003369
3370 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003371}
3372
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003373static SourceLocation getLocationFromExpr(const Expr *E) {
3374 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 return getLocationFromExpr(CE->getSubExpr());
3376
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003377 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003379 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003381 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003383 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003385 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003387 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 return PropRef->getLocation();
3389
3390 return E->getLocStart();
3391}
3392
3393extern "C" {
3394
3395unsigned clang_visitChildren(CXCursor parent,
3396 CXCursorVisitor visitor,
3397 CXClientData client_data) {
3398 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3399 /*VisitPreprocessorLast=*/false);
3400 return CursorVis.VisitChildren(parent);
3401}
3402
3403#ifndef __has_feature
3404#define __has_feature(x) 0
3405#endif
3406#if __has_feature(blocks)
3407typedef enum CXChildVisitResult
3408 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3409
3410static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3411 CXClientData client_data) {
3412 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3413 return block(cursor, parent);
3414}
3415#else
3416// If we are compiled with a compiler that doesn't have native blocks support,
3417// define and call the block manually, so the
3418typedef struct _CXChildVisitResult
3419{
3420 void *isa;
3421 int flags;
3422 int reserved;
3423 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3424 CXCursor);
3425} *CXCursorVisitorBlock;
3426
3427static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3428 CXClientData client_data) {
3429 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3430 return block->invoke(block, cursor, parent);
3431}
3432#endif
3433
3434
3435unsigned clang_visitChildrenWithBlock(CXCursor parent,
3436 CXCursorVisitorBlock block) {
3437 return clang_visitChildren(parent, visitWithBlock, block);
3438}
3439
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003440static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003442 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003443
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003444 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003446 if (const ObjCPropertyImplDecl *PropImpl =
3447 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003449 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003450
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003451 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003453 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003454
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003455 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 }
3457
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003458 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003459 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003460
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003461 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3463 // and returns different names. NamedDecl returns the class name and
3464 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003465 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003466
3467 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003468 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003469
3470 SmallString<1024> S;
3471 llvm::raw_svector_ostream os(S);
3472 ND->printName(os);
3473
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003474 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003475}
3476
3477CXString clang_getCursorSpelling(CXCursor C) {
3478 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003479 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003480
3481 if (clang_isReference(C.kind)) {
3482 switch (C.kind) {
3483 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003484 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003485 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 }
3487 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003488 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003489 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 }
3491 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003492 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003494 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 }
3496 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003497 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003498 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 }
3500 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003501 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 assert(Type && "Missing type decl");
3503
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003504 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 getAsString());
3506 }
3507 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003508 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 assert(Template && "Missing template decl");
3510
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003511 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 }
3513
3514 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003515 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 assert(NS && "Missing namespace decl");
3517
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003518 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 }
3520
3521 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003522 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 assert(Field && "Missing member decl");
3524
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003525 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 }
3527
3528 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003529 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 assert(Label && "Missing label");
3531
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003532 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 }
3534
3535 case CXCursor_OverloadedDeclRef: {
3536 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003537 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3538 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003539 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003540 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003542 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003543 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 OverloadedTemplateStorage *Ovl
3545 = Storage.get<OverloadedTemplateStorage*>();
3546 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003547 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003548 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 }
3550
3551 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003552 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 assert(Var && "Missing variable decl");
3554
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003555 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 }
3557
3558 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003559 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 }
3561 }
3562
3563 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003564 const Expr *E = getCursorExpr(C);
3565
3566 if (C.kind == CXCursor_ObjCStringLiteral ||
3567 C.kind == CXCursor_StringLiteral) {
3568 const StringLiteral *SLit;
3569 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3570 SLit = OSL->getString();
3571 } else {
3572 SLit = cast<StringLiteral>(E);
3573 }
3574 SmallString<256> Buf;
3575 llvm::raw_svector_ostream OS(Buf);
3576 SLit->outputString(OS);
3577 return cxstring::createDup(OS.str());
3578 }
3579
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003580 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 if (D)
3582 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003583 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 }
3585
3586 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003587 const Stmt *S = getCursorStmt(C);
3588 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003589 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003590
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003591 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 }
3593
3594 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003595 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 ->getNameStart());
3597
3598 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003599 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 ->getNameStart());
3601
3602 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003603 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003604
3605 if (clang_isDeclaration(C.kind))
3606 return getDeclSpelling(getCursorDecl(C));
3607
3608 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003609 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003610 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 }
3612
3613 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003614 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003615 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 }
3617
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003618 if (C.kind == CXCursor_PackedAttr) {
3619 return cxstring::createRef("packed");
3620 }
3621
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003622 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003623}
3624
3625CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3626 unsigned pieceIndex,
3627 unsigned options) {
3628 if (clang_Cursor_isNull(C))
3629 return clang_getNullRange();
3630
3631 ASTContext &Ctx = getCursorContext(C);
3632
3633 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003634 const Stmt *S = getCursorStmt(C);
3635 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 if (pieceIndex > 0)
3637 return clang_getNullRange();
3638 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3639 }
3640
3641 return clang_getNullRange();
3642 }
3643
3644 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003645 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3647 if (pieceIndex >= ME->getNumSelectorLocs())
3648 return clang_getNullRange();
3649 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3650 }
3651 }
3652
3653 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3654 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003655 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3657 if (pieceIndex >= MD->getNumSelectorLocs())
3658 return clang_getNullRange();
3659 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3660 }
3661 }
3662
3663 if (C.kind == CXCursor_ObjCCategoryDecl ||
3664 C.kind == CXCursor_ObjCCategoryImplDecl) {
3665 if (pieceIndex > 0)
3666 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003667 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3669 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003670 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3672 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3673 }
3674
3675 if (C.kind == CXCursor_ModuleImportDecl) {
3676 if (pieceIndex > 0)
3677 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003678 if (const ImportDecl *ImportD =
3679 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3681 if (!Locs.empty())
3682 return cxloc::translateSourceRange(Ctx,
3683 SourceRange(Locs.front(), Locs.back()));
3684 }
3685 return clang_getNullRange();
3686 }
3687
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003688 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3689 C.kind == CXCursor_ConversionFunction) {
3690 if (pieceIndex > 0)
3691 return clang_getNullRange();
3692 if (const FunctionDecl *FD =
3693 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3694 DeclarationNameInfo FunctionName = FD->getNameInfo();
3695 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3696 }
3697 return clang_getNullRange();
3698 }
3699
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 // FIXME: A CXCursor_InclusionDirective should give the location of the
3701 // filename, but we don't keep track of this.
3702
3703 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3704 // but we don't keep track of this.
3705
3706 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3707 // but we don't keep track of this.
3708
3709 // Default handling, give the location of the cursor.
3710
3711 if (pieceIndex > 0)
3712 return clang_getNullRange();
3713
3714 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3715 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3716 return cxloc::translateSourceRange(Ctx, Loc);
3717}
3718
Eli Bendersky44a206f2014-07-31 18:04:56 +00003719CXString clang_Cursor_getMangling(CXCursor C) {
3720 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3721 return cxstring::createEmpty();
3722
Eli Bendersky44a206f2014-07-31 18:04:56 +00003723 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003724 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003725 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3726 return cxstring::createEmpty();
3727
Eli Bendersky79759592014-08-01 15:01:10 +00003728 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003729 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003730 ASTContext &Ctx = ND->getASTContext();
3731 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003732
Eli Bendersky79759592014-08-01 15:01:10 +00003733 std::string FrontendBuf;
3734 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3735 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003736
Eli Bendersky79759592014-08-01 15:01:10 +00003737 // Now apply backend mangling.
3738 std::unique_ptr<llvm::DataLayout> DL(
3739 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3740 llvm::Mangler BackendMangler(DL.get());
3741
3742 std::string FinalBuf;
3743 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3744 BackendMangler.getNameWithPrefix(FinalBufOS,
3745 llvm::Twine(FrontendBufOS.str()));
3746
3747 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003748}
3749
Guy Benyei11169dd2012-12-18 14:30:41 +00003750CXString clang_getCursorDisplayName(CXCursor C) {
3751 if (!clang_isDeclaration(C.kind))
3752 return clang_getCursorSpelling(C);
3753
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003754 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003756 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003757
3758 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003759 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 D = FunTmpl->getTemplatedDecl();
3761
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003762 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 SmallString<64> Str;
3764 llvm::raw_svector_ostream OS(Str);
3765 OS << *Function;
3766 if (Function->getPrimaryTemplate())
3767 OS << "<>";
3768 OS << "(";
3769 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3770 if (I)
3771 OS << ", ";
3772 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3773 }
3774
3775 if (Function->isVariadic()) {
3776 if (Function->getNumParams())
3777 OS << ", ";
3778 OS << "...";
3779 }
3780 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003781 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 }
3783
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003784 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 SmallString<64> Str;
3786 llvm::raw_svector_ostream OS(Str);
3787 OS << *ClassTemplate;
3788 OS << "<";
3789 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3790 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3791 if (I)
3792 OS << ", ";
3793
3794 NamedDecl *Param = Params->getParam(I);
3795 if (Param->getIdentifier()) {
3796 OS << Param->getIdentifier()->getName();
3797 continue;
3798 }
3799
3800 // There is no parameter name, which makes this tricky. Try to come up
3801 // with something useful that isn't too long.
3802 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3803 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3804 else if (NonTypeTemplateParmDecl *NTTP
3805 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3806 OS << NTTP->getType().getAsString(Policy);
3807 else
3808 OS << "template<...> class";
3809 }
3810
3811 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003812 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 }
3814
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003815 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3817 // If the type was explicitly written, use that.
3818 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003819 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003820
Benjamin Kramer9170e912013-02-22 15:46:01 +00003821 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 llvm::raw_svector_ostream OS(Str);
3823 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003824 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 ClassSpec->getTemplateArgs().data(),
3826 ClassSpec->getTemplateArgs().size(),
3827 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003828 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 }
3830
3831 return clang_getCursorSpelling(C);
3832}
3833
3834CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3835 switch (Kind) {
3836 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003964 case CXCursor_ObjCSelfExpr:
3965 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004054 case CXCursor_SEHLeaveStmt:
4055 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004084 case CXCursor_PackedAttr:
4085 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004086 case CXCursor_PureAttr:
4087 return cxstring::createRef("attribute(pure)");
4088 case CXCursor_ConstAttr:
4089 return cxstring::createRef("attribute(const)");
4090 case CXCursor_NoDuplicateAttr:
4091 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004092 case CXCursor_CUDAConstantAttr:
4093 return cxstring::createRef("attribute(constant)");
4094 case CXCursor_CUDADeviceAttr:
4095 return cxstring::createRef("attribute(device)");
4096 case CXCursor_CUDAGlobalAttr:
4097 return cxstring::createRef("attribute(global)");
4098 case CXCursor_CUDAHostAttr:
4099 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004100 case CXCursor_CUDASharedAttr:
4101 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004150 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004151 return cxstring::createRef("OMPParallelDirective");
4152 case CXCursor_OMPSimdDirective:
4153 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004154 case CXCursor_OMPForDirective:
4155 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004156 case CXCursor_OMPForSimdDirective:
4157 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004158 case CXCursor_OMPSectionsDirective:
4159 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004160 case CXCursor_OMPSectionDirective:
4161 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004162 case CXCursor_OMPSingleDirective:
4163 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004164 case CXCursor_OMPMasterDirective:
4165 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004166 case CXCursor_OMPCriticalDirective:
4167 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004168 case CXCursor_OMPParallelForDirective:
4169 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004170 case CXCursor_OMPParallelForSimdDirective:
4171 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004172 case CXCursor_OMPParallelSectionsDirective:
4173 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004174 case CXCursor_OMPTaskDirective:
4175 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004176 case CXCursor_OMPTaskyieldDirective:
4177 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004178 case CXCursor_OMPBarrierDirective:
4179 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004180 case CXCursor_OMPTaskwaitDirective:
4181 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004182 case CXCursor_OMPFlushDirective:
4183 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004184 case CXCursor_OMPOrderedDirective:
4185 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004186 case CXCursor_OMPAtomicDirective:
4187 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004188 case CXCursor_OMPTargetDirective:
4189 return cxstring::createRef("OMPTargetDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 }
4191
4192 llvm_unreachable("Unhandled CXCursorKind");
4193}
4194
4195struct GetCursorData {
4196 SourceLocation TokenBeginLoc;
4197 bool PointsAtMacroArgExpansion;
4198 bool VisitedObjCPropertyImplDecl;
4199 SourceLocation VisitedDeclaratorDeclStartLoc;
4200 CXCursor &BestCursor;
4201
4202 GetCursorData(SourceManager &SM,
4203 SourceLocation tokenBegin, CXCursor &outputCursor)
4204 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4205 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4206 VisitedObjCPropertyImplDecl = false;
4207 }
4208};
4209
4210static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4211 CXCursor parent,
4212 CXClientData client_data) {
4213 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4214 CXCursor *BestCursor = &Data->BestCursor;
4215
4216 // If we point inside a macro argument we should provide info of what the
4217 // token is so use the actual cursor, don't replace it with a macro expansion
4218 // cursor.
4219 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4220 return CXChildVisit_Recurse;
4221
4222 if (clang_isDeclaration(cursor.kind)) {
4223 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004224 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4226 if (MD->isImplicit())
4227 return CXChildVisit_Break;
4228
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004229 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4231 // Check that when we have multiple @class references in the same line,
4232 // that later ones do not override the previous ones.
4233 // If we have:
4234 // @class Foo, Bar;
4235 // source ranges for both start at '@', so 'Bar' will end up overriding
4236 // 'Foo' even though the cursor location was at 'Foo'.
4237 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4238 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004239 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4241 if (PrevID != ID &&
4242 !PrevID->isThisDeclarationADefinition() &&
4243 !ID->isThisDeclarationADefinition())
4244 return CXChildVisit_Break;
4245 }
4246
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004247 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4249 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4250 // Check that when we have multiple declarators in the same line,
4251 // that later ones do not override the previous ones.
4252 // If we have:
4253 // int Foo, Bar;
4254 // source ranges for both start at 'int', so 'Bar' will end up overriding
4255 // 'Foo' even though the cursor location was at 'Foo'.
4256 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4257 return CXChildVisit_Break;
4258 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4259
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004260 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4262 (void)PropImp;
4263 // Check that when we have multiple @synthesize in the same line,
4264 // that later ones do not override the previous ones.
4265 // If we have:
4266 // @synthesize Foo, Bar;
4267 // source ranges for both start at '@', so 'Bar' will end up overriding
4268 // 'Foo' even though the cursor location was at 'Foo'.
4269 if (Data->VisitedObjCPropertyImplDecl)
4270 return CXChildVisit_Break;
4271 Data->VisitedObjCPropertyImplDecl = true;
4272 }
4273 }
4274
4275 if (clang_isExpression(cursor.kind) &&
4276 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004277 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 // Avoid having the cursor of an expression replace the declaration cursor
4279 // when the expression source range overlaps the declaration range.
4280 // This can happen for C++ constructor expressions whose range generally
4281 // include the variable declaration, e.g.:
4282 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4283 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4284 D->getLocation() == Data->TokenBeginLoc)
4285 return CXChildVisit_Break;
4286 }
4287 }
4288
4289 // If our current best cursor is the construction of a temporary object,
4290 // don't replace that cursor with a type reference, because we want
4291 // clang_getCursor() to point at the constructor.
4292 if (clang_isExpression(BestCursor->kind) &&
4293 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4294 cursor.kind == CXCursor_TypeRef) {
4295 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4296 // as having the actual point on the type reference.
4297 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4298 return CXChildVisit_Recurse;
4299 }
4300
4301 *BestCursor = cursor;
4302 return CXChildVisit_Recurse;
4303}
4304
4305CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004306 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004307 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004309 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004310
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004311 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004312 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4313
4314 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4315 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4316
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004317 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 CXFile SearchFile;
4319 unsigned SearchLine, SearchColumn;
4320 CXFile ResultFile;
4321 unsigned ResultLine, ResultColumn;
4322 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4323 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4324 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004325
4326 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4327 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004328 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004329 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004330 SearchFileName = clang_getFileName(SearchFile);
4331 ResultFileName = clang_getFileName(ResultFile);
4332 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4333 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004334 *Log << llvm::format("(%s:%d:%d) = %s",
4335 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4336 clang_getCString(KindSpelling))
4337 << llvm::format("(%s:%d:%d):%s%s",
4338 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4339 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 clang_disposeString(SearchFileName);
4341 clang_disposeString(ResultFileName);
4342 clang_disposeString(KindSpelling);
4343 clang_disposeString(USR);
4344
4345 CXCursor Definition = clang_getCursorDefinition(Result);
4346 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4347 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4348 CXString DefinitionKindSpelling
4349 = clang_getCursorKindSpelling(Definition.kind);
4350 CXFile DefinitionFile;
4351 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004352 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004353 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004355 *Log << llvm::format(" -> %s(%s:%d:%d)",
4356 clang_getCString(DefinitionKindSpelling),
4357 clang_getCString(DefinitionFileName),
4358 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004359 clang_disposeString(DefinitionFileName);
4360 clang_disposeString(DefinitionKindSpelling);
4361 }
4362 }
4363
4364 return Result;
4365}
4366
4367CXCursor clang_getNullCursor(void) {
4368 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4369}
4370
4371unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004372 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4373 // can't set consistently. For example, when visiting a DeclStmt we will set
4374 // it but we don't set it on the result of clang_getCursorDefinition for
4375 // a reference of the same declaration.
4376 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4377 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4378 // to provide that kind of info.
4379 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004380 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004381 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004382 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004383
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 return X == Y;
4385}
4386
4387unsigned clang_hashCursor(CXCursor C) {
4388 unsigned Index = 0;
4389 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4390 Index = 1;
4391
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004392 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004393 std::make_pair(C.kind, C.data[Index]));
4394}
4395
4396unsigned clang_isInvalid(enum CXCursorKind K) {
4397 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4398}
4399
4400unsigned clang_isDeclaration(enum CXCursorKind K) {
4401 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4402 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4403}
4404
4405unsigned clang_isReference(enum CXCursorKind K) {
4406 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4407}
4408
4409unsigned clang_isExpression(enum CXCursorKind K) {
4410 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4411}
4412
4413unsigned clang_isStatement(enum CXCursorKind K) {
4414 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4415}
4416
4417unsigned clang_isAttribute(enum CXCursorKind K) {
4418 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4419}
4420
4421unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4422 return K == CXCursor_TranslationUnit;
4423}
4424
4425unsigned clang_isPreprocessing(enum CXCursorKind K) {
4426 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4427}
4428
4429unsigned clang_isUnexposed(enum CXCursorKind K) {
4430 switch (K) {
4431 case CXCursor_UnexposedDecl:
4432 case CXCursor_UnexposedExpr:
4433 case CXCursor_UnexposedStmt:
4434 case CXCursor_UnexposedAttr:
4435 return true;
4436 default:
4437 return false;
4438 }
4439}
4440
4441CXCursorKind clang_getCursorKind(CXCursor C) {
4442 return C.kind;
4443}
4444
4445CXSourceLocation clang_getCursorLocation(CXCursor C) {
4446 if (clang_isReference(C.kind)) {
4447 switch (C.kind) {
4448 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004449 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004450 = getCursorObjCSuperClassRef(C);
4451 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4452 }
4453
4454 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004455 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004456 = getCursorObjCProtocolRef(C);
4457 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4458 }
4459
4460 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004461 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004462 = getCursorObjCClassRef(C);
4463 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4464 }
4465
4466 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004467 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4469 }
4470
4471 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004472 std::pair<const TemplateDecl *, SourceLocation> P =
4473 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4475 }
4476
4477 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004478 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4480 }
4481
4482 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004483 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4485 }
4486
4487 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004488 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4490 }
4491
4492 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004493 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 if (!BaseSpec)
4495 return clang_getNullLocation();
4496
4497 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4498 return cxloc::translateSourceLocation(getCursorContext(C),
4499 TSInfo->getTypeLoc().getBeginLoc());
4500
4501 return cxloc::translateSourceLocation(getCursorContext(C),
4502 BaseSpec->getLocStart());
4503 }
4504
4505 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004506 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4508 }
4509
4510 case CXCursor_OverloadedDeclRef:
4511 return cxloc::translateSourceLocation(getCursorContext(C),
4512 getCursorOverloadedDeclRef(C).second);
4513
4514 default:
4515 // FIXME: Need a way to enumerate all non-reference cases.
4516 llvm_unreachable("Missed a reference kind");
4517 }
4518 }
4519
4520 if (clang_isExpression(C.kind))
4521 return cxloc::translateSourceLocation(getCursorContext(C),
4522 getLocationFromExpr(getCursorExpr(C)));
4523
4524 if (clang_isStatement(C.kind))
4525 return cxloc::translateSourceLocation(getCursorContext(C),
4526 getCursorStmt(C)->getLocStart());
4527
4528 if (C.kind == CXCursor_PreprocessingDirective) {
4529 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4530 return cxloc::translateSourceLocation(getCursorContext(C), L);
4531 }
4532
4533 if (C.kind == CXCursor_MacroExpansion) {
4534 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004535 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004536 return cxloc::translateSourceLocation(getCursorContext(C), L);
4537 }
4538
4539 if (C.kind == CXCursor_MacroDefinition) {
4540 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4541 return cxloc::translateSourceLocation(getCursorContext(C), L);
4542 }
4543
4544 if (C.kind == CXCursor_InclusionDirective) {
4545 SourceLocation L
4546 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4547 return cxloc::translateSourceLocation(getCursorContext(C), L);
4548 }
4549
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004550 if (clang_isAttribute(C.kind)) {
4551 SourceLocation L
4552 = cxcursor::getCursorAttr(C)->getLocation();
4553 return cxloc::translateSourceLocation(getCursorContext(C), L);
4554 }
4555
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 if (!clang_isDeclaration(C.kind))
4557 return clang_getNullLocation();
4558
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004559 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 if (!D)
4561 return clang_getNullLocation();
4562
4563 SourceLocation Loc = D->getLocation();
4564 // FIXME: Multiple variables declared in a single declaration
4565 // currently lack the information needed to correctly determine their
4566 // ranges when accounting for the type-specifier. We use context
4567 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4568 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004569 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 if (!cxcursor::isFirstInDeclGroup(C))
4571 Loc = VD->getLocation();
4572 }
4573
4574 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004575 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004576 Loc = MD->getSelectorStartLoc();
4577
4578 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4579}
4580
4581} // end extern "C"
4582
4583CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4584 assert(TU);
4585
4586 // Guard against an invalid SourceLocation, or we may assert in one
4587 // of the following calls.
4588 if (SLoc.isInvalid())
4589 return clang_getNullCursor();
4590
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004591 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004592
4593 // Translate the given source location to make it point at the beginning of
4594 // the token under the cursor.
4595 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4596 CXXUnit->getASTContext().getLangOpts());
4597
4598 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4599 if (SLoc.isValid()) {
4600 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4601 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4602 /*VisitPreprocessorLast=*/true,
4603 /*VisitIncludedEntities=*/false,
4604 SourceLocation(SLoc));
4605 CursorVis.visitFileRegion();
4606 }
4607
4608 return Result;
4609}
4610
4611static SourceRange getRawCursorExtent(CXCursor C) {
4612 if (clang_isReference(C.kind)) {
4613 switch (C.kind) {
4614 case CXCursor_ObjCSuperClassRef:
4615 return getCursorObjCSuperClassRef(C).second;
4616
4617 case CXCursor_ObjCProtocolRef:
4618 return getCursorObjCProtocolRef(C).second;
4619
4620 case CXCursor_ObjCClassRef:
4621 return getCursorObjCClassRef(C).second;
4622
4623 case CXCursor_TypeRef:
4624 return getCursorTypeRef(C).second;
4625
4626 case CXCursor_TemplateRef:
4627 return getCursorTemplateRef(C).second;
4628
4629 case CXCursor_NamespaceRef:
4630 return getCursorNamespaceRef(C).second;
4631
4632 case CXCursor_MemberRef:
4633 return getCursorMemberRef(C).second;
4634
4635 case CXCursor_CXXBaseSpecifier:
4636 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4637
4638 case CXCursor_LabelRef:
4639 return getCursorLabelRef(C).second;
4640
4641 case CXCursor_OverloadedDeclRef:
4642 return getCursorOverloadedDeclRef(C).second;
4643
4644 case CXCursor_VariableRef:
4645 return getCursorVariableRef(C).second;
4646
4647 default:
4648 // FIXME: Need a way to enumerate all non-reference cases.
4649 llvm_unreachable("Missed a reference kind");
4650 }
4651 }
4652
4653 if (clang_isExpression(C.kind))
4654 return getCursorExpr(C)->getSourceRange();
4655
4656 if (clang_isStatement(C.kind))
4657 return getCursorStmt(C)->getSourceRange();
4658
4659 if (clang_isAttribute(C.kind))
4660 return getCursorAttr(C)->getRange();
4661
4662 if (C.kind == CXCursor_PreprocessingDirective)
4663 return cxcursor::getCursorPreprocessingDirective(C);
4664
4665 if (C.kind == CXCursor_MacroExpansion) {
4666 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004667 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 return TU->mapRangeFromPreamble(Range);
4669 }
4670
4671 if (C.kind == CXCursor_MacroDefinition) {
4672 ASTUnit *TU = getCursorASTUnit(C);
4673 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4674 return TU->mapRangeFromPreamble(Range);
4675 }
4676
4677 if (C.kind == CXCursor_InclusionDirective) {
4678 ASTUnit *TU = getCursorASTUnit(C);
4679 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4680 return TU->mapRangeFromPreamble(Range);
4681 }
4682
4683 if (C.kind == CXCursor_TranslationUnit) {
4684 ASTUnit *TU = getCursorASTUnit(C);
4685 FileID MainID = TU->getSourceManager().getMainFileID();
4686 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4687 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4688 return SourceRange(Start, End);
4689 }
4690
4691 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004692 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 if (!D)
4694 return SourceRange();
4695
4696 SourceRange R = D->getSourceRange();
4697 // FIXME: Multiple variables declared in a single declaration
4698 // currently lack the information needed to correctly determine their
4699 // ranges when accounting for the type-specifier. We use context
4700 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4701 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004702 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 if (!cxcursor::isFirstInDeclGroup(C))
4704 R.setBegin(VD->getLocation());
4705 }
4706 return R;
4707 }
4708 return SourceRange();
4709}
4710
4711/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4712/// the decl-specifier-seq for declarations.
4713static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4714 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004715 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004716 if (!D)
4717 return SourceRange();
4718
4719 SourceRange R = D->getSourceRange();
4720
4721 // Adjust the start of the location for declarations preceded by
4722 // declaration specifiers.
4723 SourceLocation StartLoc;
4724 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4725 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4726 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004727 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4729 StartLoc = TI->getTypeLoc().getLocStart();
4730 }
4731
4732 if (StartLoc.isValid() && R.getBegin().isValid() &&
4733 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4734 R.setBegin(StartLoc);
4735
4736 // FIXME: Multiple variables declared in a single declaration
4737 // currently lack the information needed to correctly determine their
4738 // ranges when accounting for the type-specifier. We use context
4739 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4740 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004741 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 if (!cxcursor::isFirstInDeclGroup(C))
4743 R.setBegin(VD->getLocation());
4744 }
4745
4746 return R;
4747 }
4748
4749 return getRawCursorExtent(C);
4750}
4751
4752extern "C" {
4753
4754CXSourceRange clang_getCursorExtent(CXCursor C) {
4755 SourceRange R = getRawCursorExtent(C);
4756 if (R.isInvalid())
4757 return clang_getNullRange();
4758
4759 return cxloc::translateSourceRange(getCursorContext(C), R);
4760}
4761
4762CXCursor clang_getCursorReferenced(CXCursor C) {
4763 if (clang_isInvalid(C.kind))
4764 return clang_getNullCursor();
4765
4766 CXTranslationUnit tu = getCursorTU(C);
4767 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004768 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 if (!D)
4770 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004771 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004773 if (const ObjCPropertyImplDecl *PropImpl =
4774 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4776 return MakeCXCursor(Property, tu);
4777
4778 return C;
4779 }
4780
4781 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004782 const Expr *E = getCursorExpr(C);
4783 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 if (D) {
4785 CXCursor declCursor = MakeCXCursor(D, tu);
4786 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4787 declCursor);
4788 return declCursor;
4789 }
4790
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004791 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004792 return MakeCursorOverloadedDeclRef(Ovl, tu);
4793
4794 return clang_getNullCursor();
4795 }
4796
4797 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004798 const Stmt *S = getCursorStmt(C);
4799 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004800 if (LabelDecl *label = Goto->getLabel())
4801 if (LabelStmt *labelS = label->getStmt())
4802 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4803
4804 return clang_getNullCursor();
4805 }
4806
4807 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004808 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004809 return MakeMacroDefinitionCursor(Def, tu);
4810 }
4811
4812 if (!clang_isReference(C.kind))
4813 return clang_getNullCursor();
4814
4815 switch (C.kind) {
4816 case CXCursor_ObjCSuperClassRef:
4817 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4818
4819 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004820 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4821 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 return MakeCXCursor(Def, tu);
4823
4824 return MakeCXCursor(Prot, tu);
4825 }
4826
4827 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004828 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4829 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 return MakeCXCursor(Def, tu);
4831
4832 return MakeCXCursor(Class, tu);
4833 }
4834
4835 case CXCursor_TypeRef:
4836 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4837
4838 case CXCursor_TemplateRef:
4839 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4840
4841 case CXCursor_NamespaceRef:
4842 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4843
4844 case CXCursor_MemberRef:
4845 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4846
4847 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004848 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004849 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4850 tu ));
4851 }
4852
4853 case CXCursor_LabelRef:
4854 // FIXME: We end up faking the "parent" declaration here because we
4855 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004856 return MakeCXCursor(getCursorLabelRef(C).first,
4857 cxtu::getASTUnit(tu)->getASTContext()
4858 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 tu);
4860
4861 case CXCursor_OverloadedDeclRef:
4862 return C;
4863
4864 case CXCursor_VariableRef:
4865 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4866
4867 default:
4868 // We would prefer to enumerate all non-reference cursor kinds here.
4869 llvm_unreachable("Unhandled reference cursor kind");
4870 }
4871}
4872
4873CXCursor clang_getCursorDefinition(CXCursor C) {
4874 if (clang_isInvalid(C.kind))
4875 return clang_getNullCursor();
4876
4877 CXTranslationUnit TU = getCursorTU(C);
4878
4879 bool WasReference = false;
4880 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4881 C = clang_getCursorReferenced(C);
4882 WasReference = true;
4883 }
4884
4885 if (C.kind == CXCursor_MacroExpansion)
4886 return clang_getCursorReferenced(C);
4887
4888 if (!clang_isDeclaration(C.kind))
4889 return clang_getNullCursor();
4890
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004891 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004892 if (!D)
4893 return clang_getNullCursor();
4894
4895 switch (D->getKind()) {
4896 // Declaration kinds that don't really separate the notions of
4897 // declaration and definition.
4898 case Decl::Namespace:
4899 case Decl::Typedef:
4900 case Decl::TypeAlias:
4901 case Decl::TypeAliasTemplate:
4902 case Decl::TemplateTypeParm:
4903 case Decl::EnumConstant:
4904 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004905 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004906 case Decl::IndirectField:
4907 case Decl::ObjCIvar:
4908 case Decl::ObjCAtDefsField:
4909 case Decl::ImplicitParam:
4910 case Decl::ParmVar:
4911 case Decl::NonTypeTemplateParm:
4912 case Decl::TemplateTemplateParm:
4913 case Decl::ObjCCategoryImpl:
4914 case Decl::ObjCImplementation:
4915 case Decl::AccessSpec:
4916 case Decl::LinkageSpec:
4917 case Decl::ObjCPropertyImpl:
4918 case Decl::FileScopeAsm:
4919 case Decl::StaticAssert:
4920 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004921 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004922 case Decl::Label: // FIXME: Is this right??
4923 case Decl::ClassScopeFunctionSpecialization:
4924 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004925 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004926 return C;
4927
4928 // Declaration kinds that don't make any sense here, but are
4929 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004930 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004931 case Decl::TranslationUnit:
4932 break;
4933
4934 // Declaration kinds for which the definition is not resolvable.
4935 case Decl::UnresolvedUsingTypename:
4936 case Decl::UnresolvedUsingValue:
4937 break;
4938
4939 case Decl::UsingDirective:
4940 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4941 TU);
4942
4943 case Decl::NamespaceAlias:
4944 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4945
4946 case Decl::Enum:
4947 case Decl::Record:
4948 case Decl::CXXRecord:
4949 case Decl::ClassTemplateSpecialization:
4950 case Decl::ClassTemplatePartialSpecialization:
4951 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4952 return MakeCXCursor(Def, TU);
4953 return clang_getNullCursor();
4954
4955 case Decl::Function:
4956 case Decl::CXXMethod:
4957 case Decl::CXXConstructor:
4958 case Decl::CXXDestructor:
4959 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004960 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004961 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004962 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004963 return clang_getNullCursor();
4964 }
4965
Larisse Voufo39a1e502013-08-06 01:03:05 +00004966 case Decl::Var:
4967 case Decl::VarTemplateSpecialization:
4968 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004969 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004970 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004971 return MakeCXCursor(Def, TU);
4972 return clang_getNullCursor();
4973 }
4974
4975 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004976 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004977 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4978 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4979 return clang_getNullCursor();
4980 }
4981
4982 case Decl::ClassTemplate: {
4983 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4984 ->getDefinition())
4985 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4986 TU);
4987 return clang_getNullCursor();
4988 }
4989
Larisse Voufo39a1e502013-08-06 01:03:05 +00004990 case Decl::VarTemplate: {
4991 if (VarDecl *Def =
4992 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4993 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4994 return clang_getNullCursor();
4995 }
4996
Guy Benyei11169dd2012-12-18 14:30:41 +00004997 case Decl::Using:
4998 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4999 D->getLocation(), TU);
5000
5001 case Decl::UsingShadow:
5002 return clang_getCursorDefinition(
5003 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5004 TU));
5005
5006 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005007 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005008 if (Method->isThisDeclarationADefinition())
5009 return C;
5010
5011 // Dig out the method definition in the associated
5012 // @implementation, if we have it.
5013 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005014 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005015 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5016 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5017 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5018 Method->isInstanceMethod()))
5019 if (Def->isThisDeclarationADefinition())
5020 return MakeCXCursor(Def, TU);
5021
5022 return clang_getNullCursor();
5023 }
5024
5025 case Decl::ObjCCategory:
5026 if (ObjCCategoryImplDecl *Impl
5027 = cast<ObjCCategoryDecl>(D)->getImplementation())
5028 return MakeCXCursor(Impl, TU);
5029 return clang_getNullCursor();
5030
5031 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005032 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005033 return MakeCXCursor(Def, TU);
5034 return clang_getNullCursor();
5035
5036 case Decl::ObjCInterface: {
5037 // There are two notions of a "definition" for an Objective-C
5038 // class: the interface and its implementation. When we resolved a
5039 // reference to an Objective-C class, produce the @interface as
5040 // the definition; when we were provided with the interface,
5041 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005042 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005043 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005044 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 return MakeCXCursor(Def, TU);
5046 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5047 return MakeCXCursor(Impl, TU);
5048 return clang_getNullCursor();
5049 }
5050
5051 case Decl::ObjCProperty:
5052 // FIXME: We don't really know where to find the
5053 // ObjCPropertyImplDecls that implement this property.
5054 return clang_getNullCursor();
5055
5056 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005057 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005058 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005059 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005060 return MakeCXCursor(Def, TU);
5061
5062 return clang_getNullCursor();
5063
5064 case Decl::Friend:
5065 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5066 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5067 return clang_getNullCursor();
5068
5069 case Decl::FriendTemplate:
5070 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5071 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5072 return clang_getNullCursor();
5073 }
5074
5075 return clang_getNullCursor();
5076}
5077
5078unsigned clang_isCursorDefinition(CXCursor C) {
5079 if (!clang_isDeclaration(C.kind))
5080 return 0;
5081
5082 return clang_getCursorDefinition(C) == C;
5083}
5084
5085CXCursor clang_getCanonicalCursor(CXCursor C) {
5086 if (!clang_isDeclaration(C.kind))
5087 return C;
5088
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005089 if (const Decl *D = getCursorDecl(C)) {
5090 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005091 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5092 return MakeCXCursor(CatD, getCursorTU(C));
5093
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005094 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5095 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005096 return MakeCXCursor(IFD, getCursorTU(C));
5097
5098 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5099 }
5100
5101 return C;
5102}
5103
5104int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5105 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5106}
5107
5108unsigned clang_getNumOverloadedDecls(CXCursor C) {
5109 if (C.kind != CXCursor_OverloadedDeclRef)
5110 return 0;
5111
5112 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005113 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 return E->getNumDecls();
5115
5116 if (OverloadedTemplateStorage *S
5117 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5118 return S->size();
5119
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005120 const Decl *D = Storage.get<const Decl *>();
5121 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 return Using->shadow_size();
5123
5124 return 0;
5125}
5126
5127CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5128 if (cursor.kind != CXCursor_OverloadedDeclRef)
5129 return clang_getNullCursor();
5130
5131 if (index >= clang_getNumOverloadedDecls(cursor))
5132 return clang_getNullCursor();
5133
5134 CXTranslationUnit TU = getCursorTU(cursor);
5135 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005136 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005137 return MakeCXCursor(E->decls_begin()[index], TU);
5138
5139 if (OverloadedTemplateStorage *S
5140 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5141 return MakeCXCursor(S->begin()[index], TU);
5142
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005143 const Decl *D = Storage.get<const Decl *>();
5144 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 // FIXME: This is, unfortunately, linear time.
5146 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5147 std::advance(Pos, index);
5148 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5149 }
5150
5151 return clang_getNullCursor();
5152}
5153
5154void clang_getDefinitionSpellingAndExtent(CXCursor C,
5155 const char **startBuf,
5156 const char **endBuf,
5157 unsigned *startLine,
5158 unsigned *startColumn,
5159 unsigned *endLine,
5160 unsigned *endColumn) {
5161 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005162 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005163 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5164
5165 SourceManager &SM = FD->getASTContext().getSourceManager();
5166 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5167 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5168 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5169 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5170 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5171 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5172}
5173
5174
5175CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5176 unsigned PieceIndex) {
5177 RefNamePieces Pieces;
5178
5179 switch (C.kind) {
5180 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005181 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5183 E->getQualifierLoc().getSourceRange());
5184 break;
5185
5186 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005187 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5189 E->getQualifierLoc().getSourceRange(),
5190 E->getOptionalExplicitTemplateArgs());
5191 break;
5192
5193 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005194 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005195 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005196 const Expr *Callee = OCE->getCallee();
5197 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 Callee = ICE->getSubExpr();
5199
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005200 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5202 DRE->getQualifierLoc().getSourceRange());
5203 }
5204 break;
5205
5206 default:
5207 break;
5208 }
5209
5210 if (Pieces.empty()) {
5211 if (PieceIndex == 0)
5212 return clang_getCursorExtent(C);
5213 } else if (PieceIndex < Pieces.size()) {
5214 SourceRange R = Pieces[PieceIndex];
5215 if (R.isValid())
5216 return cxloc::translateSourceRange(getCursorContext(C), R);
5217 }
5218
5219 return clang_getNullRange();
5220}
5221
5222void clang_enableStackTraces(void) {
5223 llvm::sys::PrintStackTraceOnErrorSignal();
5224}
5225
5226void clang_executeOnThread(void (*fn)(void*), void *user_data,
5227 unsigned stack_size) {
5228 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5229}
5230
5231} // end: extern "C"
5232
5233//===----------------------------------------------------------------------===//
5234// Token-based Operations.
5235//===----------------------------------------------------------------------===//
5236
5237/* CXToken layout:
5238 * int_data[0]: a CXTokenKind
5239 * int_data[1]: starting token location
5240 * int_data[2]: token length
5241 * int_data[3]: reserved
5242 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5243 * otherwise unused.
5244 */
5245extern "C" {
5246
5247CXTokenKind clang_getTokenKind(CXToken CXTok) {
5248 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5249}
5250
5251CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5252 switch (clang_getTokenKind(CXTok)) {
5253 case CXToken_Identifier:
5254 case CXToken_Keyword:
5255 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005256 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005257 ->getNameStart());
5258
5259 case CXToken_Literal: {
5260 // We have stashed the starting pointer in the ptr_data field. Use it.
5261 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005262 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005263 }
5264
5265 case CXToken_Punctuation:
5266 case CXToken_Comment:
5267 break;
5268 }
5269
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005270 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005271 LOG_BAD_TU(TU);
5272 return cxstring::createEmpty();
5273 }
5274
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 // We have to find the starting buffer pointer the hard way, by
5276 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005277 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005279 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005280
5281 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5282 std::pair<FileID, unsigned> LocInfo
5283 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5284 bool Invalid = false;
5285 StringRef Buffer
5286 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5287 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005288 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005289
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005290 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005291}
5292
5293CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005294 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005295 LOG_BAD_TU(TU);
5296 return clang_getNullLocation();
5297 }
5298
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005299 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 if (!CXXUnit)
5301 return clang_getNullLocation();
5302
5303 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5304 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5305}
5306
5307CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005308 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005309 LOG_BAD_TU(TU);
5310 return clang_getNullRange();
5311 }
5312
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005313 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 if (!CXXUnit)
5315 return clang_getNullRange();
5316
5317 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5318 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5319}
5320
5321static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5322 SmallVectorImpl<CXToken> &CXTokens) {
5323 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5324 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005325 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005327 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005328
5329 // Cannot tokenize across files.
5330 if (BeginLocInfo.first != EndLocInfo.first)
5331 return;
5332
5333 // Create a lexer
5334 bool Invalid = false;
5335 StringRef Buffer
5336 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5337 if (Invalid)
5338 return;
5339
5340 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5341 CXXUnit->getASTContext().getLangOpts(),
5342 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5343 Lex.SetCommentRetentionState(true);
5344
5345 // Lex tokens until we hit the end of the range.
5346 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5347 Token Tok;
5348 bool previousWasAt = false;
5349 do {
5350 // Lex the next token
5351 Lex.LexFromRawLexer(Tok);
5352 if (Tok.is(tok::eof))
5353 break;
5354
5355 // Initialize the CXToken.
5356 CXToken CXTok;
5357
5358 // - Common fields
5359 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5360 CXTok.int_data[2] = Tok.getLength();
5361 CXTok.int_data[3] = 0;
5362
5363 // - Kind-specific fields
5364 if (Tok.isLiteral()) {
5365 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005366 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005367 } else if (Tok.is(tok::raw_identifier)) {
5368 // Lookup the identifier to determine whether we have a keyword.
5369 IdentifierInfo *II
5370 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5371
5372 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5373 CXTok.int_data[0] = CXToken_Keyword;
5374 }
5375 else {
5376 CXTok.int_data[0] = Tok.is(tok::identifier)
5377 ? CXToken_Identifier
5378 : CXToken_Keyword;
5379 }
5380 CXTok.ptr_data = II;
5381 } else if (Tok.is(tok::comment)) {
5382 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005383 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005384 } else {
5385 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005386 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005387 }
5388 CXTokens.push_back(CXTok);
5389 previousWasAt = Tok.is(tok::at);
5390 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5391}
5392
5393void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5394 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005395 LOG_FUNC_SECTION {
5396 *Log << TU << ' ' << Range;
5397 }
5398
Guy Benyei11169dd2012-12-18 14:30:41 +00005399 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005400 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005401 if (NumTokens)
5402 *NumTokens = 0;
5403
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005404 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005405 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005406 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005407 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005408
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005409 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005410 if (!CXXUnit || !Tokens || !NumTokens)
5411 return;
5412
5413 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5414
5415 SourceRange R = cxloc::translateCXSourceRange(Range);
5416 if (R.isInvalid())
5417 return;
5418
5419 SmallVector<CXToken, 32> CXTokens;
5420 getTokens(CXXUnit, R, CXTokens);
5421
5422 if (CXTokens.empty())
5423 return;
5424
5425 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5426 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5427 *NumTokens = CXTokens.size();
5428}
5429
5430void clang_disposeTokens(CXTranslationUnit TU,
5431 CXToken *Tokens, unsigned NumTokens) {
5432 free(Tokens);
5433}
5434
5435} // end: extern "C"
5436
5437//===----------------------------------------------------------------------===//
5438// Token annotation APIs.
5439//===----------------------------------------------------------------------===//
5440
Guy Benyei11169dd2012-12-18 14:30:41 +00005441static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5442 CXCursor parent,
5443 CXClientData client_data);
5444static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5445 CXClientData client_data);
5446
5447namespace {
5448class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 CXToken *Tokens;
5450 CXCursor *Cursors;
5451 unsigned NumTokens;
5452 unsigned TokIdx;
5453 unsigned PreprocessingTokIdx;
5454 CursorVisitor AnnotateVis;
5455 SourceManager &SrcMgr;
5456 bool HasContextSensitiveKeywords;
5457
5458 struct PostChildrenInfo {
5459 CXCursor Cursor;
5460 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005461 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005462 unsigned BeforeChildrenTokenIdx;
5463 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005464 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005465
5466 CXToken &getTok(unsigned Idx) {
5467 assert(Idx < NumTokens);
5468 return Tokens[Idx];
5469 }
5470 const CXToken &getTok(unsigned Idx) const {
5471 assert(Idx < NumTokens);
5472 return Tokens[Idx];
5473 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 bool MoreTokens() const { return TokIdx < NumTokens; }
5475 unsigned NextToken() const { return TokIdx; }
5476 void AdvanceToken() { ++TokIdx; }
5477 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005478 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 }
5480 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005481 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 }
5483 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005484 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 }
5486
5487 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005488 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 SourceRange);
5490
5491public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005492 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005493 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005494 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005495 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005496 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 AnnotateTokensVisitor, this,
5498 /*VisitPreprocessorLast=*/true,
5499 /*VisitIncludedEntities=*/false,
5500 RegionOfInterest,
5501 /*VisitDeclsOnly=*/false,
5502 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005503 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005504 HasContextSensitiveKeywords(false) { }
5505
5506 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5507 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5508 bool postVisitChildren(CXCursor cursor);
5509 void AnnotateTokens();
5510
5511 /// \brief Determine whether the annotator saw any cursors that have
5512 /// context-sensitive keywords.
5513 bool hasContextSensitiveKeywords() const {
5514 return HasContextSensitiveKeywords;
5515 }
5516
5517 ~AnnotateTokensWorker() {
5518 assert(PostChildrenInfos.empty());
5519 }
5520};
5521}
5522
5523void AnnotateTokensWorker::AnnotateTokens() {
5524 // Walk the AST within the region of interest, annotating tokens
5525 // along the way.
5526 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005527}
Guy Benyei11169dd2012-12-18 14:30:41 +00005528
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005529static inline void updateCursorAnnotation(CXCursor &Cursor,
5530 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005531 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005532 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005533 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005534}
5535
5536/// \brief It annotates and advances tokens with a cursor until the comparison
5537//// between the cursor location and the source range is the same as
5538/// \arg compResult.
5539///
5540/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5541/// Pass RangeOverlap to annotate tokens inside a range.
5542void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5543 RangeComparisonResult compResult,
5544 SourceRange range) {
5545 while (MoreTokens()) {
5546 const unsigned I = NextToken();
5547 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005548 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5549 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005550
5551 SourceLocation TokLoc = GetTokenLoc(I);
5552 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005553 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005554 AdvanceToken();
5555 continue;
5556 }
5557 break;
5558 }
5559}
5560
5561/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005562/// \returns true if it advanced beyond all macro tokens, false otherwise.
5563bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005564 CXCursor updateC,
5565 RangeComparisonResult compResult,
5566 SourceRange range) {
5567 assert(MoreTokens());
5568 assert(isFunctionMacroToken(NextToken()) &&
5569 "Should be called only for macro arg tokens");
5570
5571 // This works differently than annotateAndAdvanceTokens; because expanded
5572 // macro arguments can have arbitrary translation-unit source order, we do not
5573 // advance the token index one by one until a token fails the range test.
5574 // We only advance once past all of the macro arg tokens if all of them
5575 // pass the range test. If one of them fails we keep the token index pointing
5576 // at the start of the macro arg tokens so that the failing token will be
5577 // annotated by a subsequent annotation try.
5578
5579 bool atLeastOneCompFail = false;
5580
5581 unsigned I = NextToken();
5582 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5583 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5584 if (TokLoc.isFileID())
5585 continue; // not macro arg token, it's parens or comma.
5586 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5587 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5588 Cursors[I] = updateC;
5589 } else
5590 atLeastOneCompFail = true;
5591 }
5592
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005593 if (atLeastOneCompFail)
5594 return false;
5595
5596 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5597 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005598}
5599
5600enum CXChildVisitResult
5601AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005602 SourceRange cursorRange = getRawCursorExtent(cursor);
5603 if (cursorRange.isInvalid())
5604 return CXChildVisit_Recurse;
5605
5606 if (!HasContextSensitiveKeywords) {
5607 // Objective-C properties can have context-sensitive keywords.
5608 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005609 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005610 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5611 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5612 }
5613 // Objective-C methods can have context-sensitive keywords.
5614 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5615 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005616 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005617 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5618 if (Method->getObjCDeclQualifier())
5619 HasContextSensitiveKeywords = true;
5620 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005621 for (const auto *P : Method->params()) {
5622 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005623 HasContextSensitiveKeywords = true;
5624 break;
5625 }
5626 }
5627 }
5628 }
5629 }
5630 // C++ methods can have context-sensitive keywords.
5631 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005632 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5634 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5635 HasContextSensitiveKeywords = true;
5636 }
5637 }
5638 // C++ classes can have context-sensitive keywords.
5639 else if (cursor.kind == CXCursor_StructDecl ||
5640 cursor.kind == CXCursor_ClassDecl ||
5641 cursor.kind == CXCursor_ClassTemplate ||
5642 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005643 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005644 if (D->hasAttr<FinalAttr>())
5645 HasContextSensitiveKeywords = true;
5646 }
5647 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005648
5649 // Don't override a property annotation with its getter/setter method.
5650 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5651 parent.kind == CXCursor_ObjCPropertyDecl)
5652 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005653
5654 if (clang_isPreprocessing(cursor.kind)) {
5655 // Items in the preprocessing record are kept separate from items in
5656 // declarations, so we keep a separate token index.
5657 unsigned SavedTokIdx = TokIdx;
5658 TokIdx = PreprocessingTokIdx;
5659
5660 // Skip tokens up until we catch up to the beginning of the preprocessing
5661 // entry.
5662 while (MoreTokens()) {
5663 const unsigned I = NextToken();
5664 SourceLocation TokLoc = GetTokenLoc(I);
5665 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5666 case RangeBefore:
5667 AdvanceToken();
5668 continue;
5669 case RangeAfter:
5670 case RangeOverlap:
5671 break;
5672 }
5673 break;
5674 }
5675
5676 // Look at all of the tokens within this range.
5677 while (MoreTokens()) {
5678 const unsigned I = NextToken();
5679 SourceLocation TokLoc = GetTokenLoc(I);
5680 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5681 case RangeBefore:
5682 llvm_unreachable("Infeasible");
5683 case RangeAfter:
5684 break;
5685 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005686 // For macro expansions, just note where the beginning of the macro
5687 // expansion occurs.
5688 if (cursor.kind == CXCursor_MacroExpansion) {
5689 if (TokLoc == cursorRange.getBegin())
5690 Cursors[I] = cursor;
5691 AdvanceToken();
5692 break;
5693 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005694 // We may have already annotated macro names inside macro definitions.
5695 if (Cursors[I].kind != CXCursor_MacroExpansion)
5696 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005697 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005698 continue;
5699 }
5700 break;
5701 }
5702
5703 // Save the preprocessing token index; restore the non-preprocessing
5704 // token index.
5705 PreprocessingTokIdx = TokIdx;
5706 TokIdx = SavedTokIdx;
5707 return CXChildVisit_Recurse;
5708 }
5709
5710 if (cursorRange.isInvalid())
5711 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005712
5713 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005714 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005715 const enum CXCursorKind K = clang_getCursorKind(parent);
5716 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005717 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5718 // Attributes are annotated out-of-order, skip tokens until we reach it.
5719 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 ? clang_getNullCursor() : parent;
5721
5722 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5723
5724 // Avoid having the cursor of an expression "overwrite" the annotation of the
5725 // variable declaration that it belongs to.
5726 // This can happen for C++ constructor expressions whose range generally
5727 // include the variable declaration, e.g.:
5728 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005729 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005730 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005731 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005732 const unsigned I = NextToken();
5733 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5734 E->getLocStart() == D->getLocation() &&
5735 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005736 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005737 AdvanceToken();
5738 }
5739 }
5740 }
5741
5742 // Before recursing into the children keep some state that we are going
5743 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5744 // extra work after the child nodes are visited.
5745 // Note that we don't call VisitChildren here to avoid traversing statements
5746 // code-recursively which can blow the stack.
5747
5748 PostChildrenInfo Info;
5749 Info.Cursor = cursor;
5750 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005751 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 Info.BeforeChildrenTokenIdx = NextToken();
5753 PostChildrenInfos.push_back(Info);
5754
5755 return CXChildVisit_Recurse;
5756}
5757
5758bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5759 if (PostChildrenInfos.empty())
5760 return false;
5761 const PostChildrenInfo &Info = PostChildrenInfos.back();
5762 if (!clang_equalCursors(Info.Cursor, cursor))
5763 return false;
5764
5765 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5766 const unsigned AfterChildren = NextToken();
5767 SourceRange cursorRange = Info.CursorRange;
5768
5769 // Scan the tokens that are at the end of the cursor, but are not captured
5770 // but the child cursors.
5771 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5772
5773 // Scan the tokens that are at the beginning of the cursor, but are not
5774 // capture by the child cursors.
5775 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5776 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5777 break;
5778
5779 Cursors[I] = cursor;
5780 }
5781
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005782 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5783 // encountered the attribute cursor.
5784 if (clang_isAttribute(cursor.kind))
5785 TokIdx = Info.BeforeReachingCursorIdx;
5786
Guy Benyei11169dd2012-12-18 14:30:41 +00005787 PostChildrenInfos.pop_back();
5788 return false;
5789}
5790
5791static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5792 CXCursor parent,
5793 CXClientData client_data) {
5794 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5795}
5796
5797static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5798 CXClientData client_data) {
5799 return static_cast<AnnotateTokensWorker*>(client_data)->
5800 postVisitChildren(cursor);
5801}
5802
5803namespace {
5804
5805/// \brief Uses the macro expansions in the preprocessing record to find
5806/// and mark tokens that are macro arguments. This info is used by the
5807/// AnnotateTokensWorker.
5808class MarkMacroArgTokensVisitor {
5809 SourceManager &SM;
5810 CXToken *Tokens;
5811 unsigned NumTokens;
5812 unsigned CurIdx;
5813
5814public:
5815 MarkMacroArgTokensVisitor(SourceManager &SM,
5816 CXToken *tokens, unsigned numTokens)
5817 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5818
5819 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5820 if (cursor.kind != CXCursor_MacroExpansion)
5821 return CXChildVisit_Continue;
5822
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005823 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005824 if (macroRange.getBegin() == macroRange.getEnd())
5825 return CXChildVisit_Continue; // it's not a function macro.
5826
5827 for (; CurIdx < NumTokens; ++CurIdx) {
5828 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5829 macroRange.getBegin()))
5830 break;
5831 }
5832
5833 if (CurIdx == NumTokens)
5834 return CXChildVisit_Break;
5835
5836 for (; CurIdx < NumTokens; ++CurIdx) {
5837 SourceLocation tokLoc = getTokenLoc(CurIdx);
5838 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5839 break;
5840
5841 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5842 }
5843
5844 if (CurIdx == NumTokens)
5845 return CXChildVisit_Break;
5846
5847 return CXChildVisit_Continue;
5848 }
5849
5850private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005851 CXToken &getTok(unsigned Idx) {
5852 assert(Idx < NumTokens);
5853 return Tokens[Idx];
5854 }
5855 const CXToken &getTok(unsigned Idx) const {
5856 assert(Idx < NumTokens);
5857 return Tokens[Idx];
5858 }
5859
Guy Benyei11169dd2012-12-18 14:30:41 +00005860 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005861 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005862 }
5863
5864 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5865 // The third field is reserved and currently not used. Use it here
5866 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005867 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005868 }
5869};
5870
5871} // end anonymous namespace
5872
5873static CXChildVisitResult
5874MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5875 CXClientData client_data) {
5876 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5877 parent);
5878}
5879
5880namespace {
5881 struct clang_annotateTokens_Data {
5882 CXTranslationUnit TU;
5883 ASTUnit *CXXUnit;
5884 CXToken *Tokens;
5885 unsigned NumTokens;
5886 CXCursor *Cursors;
5887 };
5888}
5889
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005890/// \brief Used by \c annotatePreprocessorTokens.
5891/// \returns true if lexing was finished, false otherwise.
5892static bool lexNext(Lexer &Lex, Token &Tok,
5893 unsigned &NextIdx, unsigned NumTokens) {
5894 if (NextIdx >= NumTokens)
5895 return true;
5896
5897 ++NextIdx;
5898 Lex.LexFromRawLexer(Tok);
5899 if (Tok.is(tok::eof))
5900 return true;
5901
5902 return false;
5903}
5904
Guy Benyei11169dd2012-12-18 14:30:41 +00005905static void annotatePreprocessorTokens(CXTranslationUnit TU,
5906 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005907 CXCursor *Cursors,
5908 CXToken *Tokens,
5909 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005910 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005911
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005912 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005913 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5914 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005915 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005916 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005917 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005918
5919 if (BeginLocInfo.first != EndLocInfo.first)
5920 return;
5921
5922 StringRef Buffer;
5923 bool Invalid = false;
5924 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5925 if (Buffer.empty() || Invalid)
5926 return;
5927
5928 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5929 CXXUnit->getASTContext().getLangOpts(),
5930 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5931 Buffer.end());
5932 Lex.SetCommentRetentionState(true);
5933
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005934 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005935 // Lex tokens in raw mode until we hit the end of the range, to avoid
5936 // entering #includes or expanding macros.
5937 while (true) {
5938 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005939 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5940 break;
5941 unsigned TokIdx = NextIdx-1;
5942 assert(Tok.getLocation() ==
5943 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005944
5945 reprocess:
5946 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005947 // We have found a preprocessing directive. Annotate the tokens
5948 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005949 //
5950 // FIXME: Some simple tests here could identify macro definitions and
5951 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005952
5953 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005954 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5955 break;
5956
Craig Topper69186e72014-06-08 08:38:04 +00005957 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005958 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005959 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5960 break;
5961
5962 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005963 IdentifierInfo &II =
5964 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005965 SourceLocation MappedTokLoc =
5966 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5967 MI = getMacroInfo(II, MappedTokLoc, TU);
5968 }
5969 }
5970
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005971 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005972 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005973 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5974 finished = true;
5975 break;
5976 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005977 // If we are in a macro definition, check if the token was ever a
5978 // macro name and annotate it if that's the case.
5979 if (MI) {
5980 SourceLocation SaveLoc = Tok.getLocation();
5981 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5982 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5983 Tok.setLocation(SaveLoc);
5984 if (MacroDef)
5985 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5986 Tok.getLocation(), TU);
5987 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005988 } while (!Tok.isAtStartOfLine());
5989
5990 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5991 assert(TokIdx <= LastIdx);
5992 SourceLocation EndLoc =
5993 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5994 CXCursor Cursor =
5995 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5996
5997 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005998 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005999
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006000 if (finished)
6001 break;
6002 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006003 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006004 }
6005}
6006
6007// This gets run a separate thread to avoid stack blowout.
6008static void clang_annotateTokensImpl(void *UserData) {
6009 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6010 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6011 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6012 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6013 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6014
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006015 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6017 setThreadBackgroundPriority();
6018
6019 // Determine the region of interest, which contains all of the tokens.
6020 SourceRange RegionOfInterest;
6021 RegionOfInterest.setBegin(
6022 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6023 RegionOfInterest.setEnd(
6024 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6025 Tokens[NumTokens-1])));
6026
Guy Benyei11169dd2012-12-18 14:30:41 +00006027 // Relex the tokens within the source range to look for preprocessing
6028 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006029 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006030
6031 // If begin location points inside a macro argument, set it to the expansion
6032 // location so we can have the full context when annotating semantically.
6033 {
6034 SourceManager &SM = CXXUnit->getSourceManager();
6035 SourceLocation Loc =
6036 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6037 if (Loc.isMacroID())
6038 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6039 }
6040
Guy Benyei11169dd2012-12-18 14:30:41 +00006041 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6042 // Search and mark tokens that are macro argument expansions.
6043 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6044 Tokens, NumTokens);
6045 CursorVisitor MacroArgMarker(TU,
6046 MarkMacroArgTokensVisitorDelegate, &Visitor,
6047 /*VisitPreprocessorLast=*/true,
6048 /*VisitIncludedEntities=*/false,
6049 RegionOfInterest);
6050 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6051 }
6052
6053 // Annotate all of the source locations in the region of interest that map to
6054 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006055 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006056
6057 // FIXME: We use a ridiculous stack size here because the data-recursion
6058 // algorithm uses a large stack frame than the non-data recursive version,
6059 // and AnnotationTokensWorker currently transforms the data-recursion
6060 // algorithm back into a traditional recursion by explicitly calling
6061 // VisitChildren(). We will need to remove this explicit recursive call.
6062 W.AnnotateTokens();
6063
6064 // If we ran into any entities that involve context-sensitive keywords,
6065 // take another pass through the tokens to mark them as such.
6066 if (W.hasContextSensitiveKeywords()) {
6067 for (unsigned I = 0; I != NumTokens; ++I) {
6068 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6069 continue;
6070
6071 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6072 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006073 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006074 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6075 if (Property->getPropertyAttributesAsWritten() != 0 &&
6076 llvm::StringSwitch<bool>(II->getName())
6077 .Case("readonly", true)
6078 .Case("assign", true)
6079 .Case("unsafe_unretained", true)
6080 .Case("readwrite", true)
6081 .Case("retain", true)
6082 .Case("copy", true)
6083 .Case("nonatomic", true)
6084 .Case("atomic", true)
6085 .Case("getter", true)
6086 .Case("setter", true)
6087 .Case("strong", true)
6088 .Case("weak", true)
6089 .Default(false))
6090 Tokens[I].int_data[0] = CXToken_Keyword;
6091 }
6092 continue;
6093 }
6094
6095 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6096 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6097 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6098 if (llvm::StringSwitch<bool>(II->getName())
6099 .Case("in", true)
6100 .Case("out", true)
6101 .Case("inout", true)
6102 .Case("oneway", true)
6103 .Case("bycopy", true)
6104 .Case("byref", true)
6105 .Default(false))
6106 Tokens[I].int_data[0] = CXToken_Keyword;
6107 continue;
6108 }
6109
6110 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6111 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6112 Tokens[I].int_data[0] = CXToken_Keyword;
6113 continue;
6114 }
6115 }
6116 }
6117}
6118
6119extern "C" {
6120
6121void clang_annotateTokens(CXTranslationUnit TU,
6122 CXToken *Tokens, unsigned NumTokens,
6123 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006124 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006125 LOG_BAD_TU(TU);
6126 return;
6127 }
6128 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006129 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006130 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006131 }
6132
6133 LOG_FUNC_SECTION {
6134 *Log << TU << ' ';
6135 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6136 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6137 *Log << clang_getRange(bloc, eloc);
6138 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006139
6140 // Any token we don't specifically annotate will have a NULL cursor.
6141 CXCursor C = clang_getNullCursor();
6142 for (unsigned I = 0; I != NumTokens; ++I)
6143 Cursors[I] = C;
6144
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006145 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006146 if (!CXXUnit)
6147 return;
6148
6149 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6150
6151 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6152 llvm::CrashRecoveryContext CRC;
6153 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6154 GetSafetyThreadStackSize() * 2)) {
6155 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6156 }
6157}
6158
6159} // end: extern "C"
6160
6161//===----------------------------------------------------------------------===//
6162// Operations for querying linkage of a cursor.
6163//===----------------------------------------------------------------------===//
6164
6165extern "C" {
6166CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6167 if (!clang_isDeclaration(cursor.kind))
6168 return CXLinkage_Invalid;
6169
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006170 const Decl *D = cxcursor::getCursorDecl(cursor);
6171 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006172 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006173 case NoLinkage:
6174 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006175 case InternalLinkage: return CXLinkage_Internal;
6176 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6177 case ExternalLinkage: return CXLinkage_External;
6178 };
6179
6180 return CXLinkage_Invalid;
6181}
6182} // end: extern "C"
6183
6184//===----------------------------------------------------------------------===//
6185// Operations for querying language of a cursor.
6186//===----------------------------------------------------------------------===//
6187
6188static CXLanguageKind getDeclLanguage(const Decl *D) {
6189 if (!D)
6190 return CXLanguage_C;
6191
6192 switch (D->getKind()) {
6193 default:
6194 break;
6195 case Decl::ImplicitParam:
6196 case Decl::ObjCAtDefsField:
6197 case Decl::ObjCCategory:
6198 case Decl::ObjCCategoryImpl:
6199 case Decl::ObjCCompatibleAlias:
6200 case Decl::ObjCImplementation:
6201 case Decl::ObjCInterface:
6202 case Decl::ObjCIvar:
6203 case Decl::ObjCMethod:
6204 case Decl::ObjCProperty:
6205 case Decl::ObjCPropertyImpl:
6206 case Decl::ObjCProtocol:
6207 return CXLanguage_ObjC;
6208 case Decl::CXXConstructor:
6209 case Decl::CXXConversion:
6210 case Decl::CXXDestructor:
6211 case Decl::CXXMethod:
6212 case Decl::CXXRecord:
6213 case Decl::ClassTemplate:
6214 case Decl::ClassTemplatePartialSpecialization:
6215 case Decl::ClassTemplateSpecialization:
6216 case Decl::Friend:
6217 case Decl::FriendTemplate:
6218 case Decl::FunctionTemplate:
6219 case Decl::LinkageSpec:
6220 case Decl::Namespace:
6221 case Decl::NamespaceAlias:
6222 case Decl::NonTypeTemplateParm:
6223 case Decl::StaticAssert:
6224 case Decl::TemplateTemplateParm:
6225 case Decl::TemplateTypeParm:
6226 case Decl::UnresolvedUsingTypename:
6227 case Decl::UnresolvedUsingValue:
6228 case Decl::Using:
6229 case Decl::UsingDirective:
6230 case Decl::UsingShadow:
6231 return CXLanguage_CPlusPlus;
6232 }
6233
6234 return CXLanguage_C;
6235}
6236
6237extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006238
6239static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6240 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6241 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006242
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006243 switch (D->getAvailability()) {
6244 case AR_Available:
6245 case AR_NotYetIntroduced:
6246 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006247 return getCursorAvailabilityForDecl(
6248 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006249 return CXAvailability_Available;
6250
6251 case AR_Deprecated:
6252 return CXAvailability_Deprecated;
6253
6254 case AR_Unavailable:
6255 return CXAvailability_NotAvailable;
6256 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006257
6258 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006259}
6260
Guy Benyei11169dd2012-12-18 14:30:41 +00006261enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6262 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006263 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6264 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006265
6266 return CXAvailability_Available;
6267}
6268
6269static CXVersion convertVersion(VersionTuple In) {
6270 CXVersion Out = { -1, -1, -1 };
6271 if (In.empty())
6272 return Out;
6273
6274 Out.Major = In.getMajor();
6275
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006276 Optional<unsigned> Minor = In.getMinor();
6277 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006278 Out.Minor = *Minor;
6279 else
6280 return Out;
6281
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006282 Optional<unsigned> Subminor = In.getSubminor();
6283 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006284 Out.Subminor = *Subminor;
6285
6286 return Out;
6287}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006288
6289static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6290 int *always_deprecated,
6291 CXString *deprecated_message,
6292 int *always_unavailable,
6293 CXString *unavailable_message,
6294 CXPlatformAvailability *availability,
6295 int availability_size) {
6296 bool HadAvailAttr = false;
6297 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006298 for (auto A : D->attrs()) {
6299 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006300 HadAvailAttr = true;
6301 if (always_deprecated)
6302 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006303 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006304 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006305 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006306 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006307 continue;
6308 }
6309
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006310 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006311 HadAvailAttr = true;
6312 if (always_unavailable)
6313 *always_unavailable = 1;
6314 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006315 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006316 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6317 }
6318 continue;
6319 }
6320
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006321 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006322 HadAvailAttr = true;
6323 if (N < availability_size) {
6324 availability[N].Platform
6325 = cxstring::createDup(Avail->getPlatform()->getName());
6326 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6327 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6328 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6329 availability[N].Unavailable = Avail->getUnavailable();
6330 availability[N].Message = cxstring::createDup(Avail->getMessage());
6331 }
6332 ++N;
6333 }
6334 }
6335
6336 if (!HadAvailAttr)
6337 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6338 return getCursorPlatformAvailabilityForDecl(
6339 cast<Decl>(EnumConst->getDeclContext()),
6340 always_deprecated,
6341 deprecated_message,
6342 always_unavailable,
6343 unavailable_message,
6344 availability,
6345 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006346
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006347 return N;
6348}
6349
Guy Benyei11169dd2012-12-18 14:30:41 +00006350int clang_getCursorPlatformAvailability(CXCursor cursor,
6351 int *always_deprecated,
6352 CXString *deprecated_message,
6353 int *always_unavailable,
6354 CXString *unavailable_message,
6355 CXPlatformAvailability *availability,
6356 int availability_size) {
6357 if (always_deprecated)
6358 *always_deprecated = 0;
6359 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006360 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006361 if (always_unavailable)
6362 *always_unavailable = 0;
6363 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006364 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006365
Guy Benyei11169dd2012-12-18 14:30:41 +00006366 if (!clang_isDeclaration(cursor.kind))
6367 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006368
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006369 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006370 if (!D)
6371 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006372
6373 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6374 deprecated_message,
6375 always_unavailable,
6376 unavailable_message,
6377 availability,
6378 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006379}
6380
6381void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6382 clang_disposeString(availability->Platform);
6383 clang_disposeString(availability->Message);
6384}
6385
6386CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6387 if (clang_isDeclaration(cursor.kind))
6388 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6389
6390 return CXLanguage_Invalid;
6391}
6392
6393 /// \brief If the given cursor is the "templated" declaration
6394 /// descibing a class or function template, return the class or
6395 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006396static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006397 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006398 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006399
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006400 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006401 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6402 return FunTmpl;
6403
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006404 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006405 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6406 return ClassTmpl;
6407
6408 return D;
6409}
6410
6411CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6412 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006413 if (const Decl *D = getCursorDecl(cursor)) {
6414 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006415 if (!DC)
6416 return clang_getNullCursor();
6417
6418 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6419 getCursorTU(cursor));
6420 }
6421 }
6422
6423 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006424 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006425 return MakeCXCursor(D, getCursorTU(cursor));
6426 }
6427
6428 return clang_getNullCursor();
6429}
6430
6431CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6432 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006433 if (const Decl *D = getCursorDecl(cursor)) {
6434 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006435 if (!DC)
6436 return clang_getNullCursor();
6437
6438 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6439 getCursorTU(cursor));
6440 }
6441 }
6442
6443 // FIXME: Note that we can't easily compute the lexical context of a
6444 // statement or expression, so we return nothing.
6445 return clang_getNullCursor();
6446}
6447
6448CXFile clang_getIncludedFile(CXCursor cursor) {
6449 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006450 return nullptr;
6451
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006452 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006453 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006454}
6455
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006456unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6457 if (C.kind != CXCursor_ObjCPropertyDecl)
6458 return CXObjCPropertyAttr_noattr;
6459
6460 unsigned Result = CXObjCPropertyAttr_noattr;
6461 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6462 ObjCPropertyDecl::PropertyAttributeKind Attr =
6463 PD->getPropertyAttributesAsWritten();
6464
6465#define SET_CXOBJCPROP_ATTR(A) \
6466 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6467 Result |= CXObjCPropertyAttr_##A
6468 SET_CXOBJCPROP_ATTR(readonly);
6469 SET_CXOBJCPROP_ATTR(getter);
6470 SET_CXOBJCPROP_ATTR(assign);
6471 SET_CXOBJCPROP_ATTR(readwrite);
6472 SET_CXOBJCPROP_ATTR(retain);
6473 SET_CXOBJCPROP_ATTR(copy);
6474 SET_CXOBJCPROP_ATTR(nonatomic);
6475 SET_CXOBJCPROP_ATTR(setter);
6476 SET_CXOBJCPROP_ATTR(atomic);
6477 SET_CXOBJCPROP_ATTR(weak);
6478 SET_CXOBJCPROP_ATTR(strong);
6479 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6480#undef SET_CXOBJCPROP_ATTR
6481
6482 return Result;
6483}
6484
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006485unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6486 if (!clang_isDeclaration(C.kind))
6487 return CXObjCDeclQualifier_None;
6488
6489 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6490 const Decl *D = getCursorDecl(C);
6491 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6492 QT = MD->getObjCDeclQualifier();
6493 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6494 QT = PD->getObjCDeclQualifier();
6495 if (QT == Decl::OBJC_TQ_None)
6496 return CXObjCDeclQualifier_None;
6497
6498 unsigned Result = CXObjCDeclQualifier_None;
6499 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6500 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6501 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6502 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6503 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6504 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6505
6506 return Result;
6507}
6508
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006509unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6510 if (!clang_isDeclaration(C.kind))
6511 return 0;
6512
6513 const Decl *D = getCursorDecl(C);
6514 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6515 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6516 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6517 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6518
6519 return 0;
6520}
6521
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006522unsigned clang_Cursor_isVariadic(CXCursor C) {
6523 if (!clang_isDeclaration(C.kind))
6524 return 0;
6525
6526 const Decl *D = getCursorDecl(C);
6527 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6528 return FD->isVariadic();
6529 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6530 return MD->isVariadic();
6531
6532 return 0;
6533}
6534
Guy Benyei11169dd2012-12-18 14:30:41 +00006535CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6536 if (!clang_isDeclaration(C.kind))
6537 return clang_getNullRange();
6538
6539 const Decl *D = getCursorDecl(C);
6540 ASTContext &Context = getCursorContext(C);
6541 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6542 if (!RC)
6543 return clang_getNullRange();
6544
6545 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6546}
6547
6548CXString clang_Cursor_getRawCommentText(CXCursor C) {
6549 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006550 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006551
6552 const Decl *D = getCursorDecl(C);
6553 ASTContext &Context = getCursorContext(C);
6554 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6555 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6556 StringRef();
6557
6558 // Don't duplicate the string because RawText points directly into source
6559 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006560 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006561}
6562
6563CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6564 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006565 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006566
6567 const Decl *D = getCursorDecl(C);
6568 const ASTContext &Context = getCursorContext(C);
6569 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6570
6571 if (RC) {
6572 StringRef BriefText = RC->getBriefText(Context);
6573
6574 // Don't duplicate the string because RawComment ensures that this memory
6575 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006576 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006577 }
6578
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006579 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006580}
6581
Guy Benyei11169dd2012-12-18 14:30:41 +00006582CXModule clang_Cursor_getModule(CXCursor C) {
6583 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006584 if (const ImportDecl *ImportD =
6585 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006586 return ImportD->getImportedModule();
6587 }
6588
Craig Topper69186e72014-06-08 08:38:04 +00006589 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006590}
6591
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006592CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6593 if (isNotUsableTU(TU)) {
6594 LOG_BAD_TU(TU);
6595 return nullptr;
6596 }
6597 if (!File)
6598 return nullptr;
6599 FileEntry *FE = static_cast<FileEntry *>(File);
6600
6601 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6602 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6603 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6604
6605 if (Module *Mod = Header.getModule()) {
6606 if (Header.getRole() != ModuleMap::ExcludedHeader)
6607 return Mod;
6608 }
6609 return nullptr;
6610}
6611
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006612CXFile clang_Module_getASTFile(CXModule CXMod) {
6613 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006614 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006615 Module *Mod = static_cast<Module*>(CXMod);
6616 return const_cast<FileEntry *>(Mod->getASTFile());
6617}
6618
Guy Benyei11169dd2012-12-18 14:30:41 +00006619CXModule clang_Module_getParent(CXModule CXMod) {
6620 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006621 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006622 Module *Mod = static_cast<Module*>(CXMod);
6623 return Mod->Parent;
6624}
6625
6626CXString clang_Module_getName(CXModule CXMod) {
6627 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006628 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006629 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006630 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006631}
6632
6633CXString clang_Module_getFullName(CXModule CXMod) {
6634 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006635 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006636 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006637 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006638}
6639
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006640int clang_Module_isSystem(CXModule CXMod) {
6641 if (!CXMod)
6642 return 0;
6643 Module *Mod = static_cast<Module*>(CXMod);
6644 return Mod->IsSystem;
6645}
6646
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006647unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6648 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006649 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006650 LOG_BAD_TU(TU);
6651 return 0;
6652 }
6653 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006654 return 0;
6655 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006656 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6657 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6658 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006659}
6660
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006661CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6662 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006663 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006664 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006665 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006666 }
6667 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006668 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006669 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006670 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006671
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006672 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6673 if (Index < TopHeaders.size())
6674 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006675
Craig Topper69186e72014-06-08 08:38:04 +00006676 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006677}
6678
6679} // end: extern "C"
6680
6681//===----------------------------------------------------------------------===//
6682// C++ AST instrospection.
6683//===----------------------------------------------------------------------===//
6684
6685extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006686unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6687 if (!clang_isDeclaration(C.kind))
6688 return 0;
6689
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006690 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006691 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006692 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006693 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6694}
6695
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006696unsigned clang_CXXMethod_isConst(CXCursor C) {
6697 if (!clang_isDeclaration(C.kind))
6698 return 0;
6699
6700 const Decl *D = cxcursor::getCursorDecl(C);
6701 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006702 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006703 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6704}
6705
Guy Benyei11169dd2012-12-18 14:30:41 +00006706unsigned clang_CXXMethod_isStatic(CXCursor C) {
6707 if (!clang_isDeclaration(C.kind))
6708 return 0;
6709
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006710 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006711 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006712 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006713 return (Method && Method->isStatic()) ? 1 : 0;
6714}
6715
6716unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6717 if (!clang_isDeclaration(C.kind))
6718 return 0;
6719
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006720 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006721 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006722 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006723 return (Method && Method->isVirtual()) ? 1 : 0;
6724}
6725} // end: extern "C"
6726
6727//===----------------------------------------------------------------------===//
6728// Attribute introspection.
6729//===----------------------------------------------------------------------===//
6730
6731extern "C" {
6732CXType clang_getIBOutletCollectionType(CXCursor C) {
6733 if (C.kind != CXCursor_IBOutletCollectionAttr)
6734 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6735
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006736 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006737 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6738
6739 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6740}
6741} // end: extern "C"
6742
6743//===----------------------------------------------------------------------===//
6744// Inspecting memory usage.
6745//===----------------------------------------------------------------------===//
6746
6747typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6748
6749static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6750 enum CXTUResourceUsageKind k,
6751 unsigned long amount) {
6752 CXTUResourceUsageEntry entry = { k, amount };
6753 entries.push_back(entry);
6754}
6755
6756extern "C" {
6757
6758const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6759 const char *str = "";
6760 switch (kind) {
6761 case CXTUResourceUsage_AST:
6762 str = "ASTContext: expressions, declarations, and types";
6763 break;
6764 case CXTUResourceUsage_Identifiers:
6765 str = "ASTContext: identifiers";
6766 break;
6767 case CXTUResourceUsage_Selectors:
6768 str = "ASTContext: selectors";
6769 break;
6770 case CXTUResourceUsage_GlobalCompletionResults:
6771 str = "Code completion: cached global results";
6772 break;
6773 case CXTUResourceUsage_SourceManagerContentCache:
6774 str = "SourceManager: content cache allocator";
6775 break;
6776 case CXTUResourceUsage_AST_SideTables:
6777 str = "ASTContext: side tables";
6778 break;
6779 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6780 str = "SourceManager: malloc'ed memory buffers";
6781 break;
6782 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6783 str = "SourceManager: mmap'ed memory buffers";
6784 break;
6785 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6786 str = "ExternalASTSource: malloc'ed memory buffers";
6787 break;
6788 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6789 str = "ExternalASTSource: mmap'ed memory buffers";
6790 break;
6791 case CXTUResourceUsage_Preprocessor:
6792 str = "Preprocessor: malloc'ed memory";
6793 break;
6794 case CXTUResourceUsage_PreprocessingRecord:
6795 str = "Preprocessor: PreprocessingRecord";
6796 break;
6797 case CXTUResourceUsage_SourceManager_DataStructures:
6798 str = "SourceManager: data structures and tables";
6799 break;
6800 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6801 str = "Preprocessor: header search tables";
6802 break;
6803 }
6804 return str;
6805}
6806
6807CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006808 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006809 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006810 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006811 return usage;
6812 }
6813
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006814 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006815 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006816 ASTContext &astContext = astUnit->getASTContext();
6817
6818 // How much memory is used by AST nodes and types?
6819 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6820 (unsigned long) astContext.getASTAllocatedMemory());
6821
6822 // How much memory is used by identifiers?
6823 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6824 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6825
6826 // How much memory is used for selectors?
6827 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6828 (unsigned long) astContext.Selectors.getTotalMemory());
6829
6830 // How much memory is used by ASTContext's side tables?
6831 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6832 (unsigned long) astContext.getSideTableAllocatedMemory());
6833
6834 // How much memory is used for caching global code completion results?
6835 unsigned long completionBytes = 0;
6836 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006837 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006838 completionBytes = completionAllocator->getTotalMemory();
6839 }
6840 createCXTUResourceUsageEntry(*entries,
6841 CXTUResourceUsage_GlobalCompletionResults,
6842 completionBytes);
6843
6844 // How much memory is being used by SourceManager's content cache?
6845 createCXTUResourceUsageEntry(*entries,
6846 CXTUResourceUsage_SourceManagerContentCache,
6847 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6848
6849 // How much memory is being used by the MemoryBuffer's in SourceManager?
6850 const SourceManager::MemoryBufferSizes &srcBufs =
6851 astUnit->getSourceManager().getMemoryBufferSizes();
6852
6853 createCXTUResourceUsageEntry(*entries,
6854 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6855 (unsigned long) srcBufs.malloc_bytes);
6856 createCXTUResourceUsageEntry(*entries,
6857 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6858 (unsigned long) srcBufs.mmap_bytes);
6859 createCXTUResourceUsageEntry(*entries,
6860 CXTUResourceUsage_SourceManager_DataStructures,
6861 (unsigned long) astContext.getSourceManager()
6862 .getDataStructureSizes());
6863
6864 // How much memory is being used by the ExternalASTSource?
6865 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6866 const ExternalASTSource::MemoryBufferSizes &sizes =
6867 esrc->getMemoryBufferSizes();
6868
6869 createCXTUResourceUsageEntry(*entries,
6870 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6871 (unsigned long) sizes.malloc_bytes);
6872 createCXTUResourceUsageEntry(*entries,
6873 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6874 (unsigned long) sizes.mmap_bytes);
6875 }
6876
6877 // How much memory is being used by the Preprocessor?
6878 Preprocessor &pp = astUnit->getPreprocessor();
6879 createCXTUResourceUsageEntry(*entries,
6880 CXTUResourceUsage_Preprocessor,
6881 pp.getTotalMemory());
6882
6883 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6884 createCXTUResourceUsageEntry(*entries,
6885 CXTUResourceUsage_PreprocessingRecord,
6886 pRec->getTotalMemory());
6887 }
6888
6889 createCXTUResourceUsageEntry(*entries,
6890 CXTUResourceUsage_Preprocessor_HeaderSearch,
6891 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006892
Guy Benyei11169dd2012-12-18 14:30:41 +00006893 CXTUResourceUsage usage = { (void*) entries.get(),
6894 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006895 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006896 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006897 return usage;
6898}
6899
6900void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6901 if (usage.data)
6902 delete (MemUsageEntries*) usage.data;
6903}
6904
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006905CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6906 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006907 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006908 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006909
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006910 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006911 LOG_BAD_TU(TU);
6912 return skipped;
6913 }
6914
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006915 if (!file)
6916 return skipped;
6917
6918 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6919 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6920 if (!ppRec)
6921 return skipped;
6922
6923 ASTContext &Ctx = astUnit->getASTContext();
6924 SourceManager &sm = Ctx.getSourceManager();
6925 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6926 FileID wantedFileID = sm.translateFile(fileEntry);
6927
6928 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6929 std::vector<SourceRange> wantedRanges;
6930 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6931 i != ei; ++i) {
6932 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6933 wantedRanges.push_back(*i);
6934 }
6935
6936 skipped->count = wantedRanges.size();
6937 skipped->ranges = new CXSourceRange[skipped->count];
6938 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6939 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6940
6941 return skipped;
6942}
6943
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006944void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6945 if (ranges) {
6946 delete[] ranges->ranges;
6947 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006948 }
6949}
6950
Guy Benyei11169dd2012-12-18 14:30:41 +00006951} // end extern "C"
6952
6953void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6954 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6955 for (unsigned I = 0; I != Usage.numEntries; ++I)
6956 fprintf(stderr, " %s: %lu\n",
6957 clang_getTUResourceUsageName(Usage.entries[I].kind),
6958 Usage.entries[I].amount);
6959
6960 clang_disposeCXTUResourceUsage(Usage);
6961}
6962
6963//===----------------------------------------------------------------------===//
6964// Misc. utility functions.
6965//===----------------------------------------------------------------------===//
6966
6967/// Default to using an 8 MB stack size on "safety" threads.
6968static unsigned SafetyStackThreadSize = 8 << 20;
6969
6970namespace clang {
6971
6972bool RunSafely(llvm::CrashRecoveryContext &CRC,
6973 void (*Fn)(void*), void *UserData,
6974 unsigned Size) {
6975 if (!Size)
6976 Size = GetSafetyThreadStackSize();
6977 if (Size)
6978 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6979 return CRC.RunSafely(Fn, UserData);
6980}
6981
6982unsigned GetSafetyThreadStackSize() {
6983 return SafetyStackThreadSize;
6984}
6985
6986void SetSafetyThreadStackSize(unsigned Value) {
6987 SafetyStackThreadSize = Value;
6988}
6989
6990}
6991
6992void clang::setThreadBackgroundPriority() {
6993 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6994 return;
6995
Alp Toker1a86ad22014-07-06 06:24:00 +00006996#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006997 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6998#endif
6999}
7000
7001void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7002 if (!Unit)
7003 return;
7004
7005 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7006 DEnd = Unit->stored_diag_end();
7007 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007008 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007009 CXString Msg = clang_formatDiagnostic(&Diag,
7010 clang_defaultDiagnosticDisplayOptions());
7011 fprintf(stderr, "%s\n", clang_getCString(Msg));
7012 clang_disposeString(Msg);
7013 }
7014#ifdef LLVM_ON_WIN32
7015 // On Windows, force a flush, since there may be multiple copies of
7016 // stderr and stdout in the file system, all with different buffers
7017 // but writing to the same device.
7018 fflush(stderr);
7019#endif
7020}
7021
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007022MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7023 SourceLocation MacroDefLoc,
7024 CXTranslationUnit TU){
7025 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007026 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007027 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007028 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007029
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007030 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007031 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007032 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007033 if (MD) {
7034 for (MacroDirective::DefInfo
7035 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7036 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7037 return Def.getMacroInfo();
7038 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007039 }
7040
Craig Topper69186e72014-06-08 08:38:04 +00007041 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007042}
7043
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007044const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7045 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007046 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007047 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007048 const IdentifierInfo *II = MacroDef->getName();
7049 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007050 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007051
7052 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7053}
7054
7055MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7056 const Token &Tok,
7057 CXTranslationUnit TU) {
7058 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007059 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007060 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007061 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007062
7063 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007064 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007065 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7066 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007067 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007068
7069 // Check that the token is inside the definition and not its argument list.
7070 SourceManager &SM = Unit->getSourceManager();
7071 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007072 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007073 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007074 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007075
7076 Preprocessor &PP = Unit->getPreprocessor();
7077 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7078 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007079 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007080
Alp Toker2d57cea2014-05-17 04:53:25 +00007081 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007082 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007083 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007084
7085 // Check that the identifier is not one of the macro arguments.
7086 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007087 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007088
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007089 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7090 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007091 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007092
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007093 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007094}
7095
7096MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7097 SourceLocation Loc,
7098 CXTranslationUnit TU) {
7099 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007100 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007101
7102 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007103 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007104 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007105 Preprocessor &PP = Unit->getPreprocessor();
7106 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007107 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007108 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7109 Token Tok;
7110 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007111 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007112
7113 return checkForMacroInMacroDefinition(MI, Tok, TU);
7114}
7115
Guy Benyei11169dd2012-12-18 14:30:41 +00007116extern "C" {
7117
7118CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007119 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007120}
7121
7122} // end: extern "C"
7123
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007124Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7125 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007126 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007127 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007128 if (Unit->isMainFileAST())
7129 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007130 return *this;
7131 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007132 } else {
7133 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007134 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007135 return *this;
7136}
7137
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007138Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7139 *this << FE->getName();
7140 return *this;
7141}
7142
7143Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7144 CXString cursorName = clang_getCursorDisplayName(cursor);
7145 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7146 clang_disposeString(cursorName);
7147 return *this;
7148}
7149
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007150Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7151 CXFile File;
7152 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007153 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007154 CXString FileName = clang_getFileName(File);
7155 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7156 clang_disposeString(FileName);
7157 return *this;
7158}
7159
7160Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7161 CXSourceLocation BLoc = clang_getRangeStart(range);
7162 CXSourceLocation ELoc = clang_getRangeEnd(range);
7163
7164 CXFile BFile;
7165 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007166 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007167
7168 CXFile EFile;
7169 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007170 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007171
7172 CXString BFileName = clang_getFileName(BFile);
7173 if (BFile == EFile) {
7174 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7175 BLine, BColumn, ELine, EColumn);
7176 } else {
7177 CXString EFileName = clang_getFileName(EFile);
7178 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7179 BLine, BColumn)
7180 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7181 ELine, EColumn);
7182 clang_disposeString(EFileName);
7183 }
7184 clang_disposeString(BFileName);
7185 return *this;
7186}
7187
7188Logger &cxindex::Logger::operator<<(CXString Str) {
7189 *this << clang_getCString(Str);
7190 return *this;
7191}
7192
7193Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7194 LogOS << Fmt;
7195 return *this;
7196}
7197
Chandler Carruth37ad2582014-06-27 15:14:39 +00007198static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7199
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007200cxindex::Logger::~Logger() {
7201 LogOS.flush();
7202
Chandler Carruth37ad2582014-06-27 15:14:39 +00007203 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007204
7205 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7206
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007207 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007208 OS << "[libclang:" << Name << ':';
7209
Alp Toker1a86ad22014-07-06 06:24:00 +00007210#ifdef USE_DARWIN_THREADS
7211 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007212 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7213 OS << tid << ':';
7214#endif
7215
7216 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7217 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7218 OS << Msg.str() << '\n';
7219
7220 if (Trace) {
7221 llvm::sys::PrintStackTrace(stderr);
7222 OS << "--------------------------------------------------\n";
7223 }
7224}