blob: df696b1cdf4bef8257569405b5e5a329befc3b27 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
243 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
244 Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
458
459 continue;
460 }
461
462 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
465
466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000572 if (MacroDefinition *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
667bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669 return Visit(TSInfo->getTypeLoc());
670
671 return false;
672}
673
674bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682 return VisitDeclContext(D);
683}
684
685bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686 ClassTemplateSpecializationDecl *D) {
687 bool ShouldVisitBody = false;
688 switch (D->getSpecializationKind()) {
689 case TSK_Undeclared:
690 case TSK_ImplicitInstantiation:
691 // Nothing to visit
692 return false;
693
694 case TSK_ExplicitInstantiationDeclaration:
695 case TSK_ExplicitInstantiationDefinition:
696 break;
697
698 case TSK_ExplicitSpecialization:
699 ShouldVisitBody = true;
700 break;
701 }
702
703 // Visit the template arguments used in the specialization.
704 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000706 if (TemplateSpecializationTypeLoc TSTLoc =
707 TL.getAs<TemplateSpecializationTypeLoc>()) {
708 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000710 return true;
711 }
712 }
713
714 if (ShouldVisitBody && VisitCXXRecordDecl(D))
715 return true;
716
717 return false;
718}
719
720bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721 ClassTemplatePartialSpecializationDecl *D) {
722 // FIXME: Visit the "outer" template parameter lists on the TagDecl
723 // before visiting these template parameters.
724 if (VisitTemplateParameters(D->getTemplateParameters()))
725 return true;
726
727 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000728 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732 return true;
733
734 return VisitCXXRecordDecl(D);
735}
736
737bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738 // Visit the default argument.
739 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741 if (Visit(DefArg->getTypeLoc()))
742 return true;
743
744 return false;
745}
746
747bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748 if (Expr *Init = D->getInitExpr())
749 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750 return false;
751}
752
753bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000754 unsigned NumParamList = DD->getNumTemplateParameterLists();
755 for (unsigned i = 0; i < NumParamList; i++) {
756 TemplateParameterList* Params = DD->getTemplateParameterList(i);
757 if (VisitTemplateParameters(Params))
758 return true;
759 }
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762 if (Visit(TSInfo->getTypeLoc()))
763 return true;
764
765 // Visit the nested-name-specifier, if present.
766 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
768 return true;
769
770 return false;
771}
772
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000773/// \brief Compare two base or member initializers based on their source order.
774static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775 CXXCtorInitializer *const *Y) {
776 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777}
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 unsigned NumParamList = ND->getNumTemplateParameterLists();
781 for (unsigned i = 0; i < NumParamList; i++) {
782 TemplateParameterList* Params = ND->getTemplateParameterList(i);
783 if (VisitTemplateParameters(Params))
784 return true;
785 }
786
Guy Benyei11169dd2012-12-18 14:30:41 +0000787 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788 // Visit the function declaration's syntactic components in the order
789 // written. This requires a bit of work.
790 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000791 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000792
793 // If we have a function declared directly (without the use of a typedef),
794 // visit just the return type. Otherwise, just visit the function's type
795 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000796 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000797 (!FTL && Visit(TL)))
798 return true;
799
800 // Visit the nested-name-specifier, if present.
801 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
803 return true;
804
805 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000806 if (!isa<CXXDestructorDecl>(ND))
807 if (VisitDeclarationNameInfo(ND->getNameInfo()))
808 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000809
810 // FIXME: Visit explicitly-specified template arguments!
811
812 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000813 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 return true;
815
Bill Wendling44426052012-12-20 19:22:21 +0000816 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 }
818
819 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821 // Find the initializers that were written in the source.
822 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 for (auto *I : Constructor->inits()) {
824 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 continue;
826
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 }
829
830 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000831 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832 &CompareCXXCtorInitializers);
833
Guy Benyei11169dd2012-12-18 14:30:41 +0000834 // Visit the initializers in source order
835 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836 CXXCtorInitializer *Init = WrittenInits[I];
837 if (Init->isAnyMemberInitializer()) {
838 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839 Init->getMemberLocation(), TU)))
840 return true;
841 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842 if (Visit(TInfo->getTypeLoc()))
843 return true;
844 }
845
846 // Visit the initializer value.
847 if (Expr *Initializer = Init->getInit())
848 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849 return true;
850 }
851 }
852
853 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854 return true;
855 }
856
857 return false;
858}
859
860bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861 if (VisitDeclaratorDecl(D))
862 return true;
863
864 if (Expr *BitWidth = D->getBitWidth())
865 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871 if (VisitDeclaratorDecl(D))
872 return true;
873
874 if (Expr *Init = D->getInit())
875 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876
877 return false;
878}
879
880bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881 if (VisitDeclaratorDecl(D))
882 return true;
883
884 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885 if (Expr *DefArg = D->getDefaultArgument())
886 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887
888 return false;
889}
890
891bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitFunctionDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901 // FIXME: Visit the "outer" template parameter lists on the TagDecl
902 // before visiting these template parameters.
903 if (VisitTemplateParameters(D->getTemplateParameters()))
904 return true;
905
906 return VisitCXXRecordDecl(D->getTemplatedDecl());
907}
908
909bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914 VisitTemplateArgumentLoc(D->getDefaultArgument()))
915 return true;
916
917 return false;
918}
919
920bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000921 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000922 if (Visit(TSInfo->getTypeLoc()))
923 return true;
924
Aaron Ballman43b68be2014-03-07 17:50:17 +0000925 for (const auto *P : ND->params()) {
926 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000927 return true;
928 }
929
930 if (ND->isThisDeclarationADefinition() &&
931 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
932 return true;
933
934 return false;
935}
936
937template <typename DeclIt>
938static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
939 SourceManager &SM, SourceLocation EndLoc,
940 SmallVectorImpl<Decl *> &Decls) {
941 DeclIt next = *DI_current;
942 while (++next != DE_current) {
943 Decl *D_next = *next;
944 if (!D_next)
945 break;
946 SourceLocation L = D_next->getLocStart();
947 if (!L.isValid())
948 break;
949 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
950 *DI_current = next;
951 Decls.push_back(D_next);
952 continue;
953 }
954 break;
955 }
956}
957
Guy Benyei11169dd2012-12-18 14:30:41 +0000958bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
959 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
960 // an @implementation can lexically contain Decls that are not properly
961 // nested in the AST. When we identify such cases, we need to retrofit
962 // this nesting here.
963 if (!DI_current && !FileDI_current)
964 return VisitDeclContext(D);
965
966 // Scan the Decls that immediately come after the container
967 // in the current DeclContext. If any fall within the
968 // container's lexical region, stash them into a vector
969 // for later processing.
970 SmallVector<Decl *, 24> DeclsInContainer;
971 SourceLocation EndLoc = D->getSourceRange().getEnd();
972 SourceManager &SM = AU->getSourceManager();
973 if (EndLoc.isValid()) {
974 if (DI_current) {
975 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
976 DeclsInContainer);
977 } else {
978 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
979 DeclsInContainer);
980 }
981 }
982
983 // The common case.
984 if (DeclsInContainer.empty())
985 return VisitDeclContext(D);
986
987 // Get all the Decls in the DeclContext, and sort them with the
988 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 for (auto *SubDecl : D->decls()) {
990 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
991 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000992 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000993 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000994 }
995
996 // Now sort the Decls so that they appear in lexical order.
997 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000998 [&SM](Decl *A, Decl *B) {
999 SourceLocation L_A = A->getLocStart();
1000 SourceLocation L_B = B->getLocStart();
1001 assert(L_A.isValid() && L_B.isValid());
1002 return SM.isBeforeInTranslationUnit(L_A, L_B);
1003 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001004
1005 // Now visit the decls.
1006 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1007 E = DeclsInContainer.end(); I != E; ++I) {
1008 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001009 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001010 if (!V.hasValue())
1011 continue;
1012 if (!V.getValue())
1013 return false;
1014 if (Visit(Cursor, true))
1015 return true;
1016 }
1017 return false;
1018}
1019
1020bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1021 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1022 TU)))
1023 return true;
1024
1025 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1026 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1027 E = ND->protocol_end(); I != E; ++I, ++PL)
1028 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1029 return true;
1030
1031 return VisitObjCContainerDecl(ND);
1032}
1033
1034bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1035 if (!PID->isThisDeclarationADefinition())
1036 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1037
1038 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1039 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1040 E = PID->protocol_end(); I != E; ++I, ++PL)
1041 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042 return true;
1043
1044 return VisitObjCContainerDecl(PID);
1045}
1046
1047bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1048 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1049 return true;
1050
1051 // FIXME: This implements a workaround with @property declarations also being
1052 // installed in the DeclContext for the @interface. Eventually this code
1053 // should be removed.
1054 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1055 if (!CDecl || !CDecl->IsClassExtension())
1056 return false;
1057
1058 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1059 if (!ID)
1060 return false;
1061
1062 IdentifierInfo *PropertyId = PD->getIdentifier();
1063 ObjCPropertyDecl *prevDecl =
1064 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1065
1066 if (!prevDecl)
1067 return false;
1068
1069 // Visit synthesized methods since they will be skipped when visiting
1070 // the @interface.
1071 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1072 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1073 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1074 return true;
1075
1076 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1077 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1078 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1079 return true;
1080
1081 return false;
1082}
1083
1084bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1085 if (!D->isThisDeclarationADefinition()) {
1086 // Forward declaration is treated like a reference.
1087 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1088 }
1089
1090 // Issue callbacks for super class.
1091 if (D->getSuperClass() &&
1092 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1093 D->getSuperClassLoc(),
1094 TU)))
1095 return true;
1096
1097 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1098 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1099 E = D->protocol_end(); I != E; ++I, ++PL)
1100 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1101 return true;
1102
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1107 return VisitObjCContainerDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1111 // 'ID' could be null when dealing with invalid code.
1112 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1113 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1114 return true;
1115
1116 return VisitObjCImplDecl(D);
1117}
1118
1119bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1120#if 0
1121 // Issue callbacks for super class.
1122 // FIXME: No source location information!
1123 if (D->getSuperClass() &&
1124 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125 D->getSuperClassLoc(),
1126 TU)))
1127 return true;
1128#endif
1129
1130 return VisitObjCImplDecl(D);
1131}
1132
1133bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1134 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1135 if (PD->isIvarNameSpecified())
1136 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1137
1138 return false;
1139}
1140
1141bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1142 return VisitDeclContext(D);
1143}
1144
1145bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1146 // Visit nested-name-specifier.
1147 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1148 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149 return true;
1150
1151 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1152 D->getTargetNameLoc(), TU));
1153}
1154
1155bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1156 // Visit nested-name-specifier.
1157 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1158 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1159 return true;
1160 }
1161
1162 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1163 return true;
1164
1165 return VisitDeclarationNameInfo(D->getNameInfo());
1166}
1167
1168bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1169 // Visit nested-name-specifier.
1170 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172 return true;
1173
1174 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1175 D->getIdentLocation(), TU));
1176}
1177
1178bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1179 // Visit nested-name-specifier.
1180 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1181 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1182 return true;
1183 }
1184
1185 return VisitDeclarationNameInfo(D->getNameInfo());
1186}
1187
1188bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1189 UnresolvedUsingTypenameDecl *D) {
1190 // Visit nested-name-specifier.
1191 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1192 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1193 return true;
1194
1195 return false;
1196}
1197
1198bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1199 switch (Name.getName().getNameKind()) {
1200 case clang::DeclarationName::Identifier:
1201 case clang::DeclarationName::CXXLiteralOperatorName:
1202 case clang::DeclarationName::CXXOperatorName:
1203 case clang::DeclarationName::CXXUsingDirective:
1204 return false;
1205
1206 case clang::DeclarationName::CXXConstructorName:
1207 case clang::DeclarationName::CXXDestructorName:
1208 case clang::DeclarationName::CXXConversionFunctionName:
1209 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1210 return Visit(TSInfo->getTypeLoc());
1211 return false;
1212
1213 case clang::DeclarationName::ObjCZeroArgSelector:
1214 case clang::DeclarationName::ObjCOneArgSelector:
1215 case clang::DeclarationName::ObjCMultiArgSelector:
1216 // FIXME: Per-identifier location info?
1217 return false;
1218 }
1219
1220 llvm_unreachable("Invalid DeclarationName::Kind!");
1221}
1222
1223bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1224 SourceRange Range) {
1225 // FIXME: This whole routine is a hack to work around the lack of proper
1226 // source information in nested-name-specifiers (PR5791). Since we do have
1227 // a beginning source location, we can visit the first component of the
1228 // nested-name-specifier, if it's a single-token component.
1229 if (!NNS)
1230 return false;
1231
1232 // Get the first component in the nested-name-specifier.
1233 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1234 NNS = Prefix;
1235
1236 switch (NNS->getKind()) {
1237 case NestedNameSpecifier::Namespace:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1239 TU));
1240
1241 case NestedNameSpecifier::NamespaceAlias:
1242 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1243 Range.getBegin(), TU));
1244
1245 case NestedNameSpecifier::TypeSpec: {
1246 // If the type has a form where we know that the beginning of the source
1247 // range matches up with a reference cursor. Visit the appropriate reference
1248 // cursor.
1249 const Type *T = NNS->getAsType();
1250 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1251 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1252 if (const TagType *Tag = dyn_cast<TagType>(T))
1253 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1254 if (const TemplateSpecializationType *TST
1255 = dyn_cast<TemplateSpecializationType>(T))
1256 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1257 break;
1258 }
1259
1260 case NestedNameSpecifier::TypeSpecWithTemplate:
1261 case NestedNameSpecifier::Global:
1262 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001263 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001264 break;
1265 }
1266
1267 return false;
1268}
1269
1270bool
1271CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1272 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1273 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1274 Qualifiers.push_back(Qualifier);
1275
1276 while (!Qualifiers.empty()) {
1277 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1278 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1279 switch (NNS->getKind()) {
1280 case NestedNameSpecifier::Namespace:
1281 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1282 Q.getLocalBeginLoc(),
1283 TU)))
1284 return true;
1285
1286 break;
1287
1288 case NestedNameSpecifier::NamespaceAlias:
1289 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1290 Q.getLocalBeginLoc(),
1291 TU)))
1292 return true;
1293
1294 break;
1295
1296 case NestedNameSpecifier::TypeSpec:
1297 case NestedNameSpecifier::TypeSpecWithTemplate:
1298 if (Visit(Q.getTypeLoc()))
1299 return true;
1300
1301 break;
1302
1303 case NestedNameSpecifier::Global:
1304 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001305 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001306 break;
1307 }
1308 }
1309
1310 return false;
1311}
1312
1313bool CursorVisitor::VisitTemplateParameters(
1314 const TemplateParameterList *Params) {
1315 if (!Params)
1316 return false;
1317
1318 for (TemplateParameterList::const_iterator P = Params->begin(),
1319 PEnd = Params->end();
1320 P != PEnd; ++P) {
1321 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1322 return true;
1323 }
1324
1325 return false;
1326}
1327
1328bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1329 switch (Name.getKind()) {
1330 case TemplateName::Template:
1331 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1332
1333 case TemplateName::OverloadedTemplate:
1334 // Visit the overloaded template set.
1335 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1336 return true;
1337
1338 return false;
1339
1340 case TemplateName::DependentTemplate:
1341 // FIXME: Visit nested-name-specifier.
1342 return false;
1343
1344 case TemplateName::QualifiedTemplate:
1345 // FIXME: Visit nested-name-specifier.
1346 return Visit(MakeCursorTemplateRef(
1347 Name.getAsQualifiedTemplateName()->getDecl(),
1348 Loc, TU));
1349
1350 case TemplateName::SubstTemplateTemplateParm:
1351 return Visit(MakeCursorTemplateRef(
1352 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1353 Loc, TU));
1354
1355 case TemplateName::SubstTemplateTemplateParmPack:
1356 return Visit(MakeCursorTemplateRef(
1357 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1358 Loc, TU));
1359 }
1360
1361 llvm_unreachable("Invalid TemplateName::Kind!");
1362}
1363
1364bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1365 switch (TAL.getArgument().getKind()) {
1366 case TemplateArgument::Null:
1367 case TemplateArgument::Integral:
1368 case TemplateArgument::Pack:
1369 return false;
1370
1371 case TemplateArgument::Type:
1372 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1373 return Visit(TSInfo->getTypeLoc());
1374 return false;
1375
1376 case TemplateArgument::Declaration:
1377 if (Expr *E = TAL.getSourceDeclExpression())
1378 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379 return false;
1380
1381 case TemplateArgument::NullPtr:
1382 if (Expr *E = TAL.getSourceNullPtrExpression())
1383 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1384 return false;
1385
1386 case TemplateArgument::Expression:
1387 if (Expr *E = TAL.getSourceExpression())
1388 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1389 return false;
1390
1391 case TemplateArgument::Template:
1392 case TemplateArgument::TemplateExpansion:
1393 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1394 return true;
1395
1396 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1397 TAL.getTemplateNameLoc());
1398 }
1399
1400 llvm_unreachable("Invalid TemplateArgument::Kind!");
1401}
1402
1403bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1404 return VisitDeclContext(D);
1405}
1406
1407bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1408 return Visit(TL.getUnqualifiedLoc());
1409}
1410
1411bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1412 ASTContext &Context = AU->getASTContext();
1413
1414 // Some builtin types (such as Objective-C's "id", "sel", and
1415 // "Class") have associated declarations. Create cursors for those.
1416 QualType VisitType;
1417 switch (TL.getTypePtr()->getKind()) {
1418
1419 case BuiltinType::Void:
1420 case BuiltinType::NullPtr:
1421 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001422 case BuiltinType::OCLImage1d:
1423 case BuiltinType::OCLImage1dArray:
1424 case BuiltinType::OCLImage1dBuffer:
1425 case BuiltinType::OCLImage2d:
1426 case BuiltinType::OCLImage2dArray:
1427 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001428 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001429 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001430#define BUILTIN_TYPE(Id, SingletonId)
1431#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1434#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1435#include "clang/AST/BuiltinTypes.def"
1436 break;
1437
1438 case BuiltinType::ObjCId:
1439 VisitType = Context.getObjCIdType();
1440 break;
1441
1442 case BuiltinType::ObjCClass:
1443 VisitType = Context.getObjCClassType();
1444 break;
1445
1446 case BuiltinType::ObjCSel:
1447 VisitType = Context.getObjCSelType();
1448 break;
1449 }
1450
1451 if (!VisitType.isNull()) {
1452 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1453 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1454 TU));
1455 }
1456
1457 return false;
1458}
1459
1460bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1461 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1465 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1466}
1467
1468bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1469 if (TL.isDefinition())
1470 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1471
1472 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1473}
1474
1475bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1476 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1477}
1478
1479bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1480 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1481 return true;
1482
1483 return false;
1484}
1485
1486bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1487 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1488 return true;
1489
1490 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1491 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1492 TU)))
1493 return true;
1494 }
1495
1496 return false;
1497}
1498
1499bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1500 return Visit(TL.getPointeeLoc());
1501}
1502
1503bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1504 return Visit(TL.getInnerLoc());
1505}
1506
1507bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1520 return Visit(TL.getPointeeLoc());
1521}
1522
1523bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1524 return Visit(TL.getPointeeLoc());
1525}
1526
1527bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1528 return Visit(TL.getModifiedLoc());
1529}
1530
1531bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1532 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001533 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001534 return true;
1535
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001536 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1537 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001538 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1539 return true;
1540
1541 return false;
1542}
1543
1544bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1545 if (Visit(TL.getElementLoc()))
1546 return true;
1547
1548 if (Expr *Size = TL.getSizeExpr())
1549 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1550
1551 return false;
1552}
1553
Reid Kleckner8a365022013-06-24 17:51:48 +00001554bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1555 return Visit(TL.getOriginalLoc());
1556}
1557
Reid Kleckner0503a872013-12-05 01:23:43 +00001558bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1559 return Visit(TL.getOriginalLoc());
1560}
1561
Guy Benyei11169dd2012-12-18 14:30:41 +00001562bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1563 TemplateSpecializationTypeLoc TL) {
1564 // Visit the template name.
1565 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1566 TL.getTemplateNameLoc()))
1567 return true;
1568
1569 // Visit the template arguments.
1570 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1571 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1572 return true;
1573
1574 return false;
1575}
1576
1577bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1578 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1579}
1580
1581bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1582 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1583 return Visit(TSInfo->getTypeLoc());
1584
1585 return false;
1586}
1587
1588bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1589 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1590 return Visit(TSInfo->getTypeLoc());
1591
1592 return false;
1593}
1594
1595bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1596 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1597 return true;
1598
1599 return false;
1600}
1601
1602bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1603 DependentTemplateSpecializationTypeLoc TL) {
1604 // Visit the nested-name-specifier, if there is one.
1605 if (TL.getQualifierLoc() &&
1606 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1607 return true;
1608
1609 // Visit the template arguments.
1610 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1611 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1612 return true;
1613
1614 return false;
1615}
1616
1617bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1618 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1619 return true;
1620
1621 return Visit(TL.getNamedTypeLoc());
1622}
1623
1624bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1625 return Visit(TL.getPatternLoc());
1626}
1627
1628bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1629 if (Expr *E = TL.getUnderlyingExpr())
1630 return Visit(MakeCXCursor(E, StmtParent, TU));
1631
1632 return false;
1633}
1634
1635bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1636 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1637}
1638
1639bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1640 return Visit(TL.getValueLoc());
1641}
1642
1643#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1644bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1645 return Visit##PARENT##Loc(TL); \
1646}
1647
1648DEFAULT_TYPELOC_IMPL(Complex, Type)
1649DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1652DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1653DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1654DEFAULT_TYPELOC_IMPL(Vector, Type)
1655DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1656DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1657DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1658DEFAULT_TYPELOC_IMPL(Record, TagType)
1659DEFAULT_TYPELOC_IMPL(Enum, TagType)
1660DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1661DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1662DEFAULT_TYPELOC_IMPL(Auto, Type)
1663
1664bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1665 // Visit the nested-name-specifier, if present.
1666 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1667 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1668 return true;
1669
1670 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001671 for (const auto &I : D->bases()) {
1672 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001673 return true;
1674 }
1675 }
1676
1677 return VisitTagDecl(D);
1678}
1679
1680bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001681 for (const auto *I : D->attrs())
1682 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001683 return true;
1684
1685 return false;
1686}
1687
1688//===----------------------------------------------------------------------===//
1689// Data-recursive visitor methods.
1690//===----------------------------------------------------------------------===//
1691
1692namespace {
1693#define DEF_JOB(NAME, DATA, KIND)\
1694class NAME : public VisitorJob {\
1695public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001696 NAME(const DATA *d, CXCursor parent) : \
1697 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001698 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001699 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001700};
1701
1702DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1703DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1704DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1705DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1706DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1707 ExplicitTemplateArgsVisitKind)
1708DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1709DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1710DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1711#undef DEF_JOB
1712
1713class DeclVisit : public VisitorJob {
1714public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001717 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001718 static bool classof(const VisitorJob *VJ) {
1719 return VJ->getKind() == DeclVisitKind;
1720 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001721 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001722 bool isFirst() const { return data[1] ? true : false; }
1723};
1724class TypeLocVisit : public VisitorJob {
1725public:
1726 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1727 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1728 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1729
1730 static bool classof(const VisitorJob *VJ) {
1731 return VJ->getKind() == TypeLocVisitKind;
1732 }
1733
1734 TypeLoc get() const {
1735 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001736 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001737 }
1738};
1739
1740class LabelRefVisit : public VisitorJob {
1741public:
1742 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1743 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1744 labelLoc.getPtrEncoding()) {}
1745
1746 static bool classof(const VisitorJob *VJ) {
1747 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1748 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001749 const LabelDecl *get() const {
1750 return static_cast<const LabelDecl *>(data[0]);
1751 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001752 SourceLocation getLoc() const {
1753 return SourceLocation::getFromPtrEncoding(data[1]); }
1754};
1755
1756class NestedNameSpecifierLocVisit : public VisitorJob {
1757public:
1758 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1759 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1760 Qualifier.getNestedNameSpecifier(),
1761 Qualifier.getOpaqueData()) { }
1762
1763 static bool classof(const VisitorJob *VJ) {
1764 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1765 }
1766
1767 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001768 return NestedNameSpecifierLoc(
1769 const_cast<NestedNameSpecifier *>(
1770 static_cast<const NestedNameSpecifier *>(data[0])),
1771 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001772 }
1773};
1774
1775class DeclarationNameInfoVisit : public VisitorJob {
1776public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001778 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001779 static bool classof(const VisitorJob *VJ) {
1780 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1781 }
1782 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001783 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001784 switch (S->getStmtClass()) {
1785 default:
1786 llvm_unreachable("Unhandled Stmt");
1787 case clang::Stmt::MSDependentExistsStmtClass:
1788 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1789 case Stmt::CXXDependentScopeMemberExprClass:
1790 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1791 case Stmt::DependentScopeDeclRefExprClass:
1792 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001793 case Stmt::OMPCriticalDirectiveClass:
1794 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 }
1796 }
1797};
1798class MemberRefVisit : public VisitorJob {
1799public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001801 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1802 L.getPtrEncoding()) {}
1803 static bool classof(const VisitorJob *VJ) {
1804 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1805 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001806 const FieldDecl *get() const {
1807 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001808 }
1809 SourceLocation getLoc() const {
1810 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1811 }
1812};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001814 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001815 VisitorWorkList &WL;
1816 CXCursor Parent;
1817public:
1818 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1819 : WL(wl), Parent(parent) {}
1820
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001821 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1822 void VisitBlockExpr(const BlockExpr *B);
1823 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1824 void VisitCompoundStmt(const CompoundStmt *S);
1825 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1826 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1827 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1828 void VisitCXXNewExpr(const CXXNewExpr *E);
1829 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1830 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1831 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1832 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1833 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1834 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1835 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1836 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1837 void VisitDeclRefExpr(const DeclRefExpr *D);
1838 void VisitDeclStmt(const DeclStmt *S);
1839 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1840 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1841 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1842 void VisitForStmt(const ForStmt *FS);
1843 void VisitGotoStmt(const GotoStmt *GS);
1844 void VisitIfStmt(const IfStmt *If);
1845 void VisitInitListExpr(const InitListExpr *IE);
1846 void VisitMemberExpr(const MemberExpr *M);
1847 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1848 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1849 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1850 void VisitOverloadExpr(const OverloadExpr *E);
1851 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1852 void VisitStmt(const Stmt *S);
1853 void VisitSwitchStmt(const SwitchStmt *S);
1854 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1856 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1857 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1858 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1859 void VisitVAArgExpr(const VAArgExpr *E);
1860 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1861 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1862 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1863 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001865 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001866 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001867 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001868 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001869 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001870 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001871 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001872 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001873 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001874 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001875 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001876 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001877 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001878 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001879 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001880 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001881 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001882 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001883 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001884 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001885 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001886
Guy Benyei11169dd2012-12-18 14:30:41 +00001887private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001889 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1890 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1892 void AddStmt(const Stmt *S);
1893 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001894 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001895 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001896 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001897};
1898} // end anonyous namespace
1899
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 // 'S' should always be non-null, since it comes from the
1902 // statement we are visiting.
1903 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1904}
1905
1906void
1907EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1908 if (Qualifier)
1909 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1910}
1911
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001912void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001913 if (S)
1914 WL.push_back(StmtVisit(S, Parent));
1915}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001916void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001917 if (D)
1918 WL.push_back(DeclVisit(D, Parent, isFirst));
1919}
1920void EnqueueVisitor::
1921 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1922 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001923 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001924}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001925void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001926 if (D)
1927 WL.push_back(MemberRefVisit(D, L, Parent));
1928}
1929void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1930 if (TI)
1931 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1932 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001933void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001934 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001935 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001936 AddStmt(*Child);
1937 }
1938 if (size == WL.size())
1939 return;
1940 // Now reverse the entries we just added. This will match the DFS
1941 // ordering performed by the worklist.
1942 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1943 std::reverse(I, E);
1944}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945namespace {
1946class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1947 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001948 /// \brief Process clauses with list of variables.
1949 template <typename T>
1950 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001951public:
1952 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1953#define OPENMP_CLAUSE(Name, Class) \
1954 void Visit##Class(const Class *C);
1955#include "clang/Basic/OpenMPKinds.def"
1956};
1957
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001958void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1959 Visitor->AddStmt(C->getCondition());
1960}
1961
Alexey Bataev3778b602014-07-17 07:32:53 +00001962void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1963 Visitor->AddStmt(C->getCondition());
1964}
1965
Alexey Bataev568a8332014-03-06 06:15:19 +00001966void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1967 Visitor->AddStmt(C->getNumThreads());
1968}
1969
Alexey Bataev62c87d22014-03-21 04:51:18 +00001970void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1971 Visitor->AddStmt(C->getSafelen());
1972}
1973
Alexander Musman8bd31e62014-05-27 15:12:19 +00001974void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1975 Visitor->AddStmt(C->getNumForLoops());
1976}
1977
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001978void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001979
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001980void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1981
Alexey Bataev56dafe82014-06-20 07:16:17 +00001982void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1983 Visitor->AddStmt(C->getChunkSize());
1984}
1985
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001986void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1987
Alexey Bataev236070f2014-06-20 11:19:47 +00001988void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1989
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001990void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1991
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001992void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1993
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001994void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1995
Alexey Bataevdea47612014-07-23 07:46:59 +00001996void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1997
Alexey Bataev67a4f222014-07-23 10:25:33 +00001998void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
1999
Alexey Bataev459dec02014-07-24 06:46:57 +00002000void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2001
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002002void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2003
Alexey Bataev756c1962013-09-24 03:17:45 +00002004template<typename T>
2005void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002006 for (const auto *I : Node->varlists())
2007 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00002008}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002009
2010void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002011 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002012}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002013void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2014 const OMPFirstprivateClause *C) {
2015 VisitOMPClauseList(C);
2016}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002017void OMPClauseEnqueue::VisitOMPLastprivateClause(
2018 const OMPLastprivateClause *C) {
2019 VisitOMPClauseList(C);
2020}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002021void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002022 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002023}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002024void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2025 VisitOMPClauseList(C);
2026}
Alexander Musman8dba6642014-04-22 13:09:42 +00002027void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2028 VisitOMPClauseList(C);
2029 Visitor->AddStmt(C->getStep());
2030}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002031void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2032 VisitOMPClauseList(C);
2033 Visitor->AddStmt(C->getAlignment());
2034}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002035void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2036 VisitOMPClauseList(C);
2037}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002038void
2039OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2040 VisitOMPClauseList(C);
2041}
Alexey Bataev6125da92014-07-21 11:26:11 +00002042void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2043 VisitOMPClauseList(C);
2044}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002045}
Alexey Bataev756c1962013-09-24 03:17:45 +00002046
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002047void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2048 unsigned size = WL.size();
2049 OMPClauseEnqueue Visitor(this);
2050 Visitor.Visit(S);
2051 if (size == WL.size())
2052 return;
2053 // Now reverse the entries we just added. This will match the DFS
2054 // ordering performed by the worklist.
2055 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2056 std::reverse(I, E);
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002059 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2060}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002061void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002062 AddDecl(B->getBlockDecl());
2063}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002065 EnqueueChildren(E);
2066 AddTypeLoc(E->getTypeSourceInfo());
2067}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2069 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 E = S->body_rend(); I != E; ++I) {
2071 AddStmt(*I);
2072 }
2073}
2074void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002075VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002076 AddStmt(S->getSubStmt());
2077 AddDeclarationNameInfo(S);
2078 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2079 AddNestedNameSpecifierLoc(QualifierLoc);
2080}
2081
2082void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002083VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002084 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2085 AddDeclarationNameInfo(E);
2086 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2087 AddNestedNameSpecifierLoc(QualifierLoc);
2088 if (!E->isImplicitAccess())
2089 AddStmt(E->getBase());
2090}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002091void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002092 // Enqueue the initializer , if any.
2093 AddStmt(E->getInitializer());
2094 // Enqueue the array size, if any.
2095 AddStmt(E->getArraySize());
2096 // Enqueue the allocated type.
2097 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2098 // Enqueue the placement arguments.
2099 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2100 AddStmt(E->getPlacementArg(I-1));
2101}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002103 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2104 AddStmt(CE->getArg(I-1));
2105 AddStmt(CE->getCallee());
2106 AddStmt(CE->getArg(0));
2107}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2109 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002110 // Visit the name of the type being destroyed.
2111 AddTypeLoc(E->getDestroyedTypeInfo());
2112 // Visit the scope type that looks disturbingly like the nested-name-specifier
2113 // but isn't.
2114 AddTypeLoc(E->getScopeTypeInfo());
2115 // Visit the nested-name-specifier.
2116 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2117 AddNestedNameSpecifierLoc(QualifierLoc);
2118 // Visit base expression.
2119 AddStmt(E->getBase());
2120}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2122 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 AddTypeLoc(E->getTypeSourceInfo());
2124}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2126 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 EnqueueChildren(E);
2128 AddTypeLoc(E->getTypeSourceInfo());
2129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 EnqueueChildren(E);
2132 if (E->isTypeOperand())
2133 AddTypeLoc(E->getTypeOperandSourceInfo());
2134}
2135
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2137 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 EnqueueChildren(E);
2139 AddTypeLoc(E->getTypeSourceInfo());
2140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 EnqueueChildren(E);
2143 if (E->isTypeOperand())
2144 AddTypeLoc(E->getTypeOperandSourceInfo());
2145}
2146
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 EnqueueChildren(S);
2149 AddDecl(S->getExceptionDecl());
2150}
2151
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 if (DR->hasExplicitTemplateArgs()) {
2154 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2155 }
2156 WL.push_back(DeclRefExprParts(DR, Parent));
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2159 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002160 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2161 AddDeclarationNameInfo(E);
2162 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2163}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 unsigned size = WL.size();
2166 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002167 for (const auto *D : S->decls()) {
2168 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 isFirst = false;
2170 }
2171 if (size == WL.size())
2172 return;
2173 // Now reverse the entries we just added. This will match the DFS
2174 // ordering performed by the worklist.
2175 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2176 std::reverse(I, E);
2177}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 D = E->designators_rbegin(), DEnd = E->designators_rend();
2182 D != DEnd; ++D) {
2183 if (D->isFieldDesignator()) {
2184 if (FieldDecl *Field = D->getField())
2185 AddMemberRef(Field, D->getFieldLoc());
2186 continue;
2187 }
2188 if (D->isArrayDesignator()) {
2189 AddStmt(E->getArrayIndex(*D));
2190 continue;
2191 }
2192 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2193 AddStmt(E->getArrayRangeEnd(*D));
2194 AddStmt(E->getArrayRangeStart(*D));
2195 }
2196}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 EnqueueChildren(E);
2199 AddTypeLoc(E->getTypeInfoAsWritten());
2200}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002201void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002202 AddStmt(FS->getBody());
2203 AddStmt(FS->getInc());
2204 AddStmt(FS->getCond());
2205 AddDecl(FS->getConditionVariable());
2206 AddStmt(FS->getInit());
2207}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 AddStmt(If->getElse());
2213 AddStmt(If->getThen());
2214 AddStmt(If->getCond());
2215 AddDecl(If->getConditionVariable());
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 // We care about the syntactic form of the initializer list, only.
2219 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2220 IE = Syntactic;
2221 EnqueueChildren(IE);
2222}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002223void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002224 WL.push_back(MemberExprParts(M, Parent));
2225
2226 // If the base of the member access expression is an implicit 'this', don't
2227 // visit it.
2228 // FIXME: If we ever want to show these implicit accesses, this will be
2229 // unfortunate. However, clang_getCursor() relies on this behavior.
2230 if (!M->isImplicitAccess())
2231 AddStmt(M->getBase());
2232}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002233void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002234 AddTypeLoc(E->getEncodedTypeSourceInfo());
2235}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 EnqueueChildren(M);
2238 AddTypeLoc(M->getClassReceiverTypeInfo());
2239}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002240void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 // Visit the components of the offsetof expression.
2242 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2243 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2244 const OffsetOfNode &Node = E->getComponent(I-1);
2245 switch (Node.getKind()) {
2246 case OffsetOfNode::Array:
2247 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2248 break;
2249 case OffsetOfNode::Field:
2250 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2251 break;
2252 case OffsetOfNode::Identifier:
2253 case OffsetOfNode::Base:
2254 continue;
2255 }
2256 }
2257 // Visit the type into which we're computing the offset.
2258 AddTypeLoc(E->getTypeSourceInfo());
2259}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2262 WL.push_back(OverloadExprParts(E, Parent));
2263}
2264void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 EnqueueChildren(E);
2267 if (E->isArgumentType())
2268 AddTypeLoc(E->getArgumentTypeInfo());
2269}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 EnqueueChildren(S);
2272}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 AddStmt(S->getBody());
2275 AddStmt(S->getCond());
2276 AddDecl(S->getConditionVariable());
2277}
2278
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 AddStmt(W->getBody());
2281 AddStmt(W->getCond());
2282 AddDecl(W->getConditionVariable());
2283}
2284
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 for (unsigned I = E->getNumArgs(); I > 0; --I)
2287 AddTypeLoc(E->getArg(I-1));
2288}
2289
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 AddTypeLoc(E->getQueriedTypeSourceInfo());
2292}
2293
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 EnqueueChildren(E);
2296}
2297
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 VisitOverloadExpr(U);
2300 if (!U->isImplicitAccess())
2301 AddStmt(U->getBase());
2302}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002303void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002304 AddStmt(E->getSubExpr());
2305 AddTypeLoc(E->getWrittenTypeInfo());
2306}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002307void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002308 WL.push_back(SizeOfPackExprParts(E, Parent));
2309}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 // If the opaque value has a source expression, just transparently
2312 // visit that. This is useful for (e.g.) pseudo-object expressions.
2313 if (Expr *SourceExpr = E->getSourceExpr())
2314 return Visit(SourceExpr);
2315}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002316void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002317 AddStmt(E->getBody());
2318 WL.push_back(LambdaExprParts(E, Parent));
2319}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002320void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002321 // Treat the expression like its syntactic form.
2322 Visit(E->getSyntacticForm());
2323}
2324
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002325void EnqueueVisitor::VisitOMPExecutableDirective(
2326 const OMPExecutableDirective *D) {
2327 EnqueueChildren(D);
2328 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2329 E = D->clauses().end();
2330 I != E; ++I)
2331 EnqueueChildren(*I);
2332}
2333
Alexander Musman3aaab662014-08-19 11:27:13 +00002334void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2335 VisitOMPExecutableDirective(D);
2336}
2337
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002338void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2339 VisitOMPExecutableDirective(D);
2340}
2341
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002342void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002343 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002344}
2345
Alexey Bataevf29276e2014-06-18 04:14:57 +00002346void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002347 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002348}
2349
Alexander Musmanf82886e2014-09-18 05:12:34 +00002350void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2351 VisitOMPLoopDirective(D);
2352}
2353
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002354void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2355 VisitOMPExecutableDirective(D);
2356}
2357
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002358void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2359 VisitOMPExecutableDirective(D);
2360}
2361
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002362void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2363 VisitOMPExecutableDirective(D);
2364}
2365
Alexander Musman80c22892014-07-17 08:54:58 +00002366void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2367 VisitOMPExecutableDirective(D);
2368}
2369
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002370void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2371 VisitOMPExecutableDirective(D);
2372 AddDeclarationNameInfo(D);
2373}
2374
Alexey Bataev4acb8592014-07-07 13:01:15 +00002375void
2376EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002377 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002378}
2379
Alexander Musmane4e893b2014-09-23 09:33:00 +00002380void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2381 const OMPParallelForSimdDirective *D) {
2382 VisitOMPLoopDirective(D);
2383}
2384
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002385void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2386 const OMPParallelSectionsDirective *D) {
2387 VisitOMPExecutableDirective(D);
2388}
2389
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002390void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2391 VisitOMPExecutableDirective(D);
2392}
2393
Alexey Bataev68446b72014-07-18 07:47:19 +00002394void
2395EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2396 VisitOMPExecutableDirective(D);
2397}
2398
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002399void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2400 VisitOMPExecutableDirective(D);
2401}
2402
Alexey Bataev2df347a2014-07-18 10:17:07 +00002403void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2404 VisitOMPExecutableDirective(D);
2405}
2406
Alexey Bataev6125da92014-07-21 11:26:11 +00002407void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2408 VisitOMPExecutableDirective(D);
2409}
2410
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002411void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2412 VisitOMPExecutableDirective(D);
2413}
2414
Alexey Bataev0162e452014-07-22 10:10:35 +00002415void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2416 VisitOMPExecutableDirective(D);
2417}
2418
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002419void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2420 VisitOMPExecutableDirective(D);
2421}
2422
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002423void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002424 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2425}
2426
2427bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2428 if (RegionOfInterest.isValid()) {
2429 SourceRange Range = getRawCursorExtent(C);
2430 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2431 return false;
2432 }
2433 return true;
2434}
2435
2436bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2437 while (!WL.empty()) {
2438 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002439 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002440
2441 // Set the Parent field, then back to its old value once we're done.
2442 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2443
2444 switch (LI.getKind()) {
2445 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002446 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 if (!D)
2448 continue;
2449
2450 // For now, perform default visitation for Decls.
2451 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2452 cast<DeclVisit>(&LI)->isFirst())))
2453 return true;
2454
2455 continue;
2456 }
2457 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2458 const ASTTemplateArgumentListInfo *ArgList =
2459 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2460 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2461 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2462 Arg != ArgEnd; ++Arg) {
2463 if (VisitTemplateArgumentLoc(*Arg))
2464 return true;
2465 }
2466 continue;
2467 }
2468 case VisitorJob::TypeLocVisitKind: {
2469 // Perform default visitation for TypeLocs.
2470 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2471 return true;
2472 continue;
2473 }
2474 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002475 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002476 if (LabelStmt *stmt = LS->getStmt()) {
2477 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2478 TU))) {
2479 return true;
2480 }
2481 }
2482 continue;
2483 }
2484
2485 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2486 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2487 if (VisitNestedNameSpecifierLoc(V->get()))
2488 return true;
2489 continue;
2490 }
2491
2492 case VisitorJob::DeclarationNameInfoVisitKind: {
2493 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2494 ->get()))
2495 return true;
2496 continue;
2497 }
2498 case VisitorJob::MemberRefVisitKind: {
2499 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2500 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2501 return true;
2502 continue;
2503 }
2504 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002505 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002506 if (!S)
2507 continue;
2508
2509 // Update the current cursor.
2510 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2511 if (!IsInRegionOfInterest(Cursor))
2512 continue;
2513 switch (Visitor(Cursor, Parent, ClientData)) {
2514 case CXChildVisit_Break: return true;
2515 case CXChildVisit_Continue: break;
2516 case CXChildVisit_Recurse:
2517 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002518 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002519 EnqueueWorkList(WL, S);
2520 break;
2521 }
2522 continue;
2523 }
2524 case VisitorJob::MemberExprPartsKind: {
2525 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002526 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002527
2528 // Visit the nested-name-specifier
2529 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2530 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2531 return true;
2532
2533 // Visit the declaration name.
2534 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2535 return true;
2536
2537 // Visit the explicitly-specified template arguments, if any.
2538 if (M->hasExplicitTemplateArgs()) {
2539 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2540 *ArgEnd = Arg + M->getNumTemplateArgs();
2541 Arg != ArgEnd; ++Arg) {
2542 if (VisitTemplateArgumentLoc(*Arg))
2543 return true;
2544 }
2545 }
2546 continue;
2547 }
2548 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002549 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002550 // Visit nested-name-specifier, if present.
2551 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2552 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2553 return true;
2554 // Visit declaration name.
2555 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2556 return true;
2557 continue;
2558 }
2559 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002560 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002561 // Visit the nested-name-specifier.
2562 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2563 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2564 return true;
2565 // Visit the declaration name.
2566 if (VisitDeclarationNameInfo(O->getNameInfo()))
2567 return true;
2568 // Visit the overloaded declaration reference.
2569 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2570 return true;
2571 continue;
2572 }
2573 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002574 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002575 NamedDecl *Pack = E->getPack();
2576 if (isa<TemplateTypeParmDecl>(Pack)) {
2577 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2578 E->getPackLoc(), TU)))
2579 return true;
2580
2581 continue;
2582 }
2583
2584 if (isa<TemplateTemplateParmDecl>(Pack)) {
2585 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2586 E->getPackLoc(), TU)))
2587 return true;
2588
2589 continue;
2590 }
2591
2592 // Non-type template parameter packs and function parameter packs are
2593 // treated like DeclRefExpr cursors.
2594 continue;
2595 }
2596
2597 case VisitorJob::LambdaExprPartsKind: {
2598 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002599 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002600 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2601 CEnd = E->explicit_capture_end();
2602 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002603 // FIXME: Lambda init-captures.
2604 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002605 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002606
Guy Benyei11169dd2012-12-18 14:30:41 +00002607 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2608 C->getLocation(),
2609 TU)))
2610 return true;
2611 }
2612
2613 // Visit parameters and return type, if present.
2614 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2615 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2616 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2617 // Visit the whole type.
2618 if (Visit(TL))
2619 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002620 } else if (FunctionProtoTypeLoc Proto =
2621 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002622 if (E->hasExplicitParameters()) {
2623 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002624 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2625 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002626 return true;
2627 } else {
2628 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002629 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002630 return true;
2631 }
2632 }
2633 }
2634 break;
2635 }
2636
2637 case VisitorJob::PostChildrenVisitKind:
2638 if (PostChildrenVisitor(Parent, ClientData))
2639 return true;
2640 break;
2641 }
2642 }
2643 return false;
2644}
2645
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002646bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002647 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002648 if (!WorkListFreeList.empty()) {
2649 WL = WorkListFreeList.back();
2650 WL->clear();
2651 WorkListFreeList.pop_back();
2652 }
2653 else {
2654 WL = new VisitorWorkList();
2655 WorkListCache.push_back(WL);
2656 }
2657 EnqueueWorkList(*WL, S);
2658 bool result = RunVisitorWorkList(*WL);
2659 WorkListFreeList.push_back(WL);
2660 return result;
2661}
2662
2663namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002664typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002665RefNamePieces
2666buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2667 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2668 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002669 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2670 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2671 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2672
2673 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2674
2675 RefNamePieces Pieces;
2676
2677 if (WantQualifier && QLoc.isValid())
2678 Pieces.push_back(QLoc);
2679
2680 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2681 Pieces.push_back(NI.getLoc());
2682
2683 if (WantTemplateArgs && TemplateArgs)
2684 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2685 TemplateArgs->RAngleLoc));
2686
2687 if (Kind == DeclarationName::CXXOperatorName) {
2688 Pieces.push_back(SourceLocation::getFromRawEncoding(
2689 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2690 Pieces.push_back(SourceLocation::getFromRawEncoding(
2691 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2692 }
2693
2694 if (WantSinglePiece) {
2695 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2696 Pieces.clear();
2697 Pieces.push_back(R);
2698 }
2699
2700 return Pieces;
2701}
2702}
2703
2704//===----------------------------------------------------------------------===//
2705// Misc. API hooks.
2706//===----------------------------------------------------------------------===//
2707
Chad Rosier05c71aa2013-03-27 18:28:23 +00002708static void fatal_error_handler(void *user_data, const std::string& reason,
2709 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002710 // Write the result out to stderr avoiding errs() because raw_ostreams can
2711 // call report_fatal_error.
2712 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2713 ::abort();
2714}
2715
Chandler Carruth66660742014-06-27 16:37:27 +00002716namespace {
2717struct RegisterFatalErrorHandler {
2718 RegisterFatalErrorHandler() {
2719 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2720 }
2721};
2722}
2723
2724static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2725
Guy Benyei11169dd2012-12-18 14:30:41 +00002726extern "C" {
2727CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2728 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002729 // We use crash recovery to make some of our APIs more reliable, implicitly
2730 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002731 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2732 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002733
Chandler Carruth66660742014-06-27 16:37:27 +00002734 // Look through the managed static to trigger construction of the managed
2735 // static which registers our fatal error handler. This ensures it is only
2736 // registered once.
2737 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002738
2739 CIndexer *CIdxr = new CIndexer();
2740 if (excludeDeclarationsFromPCH)
2741 CIdxr->setOnlyLocalDecls();
2742 if (displayDiagnostics)
2743 CIdxr->setDisplayDiagnostics();
2744
2745 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2746 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2747 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2748 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2749 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2750 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2751
2752 return CIdxr;
2753}
2754
2755void clang_disposeIndex(CXIndex CIdx) {
2756 if (CIdx)
2757 delete static_cast<CIndexer *>(CIdx);
2758}
2759
2760void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2761 if (CIdx)
2762 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2763}
2764
2765unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2766 if (CIdx)
2767 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2768 return 0;
2769}
2770
2771void clang_toggleCrashRecovery(unsigned isEnabled) {
2772 if (isEnabled)
2773 llvm::CrashRecoveryContext::Enable();
2774 else
2775 llvm::CrashRecoveryContext::Disable();
2776}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002777
Guy Benyei11169dd2012-12-18 14:30:41 +00002778CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2779 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002780 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002781 enum CXErrorCode Result =
2782 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002783 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002784 assert((TU && Result == CXError_Success) ||
2785 (!TU && Result != CXError_Success));
2786 return TU;
2787}
2788
2789enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2790 const char *ast_filename,
2791 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002792 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002793 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002794
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002795 if (!CIdx || !ast_filename || !out_TU)
2796 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002797
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002798 LOG_FUNC_SECTION {
2799 *Log << ast_filename;
2800 }
2801
Guy Benyei11169dd2012-12-18 14:30:41 +00002802 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2803 FileSystemOptions FileSystemOpts;
2804
2805 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
David Blaikie6f7382d2014-08-10 19:08:04 +00002806 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2807 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2808 /*CaptureDiagnostics=*/true,
2809 /*AllowPCHWithCompilerErrors=*/true,
2810 /*UserFilesAreVolatile=*/true);
2811 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002812 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002813}
2814
2815unsigned clang_defaultEditingTranslationUnitOptions() {
2816 return CXTranslationUnit_PrecompiledPreamble |
2817 CXTranslationUnit_CacheCompletionResults;
2818}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002819
Guy Benyei11169dd2012-12-18 14:30:41 +00002820CXTranslationUnit
2821clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2822 const char *source_filename,
2823 int num_command_line_args,
2824 const char * const *command_line_args,
2825 unsigned num_unsaved_files,
2826 struct CXUnsavedFile *unsaved_files) {
2827 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2828 return clang_parseTranslationUnit(CIdx, source_filename,
2829 command_line_args, num_command_line_args,
2830 unsaved_files, num_unsaved_files,
2831 Options);
2832}
2833
2834struct ParseTranslationUnitInfo {
2835 CXIndex CIdx;
2836 const char *source_filename;
2837 const char *const *command_line_args;
2838 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002839 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002840 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002841 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002842 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002843};
2844static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002845 const ParseTranslationUnitInfo *PTUI =
2846 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002847 CXIndex CIdx = PTUI->CIdx;
2848 const char *source_filename = PTUI->source_filename;
2849 const char * const *command_line_args = PTUI->command_line_args;
2850 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002851 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002852 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002853
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002854 // Set up the initial return values.
2855 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002856 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002857
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002858 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002859 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002860 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002861 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002862 }
2863
Guy Benyei11169dd2012-12-18 14:30:41 +00002864 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2865
2866 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2867 setThreadBackgroundPriority();
2868
2869 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2870 // FIXME: Add a flag for modules.
2871 TranslationUnitKind TUKind
2872 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002873 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002874 = options & CXTranslationUnit_CacheCompletionResults;
2875 bool IncludeBriefCommentsInCodeCompletion
2876 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2877 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2878 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2879
2880 // Configure the diagnostics.
2881 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002882 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002883
2884 // Recover resources if we crash before exiting this function.
2885 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2886 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002887 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002888
Ahmed Charlesb8984322014-03-07 20:03:18 +00002889 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2890 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002891
2892 // Recover resources if we crash before exiting this function.
2893 llvm::CrashRecoveryContextCleanupRegistrar<
2894 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2895
Alp Toker9d85b182014-07-07 01:23:14 +00002896 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002897 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002898 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002899 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002900 }
2901
Ahmed Charlesb8984322014-03-07 20:03:18 +00002902 std::unique_ptr<std::vector<const char *>> Args(
2903 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002904
2905 // Recover resources if we crash before exiting this method.
2906 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2907 ArgsCleanup(Args.get());
2908
2909 // Since the Clang C library is primarily used by batch tools dealing with
2910 // (often very broken) source code, where spell-checking can have a
2911 // significant negative impact on performance (particularly when
2912 // precompiled headers are involved), we disable it by default.
2913 // Only do this if we haven't found a spell-checking-related argument.
2914 bool FoundSpellCheckingArgument = false;
2915 for (int I = 0; I != num_command_line_args; ++I) {
2916 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2917 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2918 FoundSpellCheckingArgument = true;
2919 break;
2920 }
2921 }
2922 if (!FoundSpellCheckingArgument)
2923 Args->push_back("-fno-spell-checking");
2924
2925 Args->insert(Args->end(), command_line_args,
2926 command_line_args + num_command_line_args);
2927
2928 // The 'source_filename' argument is optional. If the caller does not
2929 // specify it then it is assumed that the source file is specified
2930 // in the actual argument list.
2931 // Put the source file after command_line_args otherwise if '-x' flag is
2932 // present it will be unused.
2933 if (source_filename)
2934 Args->push_back(source_filename);
2935
2936 // Do we need the detailed preprocessing record?
2937 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2938 Args->push_back("-Xclang");
2939 Args->push_back("-detailed-preprocessing-record");
2940 }
2941
2942 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002943 std::unique_ptr<ASTUnit> ErrUnit;
2944 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002945 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002946 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2947 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2948 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2949 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2950 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2951 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002952
2953 if (NumErrors != Diags->getClient()->getNumErrors()) {
2954 // Make sure to check that 'Unit' is non-NULL.
2955 if (CXXIdx->getDisplayDiagnostics())
2956 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2957 }
2958
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002959 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2960 PTUI->result = CXError_ASTReadError;
2961 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002962 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002963 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2964 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002965}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002966
2967CXTranslationUnit
2968clang_parseTranslationUnit(CXIndex CIdx,
2969 const char *source_filename,
2970 const char *const *command_line_args,
2971 int num_command_line_args,
2972 struct CXUnsavedFile *unsaved_files,
2973 unsigned num_unsaved_files,
2974 unsigned options) {
2975 CXTranslationUnit TU;
2976 enum CXErrorCode Result = clang_parseTranslationUnit2(
2977 CIdx, source_filename, command_line_args, num_command_line_args,
2978 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002979 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002980 assert((TU && Result == CXError_Success) ||
2981 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002982 return TU;
2983}
2984
2985enum CXErrorCode clang_parseTranslationUnit2(
2986 CXIndex CIdx,
2987 const char *source_filename,
2988 const char *const *command_line_args,
2989 int num_command_line_args,
2990 struct CXUnsavedFile *unsaved_files,
2991 unsigned num_unsaved_files,
2992 unsigned options,
2993 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002994 LOG_FUNC_SECTION {
2995 *Log << source_filename << ": ";
2996 for (int i = 0; i != num_command_line_args; ++i)
2997 *Log << command_line_args[i] << " ";
2998 }
2999
Alp Toker9d85b182014-07-07 01:23:14 +00003000 if (num_unsaved_files && !unsaved_files)
3001 return CXError_InvalidArguments;
3002
Alp Toker5c532982014-07-07 22:42:03 +00003003 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003004 ParseTranslationUnitInfo PTUI = {
3005 CIdx,
3006 source_filename,
3007 command_line_args,
3008 num_command_line_args,
3009 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3010 options,
3011 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003012 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003013 llvm::CrashRecoveryContext CRC;
3014
3015 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3016 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3017 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3018 fprintf(stderr, " 'command_line_args' : [");
3019 for (int i = 0; i != num_command_line_args; ++i) {
3020 if (i)
3021 fprintf(stderr, ", ");
3022 fprintf(stderr, "'%s'", command_line_args[i]);
3023 }
3024 fprintf(stderr, "],\n");
3025 fprintf(stderr, " 'unsaved_files' : [");
3026 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3027 if (i)
3028 fprintf(stderr, ", ");
3029 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3030 unsaved_files[i].Length);
3031 }
3032 fprintf(stderr, "],\n");
3033 fprintf(stderr, " 'options' : %d,\n", options);
3034 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003035
3036 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003037 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003038 if (CXTranslationUnit *TU = PTUI.out_TU)
3039 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003040 }
Alp Toker5c532982014-07-07 22:42:03 +00003041
3042 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003043}
3044
3045unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3046 return CXSaveTranslationUnit_None;
3047}
3048
3049namespace {
3050
3051struct SaveTranslationUnitInfo {
3052 CXTranslationUnit TU;
3053 const char *FileName;
3054 unsigned options;
3055 CXSaveError result;
3056};
3057
3058}
3059
3060static void clang_saveTranslationUnit_Impl(void *UserData) {
3061 SaveTranslationUnitInfo *STUI =
3062 static_cast<SaveTranslationUnitInfo*>(UserData);
3063
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003064 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003065 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3066 setThreadBackgroundPriority();
3067
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003068 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003069 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3070}
3071
3072int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3073 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003074 LOG_FUNC_SECTION {
3075 *Log << TU << ' ' << FileName;
3076 }
3077
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003078 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003079 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003080 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003081 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003082
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003083 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003084 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3085 if (!CXXUnit->hasSema())
3086 return CXSaveError_InvalidTU;
3087
3088 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3089
3090 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3091 getenv("LIBCLANG_NOTHREADS")) {
3092 clang_saveTranslationUnit_Impl(&STUI);
3093
3094 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3095 PrintLibclangResourceUsage(TU);
3096
3097 return STUI.result;
3098 }
3099
3100 // We have an AST that has invalid nodes due to compiler errors.
3101 // Use a crash recovery thread for protection.
3102
3103 llvm::CrashRecoveryContext CRC;
3104
3105 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3106 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3107 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3108 fprintf(stderr, " 'options' : %d,\n", options);
3109 fprintf(stderr, "}\n");
3110
3111 return CXSaveError_Unknown;
3112
3113 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3114 PrintLibclangResourceUsage(TU);
3115 }
3116
3117 return STUI.result;
3118}
3119
3120void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3121 if (CTUnit) {
3122 // If the translation unit has been marked as unsafe to free, just discard
3123 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003124 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3125 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 return;
3127
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003128 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003129 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3131 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003132 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003133 delete CTUnit;
3134 }
3135}
3136
3137unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3138 return CXReparse_None;
3139}
3140
3141struct ReparseTranslationUnitInfo {
3142 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003143 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003144 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003145 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003146};
3147
3148static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003149 const ReparseTranslationUnitInfo *RTUI =
3150 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003151 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003152 unsigned options = RTUI->options;
3153 (void) options;
3154
3155 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003156 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003157 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003158 RTUI->result = CXError_InvalidArguments;
3159 return;
3160 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003161
3162 // Reset the associated diagnostics.
3163 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003164 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003165
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003166 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3168 setThreadBackgroundPriority();
3169
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003170 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003172
3173 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3174 new std::vector<ASTUnit::RemappedFile>());
3175
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 // Recover resources if we crash before exiting this function.
3177 llvm::CrashRecoveryContextCleanupRegistrar<
3178 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003179
3180 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003181 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003182 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003183 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003185
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003186 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003187 RTUI->result = CXError_Success;
3188 else if (isASTReadError(CXXUnit))
3189 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003190}
3191
3192int clang_reparseTranslationUnit(CXTranslationUnit TU,
3193 unsigned num_unsaved_files,
3194 struct CXUnsavedFile *unsaved_files,
3195 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003196 LOG_FUNC_SECTION {
3197 *Log << TU;
3198 }
3199
Alp Toker9d85b182014-07-07 01:23:14 +00003200 if (num_unsaved_files && !unsaved_files)
3201 return CXError_InvalidArguments;
3202
Alp Toker5c532982014-07-07 22:42:03 +00003203 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003204 ReparseTranslationUnitInfo RTUI = {
3205 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003206 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003207
3208 if (getenv("LIBCLANG_NOTHREADS")) {
3209 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003210 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 }
3212
3213 llvm::CrashRecoveryContext CRC;
3214
3215 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3216 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003217 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003218 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3220 PrintLibclangResourceUsage(TU);
3221
Alp Toker5c532982014-07-07 22:42:03 +00003222 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003223}
3224
3225
3226CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003227 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003228 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003229 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003230 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003231
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003232 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003233 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003234}
3235
3236CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003237 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003238 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003239 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003240 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003241
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003242 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003243 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3244}
3245
3246} // end: extern "C"
3247
3248//===----------------------------------------------------------------------===//
3249// CXFile Operations.
3250//===----------------------------------------------------------------------===//
3251
3252extern "C" {
3253CXString clang_getFileName(CXFile SFile) {
3254 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003255 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003256
3257 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003258 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003259}
3260
3261time_t clang_getFileTime(CXFile SFile) {
3262 if (!SFile)
3263 return 0;
3264
3265 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3266 return FEnt->getModificationTime();
3267}
3268
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003269CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003270 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003271 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003272 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003273 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003274
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003275 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003276
3277 FileManager &FMgr = CXXUnit->getFileManager();
3278 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3279}
3280
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003281unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3282 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003283 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003284 LOG_BAD_TU(TU);
3285 return 0;
3286 }
3287
3288 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 return 0;
3290
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003291 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003292 FileEntry *FEnt = static_cast<FileEntry *>(file);
3293 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3294 .isFileMultipleIncludeGuarded(FEnt);
3295}
3296
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003297int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3298 if (!file || !outID)
3299 return 1;
3300
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003301 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003302 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3303 outID->data[0] = ID.getDevice();
3304 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003305 outID->data[2] = FEnt->getModificationTime();
3306 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003307}
3308
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003309int clang_File_isEqual(CXFile file1, CXFile file2) {
3310 if (file1 == file2)
3311 return true;
3312
3313 if (!file1 || !file2)
3314 return false;
3315
3316 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3317 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3318 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3319}
3320
Guy Benyei11169dd2012-12-18 14:30:41 +00003321} // end: extern "C"
3322
3323//===----------------------------------------------------------------------===//
3324// CXCursor Operations.
3325//===----------------------------------------------------------------------===//
3326
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003327static const Decl *getDeclFromExpr(const Stmt *E) {
3328 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 return getDeclFromExpr(CE->getSubExpr());
3330
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003331 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003333 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003335 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003337 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 if (PRE->isExplicitProperty())
3339 return PRE->getExplicitProperty();
3340 // It could be messaging both getter and setter as in:
3341 // ++myobj.myprop;
3342 // in which case prefer to associate the setter since it is less obvious
3343 // from inspecting the source that the setter is going to get called.
3344 if (PRE->isMessagingSetter())
3345 return PRE->getImplicitPropertySetter();
3346 return PRE->getImplicitPropertyGetter();
3347 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003348 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003350 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 if (Expr *Src = OVE->getSourceExpr())
3352 return getDeclFromExpr(Src);
3353
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003354 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003356 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 if (!CE->isElidable())
3358 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003359 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 return OME->getMethodDecl();
3361
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003362 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003364 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3366 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003367 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3369 isa<ParmVarDecl>(SizeOfPack->getPack()))
3370 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003371
3372 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003373}
3374
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003375static SourceLocation getLocationFromExpr(const Expr *E) {
3376 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 return getLocationFromExpr(CE->getSubExpr());
3378
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003379 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003381 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003383 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003385 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003387 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003389 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 return PropRef->getLocation();
3391
3392 return E->getLocStart();
3393}
3394
3395extern "C" {
3396
3397unsigned clang_visitChildren(CXCursor parent,
3398 CXCursorVisitor visitor,
3399 CXClientData client_data) {
3400 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3401 /*VisitPreprocessorLast=*/false);
3402 return CursorVis.VisitChildren(parent);
3403}
3404
3405#ifndef __has_feature
3406#define __has_feature(x) 0
3407#endif
3408#if __has_feature(blocks)
3409typedef enum CXChildVisitResult
3410 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3411
3412static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3413 CXClientData client_data) {
3414 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3415 return block(cursor, parent);
3416}
3417#else
3418// If we are compiled with a compiler that doesn't have native blocks support,
3419// define and call the block manually, so the
3420typedef struct _CXChildVisitResult
3421{
3422 void *isa;
3423 int flags;
3424 int reserved;
3425 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3426 CXCursor);
3427} *CXCursorVisitorBlock;
3428
3429static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3430 CXClientData client_data) {
3431 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3432 return block->invoke(block, cursor, parent);
3433}
3434#endif
3435
3436
3437unsigned clang_visitChildrenWithBlock(CXCursor parent,
3438 CXCursorVisitorBlock block) {
3439 return clang_visitChildren(parent, visitWithBlock, block);
3440}
3441
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003442static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003444 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003445
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003446 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003447 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003448 if (const ObjCPropertyImplDecl *PropImpl =
3449 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003451 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003452
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003453 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003454 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003455 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003456
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003457 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 }
3459
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003460 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003461 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003462
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003463 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3465 // and returns different names. NamedDecl returns the class name and
3466 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003467 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003468
3469 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003470 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003471
3472 SmallString<1024> S;
3473 llvm::raw_svector_ostream os(S);
3474 ND->printName(os);
3475
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003476 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003477}
3478
3479CXString clang_getCursorSpelling(CXCursor C) {
3480 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003481 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003482
3483 if (clang_isReference(C.kind)) {
3484 switch (C.kind) {
3485 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003486 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003487 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 }
3489 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003490 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003491 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 }
3493 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003494 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003496 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 }
3498 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003499 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003500 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003501 }
3502 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003503 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 assert(Type && "Missing type decl");
3505
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003506 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 getAsString());
3508 }
3509 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003510 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 assert(Template && "Missing template decl");
3512
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003513 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 }
3515
3516 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003517 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003518 assert(NS && "Missing namespace decl");
3519
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003520 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 }
3522
3523 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003524 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 assert(Field && "Missing member decl");
3526
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003527 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 }
3529
3530 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003531 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 assert(Label && "Missing label");
3533
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003534 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 }
3536
3537 case CXCursor_OverloadedDeclRef: {
3538 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003539 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3540 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003541 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003542 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003544 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003545 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 OverloadedTemplateStorage *Ovl
3547 = Storage.get<OverloadedTemplateStorage*>();
3548 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003549 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003550 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 }
3552
3553 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003554 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 assert(Var && "Missing variable decl");
3556
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003557 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 }
3559
3560 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003561 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 }
3563 }
3564
3565 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003566 const Expr *E = getCursorExpr(C);
3567
3568 if (C.kind == CXCursor_ObjCStringLiteral ||
3569 C.kind == CXCursor_StringLiteral) {
3570 const StringLiteral *SLit;
3571 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3572 SLit = OSL->getString();
3573 } else {
3574 SLit = cast<StringLiteral>(E);
3575 }
3576 SmallString<256> Buf;
3577 llvm::raw_svector_ostream OS(Buf);
3578 SLit->outputString(OS);
3579 return cxstring::createDup(OS.str());
3580 }
3581
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003582 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 if (D)
3584 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003585 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 }
3587
3588 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003589 const Stmt *S = getCursorStmt(C);
3590 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003591 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003592
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003593 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 }
3595
3596 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003597 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 ->getNameStart());
3599
3600 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003601 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 ->getNameStart());
3603
3604 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003605 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003606
3607 if (clang_isDeclaration(C.kind))
3608 return getDeclSpelling(getCursorDecl(C));
3609
3610 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003611 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003612 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 }
3614
3615 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003616 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003617 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 }
3619
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003620 if (C.kind == CXCursor_PackedAttr) {
3621 return cxstring::createRef("packed");
3622 }
3623
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003624 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003625}
3626
3627CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3628 unsigned pieceIndex,
3629 unsigned options) {
3630 if (clang_Cursor_isNull(C))
3631 return clang_getNullRange();
3632
3633 ASTContext &Ctx = getCursorContext(C);
3634
3635 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003636 const Stmt *S = getCursorStmt(C);
3637 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 if (pieceIndex > 0)
3639 return clang_getNullRange();
3640 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3641 }
3642
3643 return clang_getNullRange();
3644 }
3645
3646 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003647 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3649 if (pieceIndex >= ME->getNumSelectorLocs())
3650 return clang_getNullRange();
3651 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3652 }
3653 }
3654
3655 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3656 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003657 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3659 if (pieceIndex >= MD->getNumSelectorLocs())
3660 return clang_getNullRange();
3661 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3662 }
3663 }
3664
3665 if (C.kind == CXCursor_ObjCCategoryDecl ||
3666 C.kind == CXCursor_ObjCCategoryImplDecl) {
3667 if (pieceIndex > 0)
3668 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003669 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3671 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003672 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3674 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3675 }
3676
3677 if (C.kind == CXCursor_ModuleImportDecl) {
3678 if (pieceIndex > 0)
3679 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003680 if (const ImportDecl *ImportD =
3681 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3683 if (!Locs.empty())
3684 return cxloc::translateSourceRange(Ctx,
3685 SourceRange(Locs.front(), Locs.back()));
3686 }
3687 return clang_getNullRange();
3688 }
3689
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003690 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3691 C.kind == CXCursor_ConversionFunction) {
3692 if (pieceIndex > 0)
3693 return clang_getNullRange();
3694 if (const FunctionDecl *FD =
3695 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3696 DeclarationNameInfo FunctionName = FD->getNameInfo();
3697 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3698 }
3699 return clang_getNullRange();
3700 }
3701
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 // FIXME: A CXCursor_InclusionDirective should give the location of the
3703 // filename, but we don't keep track of this.
3704
3705 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3706 // but we don't keep track of this.
3707
3708 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3709 // but we don't keep track of this.
3710
3711 // Default handling, give the location of the cursor.
3712
3713 if (pieceIndex > 0)
3714 return clang_getNullRange();
3715
3716 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3717 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3718 return cxloc::translateSourceRange(Ctx, Loc);
3719}
3720
Eli Bendersky44a206f2014-07-31 18:04:56 +00003721CXString clang_Cursor_getMangling(CXCursor C) {
3722 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3723 return cxstring::createEmpty();
3724
Eli Bendersky44a206f2014-07-31 18:04:56 +00003725 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003726 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003727 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3728 return cxstring::createEmpty();
3729
Eli Bendersky79759592014-08-01 15:01:10 +00003730 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003731 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003732 ASTContext &Ctx = ND->getASTContext();
3733 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003734
Eli Bendersky79759592014-08-01 15:01:10 +00003735 std::string FrontendBuf;
3736 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3737 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003738
Eli Bendersky79759592014-08-01 15:01:10 +00003739 // Now apply backend mangling.
3740 std::unique_ptr<llvm::DataLayout> DL(
3741 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3742 llvm::Mangler BackendMangler(DL.get());
3743
3744 std::string FinalBuf;
3745 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3746 BackendMangler.getNameWithPrefix(FinalBufOS,
3747 llvm::Twine(FrontendBufOS.str()));
3748
3749 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003750}
3751
Guy Benyei11169dd2012-12-18 14:30:41 +00003752CXString clang_getCursorDisplayName(CXCursor C) {
3753 if (!clang_isDeclaration(C.kind))
3754 return clang_getCursorSpelling(C);
3755
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003756 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003758 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003759
3760 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003761 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 D = FunTmpl->getTemplatedDecl();
3763
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003764 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 SmallString<64> Str;
3766 llvm::raw_svector_ostream OS(Str);
3767 OS << *Function;
3768 if (Function->getPrimaryTemplate())
3769 OS << "<>";
3770 OS << "(";
3771 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3772 if (I)
3773 OS << ", ";
3774 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3775 }
3776
3777 if (Function->isVariadic()) {
3778 if (Function->getNumParams())
3779 OS << ", ";
3780 OS << "...";
3781 }
3782 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003783 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 }
3785
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003786 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 SmallString<64> Str;
3788 llvm::raw_svector_ostream OS(Str);
3789 OS << *ClassTemplate;
3790 OS << "<";
3791 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3792 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3793 if (I)
3794 OS << ", ";
3795
3796 NamedDecl *Param = Params->getParam(I);
3797 if (Param->getIdentifier()) {
3798 OS << Param->getIdentifier()->getName();
3799 continue;
3800 }
3801
3802 // There is no parameter name, which makes this tricky. Try to come up
3803 // with something useful that isn't too long.
3804 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3805 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3806 else if (NonTypeTemplateParmDecl *NTTP
3807 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3808 OS << NTTP->getType().getAsString(Policy);
3809 else
3810 OS << "template<...> class";
3811 }
3812
3813 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003814 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 }
3816
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003817 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3819 // If the type was explicitly written, use that.
3820 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003821 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003822
Benjamin Kramer9170e912013-02-22 15:46:01 +00003823 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 llvm::raw_svector_ostream OS(Str);
3825 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003826 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 ClassSpec->getTemplateArgs().data(),
3828 ClassSpec->getTemplateArgs().size(),
3829 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003830 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 }
3832
3833 return clang_getCursorSpelling(C);
3834}
3835
3836CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3837 switch (Kind) {
3838 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003966 case CXCursor_ObjCSelfExpr:
3967 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004056 case CXCursor_SEHLeaveStmt:
4057 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004086 case CXCursor_PackedAttr:
4087 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004088 case CXCursor_PureAttr:
4089 return cxstring::createRef("attribute(pure)");
4090 case CXCursor_ConstAttr:
4091 return cxstring::createRef("attribute(const)");
4092 case CXCursor_NoDuplicateAttr:
4093 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004094 case CXCursor_CUDAConstantAttr:
4095 return cxstring::createRef("attribute(constant)");
4096 case CXCursor_CUDADeviceAttr:
4097 return cxstring::createRef("attribute(device)");
4098 case CXCursor_CUDAGlobalAttr:
4099 return cxstring::createRef("attribute(global)");
4100 case CXCursor_CUDAHostAttr:
4101 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004102 case CXCursor_CUDASharedAttr:
4103 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004152 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004153 return cxstring::createRef("OMPParallelDirective");
4154 case CXCursor_OMPSimdDirective:
4155 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004156 case CXCursor_OMPForDirective:
4157 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004158 case CXCursor_OMPForSimdDirective:
4159 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004160 case CXCursor_OMPSectionsDirective:
4161 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004162 case CXCursor_OMPSectionDirective:
4163 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004164 case CXCursor_OMPSingleDirective:
4165 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004166 case CXCursor_OMPMasterDirective:
4167 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004168 case CXCursor_OMPCriticalDirective:
4169 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004170 case CXCursor_OMPParallelForDirective:
4171 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004172 case CXCursor_OMPParallelForSimdDirective:
4173 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004174 case CXCursor_OMPParallelSectionsDirective:
4175 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004176 case CXCursor_OMPTaskDirective:
4177 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004178 case CXCursor_OMPTaskyieldDirective:
4179 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004180 case CXCursor_OMPBarrierDirective:
4181 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004182 case CXCursor_OMPTaskwaitDirective:
4183 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004184 case CXCursor_OMPFlushDirective:
4185 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004186 case CXCursor_OMPOrderedDirective:
4187 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004188 case CXCursor_OMPAtomicDirective:
4189 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004190 case CXCursor_OMPTargetDirective:
4191 return cxstring::createRef("OMPTargetDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 }
4193
4194 llvm_unreachable("Unhandled CXCursorKind");
4195}
4196
4197struct GetCursorData {
4198 SourceLocation TokenBeginLoc;
4199 bool PointsAtMacroArgExpansion;
4200 bool VisitedObjCPropertyImplDecl;
4201 SourceLocation VisitedDeclaratorDeclStartLoc;
4202 CXCursor &BestCursor;
4203
4204 GetCursorData(SourceManager &SM,
4205 SourceLocation tokenBegin, CXCursor &outputCursor)
4206 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4207 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4208 VisitedObjCPropertyImplDecl = false;
4209 }
4210};
4211
4212static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4213 CXCursor parent,
4214 CXClientData client_data) {
4215 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4216 CXCursor *BestCursor = &Data->BestCursor;
4217
4218 // If we point inside a macro argument we should provide info of what the
4219 // token is so use the actual cursor, don't replace it with a macro expansion
4220 // cursor.
4221 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4222 return CXChildVisit_Recurse;
4223
4224 if (clang_isDeclaration(cursor.kind)) {
4225 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004226 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4228 if (MD->isImplicit())
4229 return CXChildVisit_Break;
4230
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004231 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4233 // Check that when we have multiple @class references in the same line,
4234 // that later ones do not override the previous ones.
4235 // If we have:
4236 // @class Foo, Bar;
4237 // source ranges for both start at '@', so 'Bar' will end up overriding
4238 // 'Foo' even though the cursor location was at 'Foo'.
4239 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4240 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004241 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4243 if (PrevID != ID &&
4244 !PrevID->isThisDeclarationADefinition() &&
4245 !ID->isThisDeclarationADefinition())
4246 return CXChildVisit_Break;
4247 }
4248
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004249 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4251 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4252 // Check that when we have multiple declarators in the same line,
4253 // that later ones do not override the previous ones.
4254 // If we have:
4255 // int Foo, Bar;
4256 // source ranges for both start at 'int', so 'Bar' will end up overriding
4257 // 'Foo' even though the cursor location was at 'Foo'.
4258 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4259 return CXChildVisit_Break;
4260 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4261
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004262 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4264 (void)PropImp;
4265 // Check that when we have multiple @synthesize in the same line,
4266 // that later ones do not override the previous ones.
4267 // If we have:
4268 // @synthesize Foo, Bar;
4269 // source ranges for both start at '@', so 'Bar' will end up overriding
4270 // 'Foo' even though the cursor location was at 'Foo'.
4271 if (Data->VisitedObjCPropertyImplDecl)
4272 return CXChildVisit_Break;
4273 Data->VisitedObjCPropertyImplDecl = true;
4274 }
4275 }
4276
4277 if (clang_isExpression(cursor.kind) &&
4278 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004279 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 // Avoid having the cursor of an expression replace the declaration cursor
4281 // when the expression source range overlaps the declaration range.
4282 // This can happen for C++ constructor expressions whose range generally
4283 // include the variable declaration, e.g.:
4284 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4285 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4286 D->getLocation() == Data->TokenBeginLoc)
4287 return CXChildVisit_Break;
4288 }
4289 }
4290
4291 // If our current best cursor is the construction of a temporary object,
4292 // don't replace that cursor with a type reference, because we want
4293 // clang_getCursor() to point at the constructor.
4294 if (clang_isExpression(BestCursor->kind) &&
4295 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4296 cursor.kind == CXCursor_TypeRef) {
4297 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4298 // as having the actual point on the type reference.
4299 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4300 return CXChildVisit_Recurse;
4301 }
4302
4303 *BestCursor = cursor;
4304 return CXChildVisit_Recurse;
4305}
4306
4307CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004308 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004309 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004311 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004312
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004313 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004314 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4315
4316 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4317 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4318
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004319 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 CXFile SearchFile;
4321 unsigned SearchLine, SearchColumn;
4322 CXFile ResultFile;
4323 unsigned ResultLine, ResultColumn;
4324 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4325 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4326 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004327
4328 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4329 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004330 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004331 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 SearchFileName = clang_getFileName(SearchFile);
4333 ResultFileName = clang_getFileName(ResultFile);
4334 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4335 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004336 *Log << llvm::format("(%s:%d:%d) = %s",
4337 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4338 clang_getCString(KindSpelling))
4339 << llvm::format("(%s:%d:%d):%s%s",
4340 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4341 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004342 clang_disposeString(SearchFileName);
4343 clang_disposeString(ResultFileName);
4344 clang_disposeString(KindSpelling);
4345 clang_disposeString(USR);
4346
4347 CXCursor Definition = clang_getCursorDefinition(Result);
4348 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4349 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4350 CXString DefinitionKindSpelling
4351 = clang_getCursorKindSpelling(Definition.kind);
4352 CXFile DefinitionFile;
4353 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004354 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004355 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004356 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004357 *Log << llvm::format(" -> %s(%s:%d:%d)",
4358 clang_getCString(DefinitionKindSpelling),
4359 clang_getCString(DefinitionFileName),
4360 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004361 clang_disposeString(DefinitionFileName);
4362 clang_disposeString(DefinitionKindSpelling);
4363 }
4364 }
4365
4366 return Result;
4367}
4368
4369CXCursor clang_getNullCursor(void) {
4370 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4371}
4372
4373unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004374 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4375 // can't set consistently. For example, when visiting a DeclStmt we will set
4376 // it but we don't set it on the result of clang_getCursorDefinition for
4377 // a reference of the same declaration.
4378 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4379 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4380 // to provide that kind of info.
4381 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004382 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004383 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004384 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004385
Guy Benyei11169dd2012-12-18 14:30:41 +00004386 return X == Y;
4387}
4388
4389unsigned clang_hashCursor(CXCursor C) {
4390 unsigned Index = 0;
4391 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4392 Index = 1;
4393
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004394 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004395 std::make_pair(C.kind, C.data[Index]));
4396}
4397
4398unsigned clang_isInvalid(enum CXCursorKind K) {
4399 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4400}
4401
4402unsigned clang_isDeclaration(enum CXCursorKind K) {
4403 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4404 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4405}
4406
4407unsigned clang_isReference(enum CXCursorKind K) {
4408 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4409}
4410
4411unsigned clang_isExpression(enum CXCursorKind K) {
4412 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4413}
4414
4415unsigned clang_isStatement(enum CXCursorKind K) {
4416 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4417}
4418
4419unsigned clang_isAttribute(enum CXCursorKind K) {
4420 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4421}
4422
4423unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4424 return K == CXCursor_TranslationUnit;
4425}
4426
4427unsigned clang_isPreprocessing(enum CXCursorKind K) {
4428 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4429}
4430
4431unsigned clang_isUnexposed(enum CXCursorKind K) {
4432 switch (K) {
4433 case CXCursor_UnexposedDecl:
4434 case CXCursor_UnexposedExpr:
4435 case CXCursor_UnexposedStmt:
4436 case CXCursor_UnexposedAttr:
4437 return true;
4438 default:
4439 return false;
4440 }
4441}
4442
4443CXCursorKind clang_getCursorKind(CXCursor C) {
4444 return C.kind;
4445}
4446
4447CXSourceLocation clang_getCursorLocation(CXCursor C) {
4448 if (clang_isReference(C.kind)) {
4449 switch (C.kind) {
4450 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004451 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 = getCursorObjCSuperClassRef(C);
4453 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4454 }
4455
4456 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004457 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 = getCursorObjCProtocolRef(C);
4459 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4460 }
4461
4462 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004463 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 = getCursorObjCClassRef(C);
4465 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4466 }
4467
4468 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004469 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4471 }
4472
4473 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004474 std::pair<const TemplateDecl *, SourceLocation> P =
4475 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4477 }
4478
4479 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004480 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4482 }
4483
4484 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004485 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4487 }
4488
4489 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004490 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4492 }
4493
4494 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004495 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 if (!BaseSpec)
4497 return clang_getNullLocation();
4498
4499 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4500 return cxloc::translateSourceLocation(getCursorContext(C),
4501 TSInfo->getTypeLoc().getBeginLoc());
4502
4503 return cxloc::translateSourceLocation(getCursorContext(C),
4504 BaseSpec->getLocStart());
4505 }
4506
4507 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004508 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4510 }
4511
4512 case CXCursor_OverloadedDeclRef:
4513 return cxloc::translateSourceLocation(getCursorContext(C),
4514 getCursorOverloadedDeclRef(C).second);
4515
4516 default:
4517 // FIXME: Need a way to enumerate all non-reference cases.
4518 llvm_unreachable("Missed a reference kind");
4519 }
4520 }
4521
4522 if (clang_isExpression(C.kind))
4523 return cxloc::translateSourceLocation(getCursorContext(C),
4524 getLocationFromExpr(getCursorExpr(C)));
4525
4526 if (clang_isStatement(C.kind))
4527 return cxloc::translateSourceLocation(getCursorContext(C),
4528 getCursorStmt(C)->getLocStart());
4529
4530 if (C.kind == CXCursor_PreprocessingDirective) {
4531 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4532 return cxloc::translateSourceLocation(getCursorContext(C), L);
4533 }
4534
4535 if (C.kind == CXCursor_MacroExpansion) {
4536 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004537 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 return cxloc::translateSourceLocation(getCursorContext(C), L);
4539 }
4540
4541 if (C.kind == CXCursor_MacroDefinition) {
4542 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4543 return cxloc::translateSourceLocation(getCursorContext(C), L);
4544 }
4545
4546 if (C.kind == CXCursor_InclusionDirective) {
4547 SourceLocation L
4548 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4549 return cxloc::translateSourceLocation(getCursorContext(C), L);
4550 }
4551
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004552 if (clang_isAttribute(C.kind)) {
4553 SourceLocation L
4554 = cxcursor::getCursorAttr(C)->getLocation();
4555 return cxloc::translateSourceLocation(getCursorContext(C), L);
4556 }
4557
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 if (!clang_isDeclaration(C.kind))
4559 return clang_getNullLocation();
4560
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004561 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 if (!D)
4563 return clang_getNullLocation();
4564
4565 SourceLocation Loc = D->getLocation();
4566 // FIXME: Multiple variables declared in a single declaration
4567 // currently lack the information needed to correctly determine their
4568 // ranges when accounting for the type-specifier. We use context
4569 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4570 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004571 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 if (!cxcursor::isFirstInDeclGroup(C))
4573 Loc = VD->getLocation();
4574 }
4575
4576 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004577 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 Loc = MD->getSelectorStartLoc();
4579
4580 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4581}
4582
4583} // end extern "C"
4584
4585CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4586 assert(TU);
4587
4588 // Guard against an invalid SourceLocation, or we may assert in one
4589 // of the following calls.
4590 if (SLoc.isInvalid())
4591 return clang_getNullCursor();
4592
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004593 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004594
4595 // Translate the given source location to make it point at the beginning of
4596 // the token under the cursor.
4597 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4598 CXXUnit->getASTContext().getLangOpts());
4599
4600 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4601 if (SLoc.isValid()) {
4602 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4603 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4604 /*VisitPreprocessorLast=*/true,
4605 /*VisitIncludedEntities=*/false,
4606 SourceLocation(SLoc));
4607 CursorVis.visitFileRegion();
4608 }
4609
4610 return Result;
4611}
4612
4613static SourceRange getRawCursorExtent(CXCursor C) {
4614 if (clang_isReference(C.kind)) {
4615 switch (C.kind) {
4616 case CXCursor_ObjCSuperClassRef:
4617 return getCursorObjCSuperClassRef(C).second;
4618
4619 case CXCursor_ObjCProtocolRef:
4620 return getCursorObjCProtocolRef(C).second;
4621
4622 case CXCursor_ObjCClassRef:
4623 return getCursorObjCClassRef(C).second;
4624
4625 case CXCursor_TypeRef:
4626 return getCursorTypeRef(C).second;
4627
4628 case CXCursor_TemplateRef:
4629 return getCursorTemplateRef(C).second;
4630
4631 case CXCursor_NamespaceRef:
4632 return getCursorNamespaceRef(C).second;
4633
4634 case CXCursor_MemberRef:
4635 return getCursorMemberRef(C).second;
4636
4637 case CXCursor_CXXBaseSpecifier:
4638 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4639
4640 case CXCursor_LabelRef:
4641 return getCursorLabelRef(C).second;
4642
4643 case CXCursor_OverloadedDeclRef:
4644 return getCursorOverloadedDeclRef(C).second;
4645
4646 case CXCursor_VariableRef:
4647 return getCursorVariableRef(C).second;
4648
4649 default:
4650 // FIXME: Need a way to enumerate all non-reference cases.
4651 llvm_unreachable("Missed a reference kind");
4652 }
4653 }
4654
4655 if (clang_isExpression(C.kind))
4656 return getCursorExpr(C)->getSourceRange();
4657
4658 if (clang_isStatement(C.kind))
4659 return getCursorStmt(C)->getSourceRange();
4660
4661 if (clang_isAttribute(C.kind))
4662 return getCursorAttr(C)->getRange();
4663
4664 if (C.kind == CXCursor_PreprocessingDirective)
4665 return cxcursor::getCursorPreprocessingDirective(C);
4666
4667 if (C.kind == CXCursor_MacroExpansion) {
4668 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004669 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 return TU->mapRangeFromPreamble(Range);
4671 }
4672
4673 if (C.kind == CXCursor_MacroDefinition) {
4674 ASTUnit *TU = getCursorASTUnit(C);
4675 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4676 return TU->mapRangeFromPreamble(Range);
4677 }
4678
4679 if (C.kind == CXCursor_InclusionDirective) {
4680 ASTUnit *TU = getCursorASTUnit(C);
4681 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4682 return TU->mapRangeFromPreamble(Range);
4683 }
4684
4685 if (C.kind == CXCursor_TranslationUnit) {
4686 ASTUnit *TU = getCursorASTUnit(C);
4687 FileID MainID = TU->getSourceManager().getMainFileID();
4688 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4689 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4690 return SourceRange(Start, End);
4691 }
4692
4693 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004694 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 if (!D)
4696 return SourceRange();
4697
4698 SourceRange R = D->getSourceRange();
4699 // FIXME: Multiple variables declared in a single declaration
4700 // currently lack the information needed to correctly determine their
4701 // ranges when accounting for the type-specifier. We use context
4702 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4703 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004704 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 if (!cxcursor::isFirstInDeclGroup(C))
4706 R.setBegin(VD->getLocation());
4707 }
4708 return R;
4709 }
4710 return SourceRange();
4711}
4712
4713/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4714/// the decl-specifier-seq for declarations.
4715static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4716 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004717 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 if (!D)
4719 return SourceRange();
4720
4721 SourceRange R = D->getSourceRange();
4722
4723 // Adjust the start of the location for declarations preceded by
4724 // declaration specifiers.
4725 SourceLocation StartLoc;
4726 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4727 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4728 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004729 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4731 StartLoc = TI->getTypeLoc().getLocStart();
4732 }
4733
4734 if (StartLoc.isValid() && R.getBegin().isValid() &&
4735 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4736 R.setBegin(StartLoc);
4737
4738 // FIXME: Multiple variables declared in a single declaration
4739 // currently lack the information needed to correctly determine their
4740 // ranges when accounting for the type-specifier. We use context
4741 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4742 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004743 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 if (!cxcursor::isFirstInDeclGroup(C))
4745 R.setBegin(VD->getLocation());
4746 }
4747
4748 return R;
4749 }
4750
4751 return getRawCursorExtent(C);
4752}
4753
4754extern "C" {
4755
4756CXSourceRange clang_getCursorExtent(CXCursor C) {
4757 SourceRange R = getRawCursorExtent(C);
4758 if (R.isInvalid())
4759 return clang_getNullRange();
4760
4761 return cxloc::translateSourceRange(getCursorContext(C), R);
4762}
4763
4764CXCursor clang_getCursorReferenced(CXCursor C) {
4765 if (clang_isInvalid(C.kind))
4766 return clang_getNullCursor();
4767
4768 CXTranslationUnit tu = getCursorTU(C);
4769 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004770 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 if (!D)
4772 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004773 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004775 if (const ObjCPropertyImplDecl *PropImpl =
4776 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4778 return MakeCXCursor(Property, tu);
4779
4780 return C;
4781 }
4782
4783 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004784 const Expr *E = getCursorExpr(C);
4785 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 if (D) {
4787 CXCursor declCursor = MakeCXCursor(D, tu);
4788 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4789 declCursor);
4790 return declCursor;
4791 }
4792
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004793 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 return MakeCursorOverloadedDeclRef(Ovl, tu);
4795
4796 return clang_getNullCursor();
4797 }
4798
4799 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004800 const Stmt *S = getCursorStmt(C);
4801 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004802 if (LabelDecl *label = Goto->getLabel())
4803 if (LabelStmt *labelS = label->getStmt())
4804 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4805
4806 return clang_getNullCursor();
4807 }
4808
4809 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004810 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004811 return MakeMacroDefinitionCursor(Def, tu);
4812 }
4813
4814 if (!clang_isReference(C.kind))
4815 return clang_getNullCursor();
4816
4817 switch (C.kind) {
4818 case CXCursor_ObjCSuperClassRef:
4819 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4820
4821 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004822 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4823 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 return MakeCXCursor(Def, tu);
4825
4826 return MakeCXCursor(Prot, tu);
4827 }
4828
4829 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004830 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4831 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 return MakeCXCursor(Def, tu);
4833
4834 return MakeCXCursor(Class, tu);
4835 }
4836
4837 case CXCursor_TypeRef:
4838 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4839
4840 case CXCursor_TemplateRef:
4841 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4842
4843 case CXCursor_NamespaceRef:
4844 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4845
4846 case CXCursor_MemberRef:
4847 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4848
4849 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004850 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4852 tu ));
4853 }
4854
4855 case CXCursor_LabelRef:
4856 // FIXME: We end up faking the "parent" declaration here because we
4857 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004858 return MakeCXCursor(getCursorLabelRef(C).first,
4859 cxtu::getASTUnit(tu)->getASTContext()
4860 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 tu);
4862
4863 case CXCursor_OverloadedDeclRef:
4864 return C;
4865
4866 case CXCursor_VariableRef:
4867 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4868
4869 default:
4870 // We would prefer to enumerate all non-reference cursor kinds here.
4871 llvm_unreachable("Unhandled reference cursor kind");
4872 }
4873}
4874
4875CXCursor clang_getCursorDefinition(CXCursor C) {
4876 if (clang_isInvalid(C.kind))
4877 return clang_getNullCursor();
4878
4879 CXTranslationUnit TU = getCursorTU(C);
4880
4881 bool WasReference = false;
4882 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4883 C = clang_getCursorReferenced(C);
4884 WasReference = true;
4885 }
4886
4887 if (C.kind == CXCursor_MacroExpansion)
4888 return clang_getCursorReferenced(C);
4889
4890 if (!clang_isDeclaration(C.kind))
4891 return clang_getNullCursor();
4892
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004893 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 if (!D)
4895 return clang_getNullCursor();
4896
4897 switch (D->getKind()) {
4898 // Declaration kinds that don't really separate the notions of
4899 // declaration and definition.
4900 case Decl::Namespace:
4901 case Decl::Typedef:
4902 case Decl::TypeAlias:
4903 case Decl::TypeAliasTemplate:
4904 case Decl::TemplateTypeParm:
4905 case Decl::EnumConstant:
4906 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004907 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004908 case Decl::IndirectField:
4909 case Decl::ObjCIvar:
4910 case Decl::ObjCAtDefsField:
4911 case Decl::ImplicitParam:
4912 case Decl::ParmVar:
4913 case Decl::NonTypeTemplateParm:
4914 case Decl::TemplateTemplateParm:
4915 case Decl::ObjCCategoryImpl:
4916 case Decl::ObjCImplementation:
4917 case Decl::AccessSpec:
4918 case Decl::LinkageSpec:
4919 case Decl::ObjCPropertyImpl:
4920 case Decl::FileScopeAsm:
4921 case Decl::StaticAssert:
4922 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004923 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 case Decl::Label: // FIXME: Is this right??
4925 case Decl::ClassScopeFunctionSpecialization:
4926 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004927 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004928 return C;
4929
4930 // Declaration kinds that don't make any sense here, but are
4931 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004932 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004933 case Decl::TranslationUnit:
4934 break;
4935
4936 // Declaration kinds for which the definition is not resolvable.
4937 case Decl::UnresolvedUsingTypename:
4938 case Decl::UnresolvedUsingValue:
4939 break;
4940
4941 case Decl::UsingDirective:
4942 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4943 TU);
4944
4945 case Decl::NamespaceAlias:
4946 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4947
4948 case Decl::Enum:
4949 case Decl::Record:
4950 case Decl::CXXRecord:
4951 case Decl::ClassTemplateSpecialization:
4952 case Decl::ClassTemplatePartialSpecialization:
4953 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4954 return MakeCXCursor(Def, TU);
4955 return clang_getNullCursor();
4956
4957 case Decl::Function:
4958 case Decl::CXXMethod:
4959 case Decl::CXXConstructor:
4960 case Decl::CXXDestructor:
4961 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004962 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004963 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004964 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004965 return clang_getNullCursor();
4966 }
4967
Larisse Voufo39a1e502013-08-06 01:03:05 +00004968 case Decl::Var:
4969 case Decl::VarTemplateSpecialization:
4970 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004971 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004972 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004973 return MakeCXCursor(Def, TU);
4974 return clang_getNullCursor();
4975 }
4976
4977 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004978 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004979 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4980 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4981 return clang_getNullCursor();
4982 }
4983
4984 case Decl::ClassTemplate: {
4985 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4986 ->getDefinition())
4987 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4988 TU);
4989 return clang_getNullCursor();
4990 }
4991
Larisse Voufo39a1e502013-08-06 01:03:05 +00004992 case Decl::VarTemplate: {
4993 if (VarDecl *Def =
4994 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4995 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4996 return clang_getNullCursor();
4997 }
4998
Guy Benyei11169dd2012-12-18 14:30:41 +00004999 case Decl::Using:
5000 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5001 D->getLocation(), TU);
5002
5003 case Decl::UsingShadow:
5004 return clang_getCursorDefinition(
5005 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5006 TU));
5007
5008 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005009 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005010 if (Method->isThisDeclarationADefinition())
5011 return C;
5012
5013 // Dig out the method definition in the associated
5014 // @implementation, if we have it.
5015 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005016 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5018 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5019 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5020 Method->isInstanceMethod()))
5021 if (Def->isThisDeclarationADefinition())
5022 return MakeCXCursor(Def, TU);
5023
5024 return clang_getNullCursor();
5025 }
5026
5027 case Decl::ObjCCategory:
5028 if (ObjCCategoryImplDecl *Impl
5029 = cast<ObjCCategoryDecl>(D)->getImplementation())
5030 return MakeCXCursor(Impl, TU);
5031 return clang_getNullCursor();
5032
5033 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005034 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005035 return MakeCXCursor(Def, TU);
5036 return clang_getNullCursor();
5037
5038 case Decl::ObjCInterface: {
5039 // There are two notions of a "definition" for an Objective-C
5040 // class: the interface and its implementation. When we resolved a
5041 // reference to an Objective-C class, produce the @interface as
5042 // the definition; when we were provided with the interface,
5043 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005044 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005046 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 return MakeCXCursor(Def, TU);
5048 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5049 return MakeCXCursor(Impl, TU);
5050 return clang_getNullCursor();
5051 }
5052
5053 case Decl::ObjCProperty:
5054 // FIXME: We don't really know where to find the
5055 // ObjCPropertyImplDecls that implement this property.
5056 return clang_getNullCursor();
5057
5058 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005059 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005060 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005061 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005062 return MakeCXCursor(Def, TU);
5063
5064 return clang_getNullCursor();
5065
5066 case Decl::Friend:
5067 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5068 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5069 return clang_getNullCursor();
5070
5071 case Decl::FriendTemplate:
5072 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5073 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5074 return clang_getNullCursor();
5075 }
5076
5077 return clang_getNullCursor();
5078}
5079
5080unsigned clang_isCursorDefinition(CXCursor C) {
5081 if (!clang_isDeclaration(C.kind))
5082 return 0;
5083
5084 return clang_getCursorDefinition(C) == C;
5085}
5086
5087CXCursor clang_getCanonicalCursor(CXCursor C) {
5088 if (!clang_isDeclaration(C.kind))
5089 return C;
5090
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005091 if (const Decl *D = getCursorDecl(C)) {
5092 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005093 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5094 return MakeCXCursor(CatD, getCursorTU(C));
5095
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005096 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5097 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005098 return MakeCXCursor(IFD, getCursorTU(C));
5099
5100 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5101 }
5102
5103 return C;
5104}
5105
5106int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5107 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5108}
5109
5110unsigned clang_getNumOverloadedDecls(CXCursor C) {
5111 if (C.kind != CXCursor_OverloadedDeclRef)
5112 return 0;
5113
5114 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005115 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 return E->getNumDecls();
5117
5118 if (OverloadedTemplateStorage *S
5119 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5120 return S->size();
5121
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005122 const Decl *D = Storage.get<const Decl *>();
5123 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 return Using->shadow_size();
5125
5126 return 0;
5127}
5128
5129CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5130 if (cursor.kind != CXCursor_OverloadedDeclRef)
5131 return clang_getNullCursor();
5132
5133 if (index >= clang_getNumOverloadedDecls(cursor))
5134 return clang_getNullCursor();
5135
5136 CXTranslationUnit TU = getCursorTU(cursor);
5137 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005138 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005139 return MakeCXCursor(E->decls_begin()[index], TU);
5140
5141 if (OverloadedTemplateStorage *S
5142 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5143 return MakeCXCursor(S->begin()[index], TU);
5144
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005145 const Decl *D = Storage.get<const Decl *>();
5146 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005147 // FIXME: This is, unfortunately, linear time.
5148 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5149 std::advance(Pos, index);
5150 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5151 }
5152
5153 return clang_getNullCursor();
5154}
5155
5156void clang_getDefinitionSpellingAndExtent(CXCursor C,
5157 const char **startBuf,
5158 const char **endBuf,
5159 unsigned *startLine,
5160 unsigned *startColumn,
5161 unsigned *endLine,
5162 unsigned *endColumn) {
5163 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005164 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005165 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5166
5167 SourceManager &SM = FD->getASTContext().getSourceManager();
5168 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5169 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5170 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5171 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5172 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5173 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5174}
5175
5176
5177CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5178 unsigned PieceIndex) {
5179 RefNamePieces Pieces;
5180
5181 switch (C.kind) {
5182 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005183 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5185 E->getQualifierLoc().getSourceRange());
5186 break;
5187
5188 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005189 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5191 E->getQualifierLoc().getSourceRange(),
5192 E->getOptionalExplicitTemplateArgs());
5193 break;
5194
5195 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005196 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005197 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005198 const Expr *Callee = OCE->getCallee();
5199 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 Callee = ICE->getSubExpr();
5201
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005202 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5204 DRE->getQualifierLoc().getSourceRange());
5205 }
5206 break;
5207
5208 default:
5209 break;
5210 }
5211
5212 if (Pieces.empty()) {
5213 if (PieceIndex == 0)
5214 return clang_getCursorExtent(C);
5215 } else if (PieceIndex < Pieces.size()) {
5216 SourceRange R = Pieces[PieceIndex];
5217 if (R.isValid())
5218 return cxloc::translateSourceRange(getCursorContext(C), R);
5219 }
5220
5221 return clang_getNullRange();
5222}
5223
5224void clang_enableStackTraces(void) {
5225 llvm::sys::PrintStackTraceOnErrorSignal();
5226}
5227
5228void clang_executeOnThread(void (*fn)(void*), void *user_data,
5229 unsigned stack_size) {
5230 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5231}
5232
5233} // end: extern "C"
5234
5235//===----------------------------------------------------------------------===//
5236// Token-based Operations.
5237//===----------------------------------------------------------------------===//
5238
5239/* CXToken layout:
5240 * int_data[0]: a CXTokenKind
5241 * int_data[1]: starting token location
5242 * int_data[2]: token length
5243 * int_data[3]: reserved
5244 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5245 * otherwise unused.
5246 */
5247extern "C" {
5248
5249CXTokenKind clang_getTokenKind(CXToken CXTok) {
5250 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5251}
5252
5253CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5254 switch (clang_getTokenKind(CXTok)) {
5255 case CXToken_Identifier:
5256 case CXToken_Keyword:
5257 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005258 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005259 ->getNameStart());
5260
5261 case CXToken_Literal: {
5262 // We have stashed the starting pointer in the ptr_data field. Use it.
5263 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005264 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005265 }
5266
5267 case CXToken_Punctuation:
5268 case CXToken_Comment:
5269 break;
5270 }
5271
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005272 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005273 LOG_BAD_TU(TU);
5274 return cxstring::createEmpty();
5275 }
5276
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 // We have to find the starting buffer pointer the hard way, by
5278 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005279 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005281 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005282
5283 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5284 std::pair<FileID, unsigned> LocInfo
5285 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5286 bool Invalid = false;
5287 StringRef Buffer
5288 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5289 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005290 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005291
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005292 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005293}
5294
5295CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005296 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005297 LOG_BAD_TU(TU);
5298 return clang_getNullLocation();
5299 }
5300
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005301 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 if (!CXXUnit)
5303 return clang_getNullLocation();
5304
5305 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5306 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5307}
5308
5309CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005310 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005311 LOG_BAD_TU(TU);
5312 return clang_getNullRange();
5313 }
5314
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005315 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 if (!CXXUnit)
5317 return clang_getNullRange();
5318
5319 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5320 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5321}
5322
5323static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5324 SmallVectorImpl<CXToken> &CXTokens) {
5325 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5326 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005327 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005329 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005330
5331 // Cannot tokenize across files.
5332 if (BeginLocInfo.first != EndLocInfo.first)
5333 return;
5334
5335 // Create a lexer
5336 bool Invalid = false;
5337 StringRef Buffer
5338 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5339 if (Invalid)
5340 return;
5341
5342 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5343 CXXUnit->getASTContext().getLangOpts(),
5344 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5345 Lex.SetCommentRetentionState(true);
5346
5347 // Lex tokens until we hit the end of the range.
5348 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5349 Token Tok;
5350 bool previousWasAt = false;
5351 do {
5352 // Lex the next token
5353 Lex.LexFromRawLexer(Tok);
5354 if (Tok.is(tok::eof))
5355 break;
5356
5357 // Initialize the CXToken.
5358 CXToken CXTok;
5359
5360 // - Common fields
5361 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5362 CXTok.int_data[2] = Tok.getLength();
5363 CXTok.int_data[3] = 0;
5364
5365 // - Kind-specific fields
5366 if (Tok.isLiteral()) {
5367 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005368 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005369 } else if (Tok.is(tok::raw_identifier)) {
5370 // Lookup the identifier to determine whether we have a keyword.
5371 IdentifierInfo *II
5372 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5373
5374 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5375 CXTok.int_data[0] = CXToken_Keyword;
5376 }
5377 else {
5378 CXTok.int_data[0] = Tok.is(tok::identifier)
5379 ? CXToken_Identifier
5380 : CXToken_Keyword;
5381 }
5382 CXTok.ptr_data = II;
5383 } else if (Tok.is(tok::comment)) {
5384 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005385 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005386 } else {
5387 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005388 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005389 }
5390 CXTokens.push_back(CXTok);
5391 previousWasAt = Tok.is(tok::at);
5392 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5393}
5394
5395void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5396 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005397 LOG_FUNC_SECTION {
5398 *Log << TU << ' ' << Range;
5399 }
5400
Guy Benyei11169dd2012-12-18 14:30:41 +00005401 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005402 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 if (NumTokens)
5404 *NumTokens = 0;
5405
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005406 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005407 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005408 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005409 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005410
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005411 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005412 if (!CXXUnit || !Tokens || !NumTokens)
5413 return;
5414
5415 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5416
5417 SourceRange R = cxloc::translateCXSourceRange(Range);
5418 if (R.isInvalid())
5419 return;
5420
5421 SmallVector<CXToken, 32> CXTokens;
5422 getTokens(CXXUnit, R, CXTokens);
5423
5424 if (CXTokens.empty())
5425 return;
5426
5427 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5428 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5429 *NumTokens = CXTokens.size();
5430}
5431
5432void clang_disposeTokens(CXTranslationUnit TU,
5433 CXToken *Tokens, unsigned NumTokens) {
5434 free(Tokens);
5435}
5436
5437} // end: extern "C"
5438
5439//===----------------------------------------------------------------------===//
5440// Token annotation APIs.
5441//===----------------------------------------------------------------------===//
5442
Guy Benyei11169dd2012-12-18 14:30:41 +00005443static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5444 CXCursor parent,
5445 CXClientData client_data);
5446static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5447 CXClientData client_data);
5448
5449namespace {
5450class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 CXToken *Tokens;
5452 CXCursor *Cursors;
5453 unsigned NumTokens;
5454 unsigned TokIdx;
5455 unsigned PreprocessingTokIdx;
5456 CursorVisitor AnnotateVis;
5457 SourceManager &SrcMgr;
5458 bool HasContextSensitiveKeywords;
5459
5460 struct PostChildrenInfo {
5461 CXCursor Cursor;
5462 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005463 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 unsigned BeforeChildrenTokenIdx;
5465 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005466 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005467
5468 CXToken &getTok(unsigned Idx) {
5469 assert(Idx < NumTokens);
5470 return Tokens[Idx];
5471 }
5472 const CXToken &getTok(unsigned Idx) const {
5473 assert(Idx < NumTokens);
5474 return Tokens[Idx];
5475 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 bool MoreTokens() const { return TokIdx < NumTokens; }
5477 unsigned NextToken() const { return TokIdx; }
5478 void AdvanceToken() { ++TokIdx; }
5479 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005480 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 }
5482 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005483 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 }
5485 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005486 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 }
5488
5489 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005490 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 SourceRange);
5492
5493public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005494 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005495 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005496 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005498 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005499 AnnotateTokensVisitor, this,
5500 /*VisitPreprocessorLast=*/true,
5501 /*VisitIncludedEntities=*/false,
5502 RegionOfInterest,
5503 /*VisitDeclsOnly=*/false,
5504 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005505 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005506 HasContextSensitiveKeywords(false) { }
5507
5508 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5509 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5510 bool postVisitChildren(CXCursor cursor);
5511 void AnnotateTokens();
5512
5513 /// \brief Determine whether the annotator saw any cursors that have
5514 /// context-sensitive keywords.
5515 bool hasContextSensitiveKeywords() const {
5516 return HasContextSensitiveKeywords;
5517 }
5518
5519 ~AnnotateTokensWorker() {
5520 assert(PostChildrenInfos.empty());
5521 }
5522};
5523}
5524
5525void AnnotateTokensWorker::AnnotateTokens() {
5526 // Walk the AST within the region of interest, annotating tokens
5527 // along the way.
5528 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005529}
Guy Benyei11169dd2012-12-18 14:30:41 +00005530
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005531static inline void updateCursorAnnotation(CXCursor &Cursor,
5532 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005533 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005534 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005535 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005536}
5537
5538/// \brief It annotates and advances tokens with a cursor until the comparison
5539//// between the cursor location and the source range is the same as
5540/// \arg compResult.
5541///
5542/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5543/// Pass RangeOverlap to annotate tokens inside a range.
5544void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5545 RangeComparisonResult compResult,
5546 SourceRange range) {
5547 while (MoreTokens()) {
5548 const unsigned I = NextToken();
5549 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005550 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5551 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005552
5553 SourceLocation TokLoc = GetTokenLoc(I);
5554 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005555 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 AdvanceToken();
5557 continue;
5558 }
5559 break;
5560 }
5561}
5562
5563/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005564/// \returns true if it advanced beyond all macro tokens, false otherwise.
5565bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005566 CXCursor updateC,
5567 RangeComparisonResult compResult,
5568 SourceRange range) {
5569 assert(MoreTokens());
5570 assert(isFunctionMacroToken(NextToken()) &&
5571 "Should be called only for macro arg tokens");
5572
5573 // This works differently than annotateAndAdvanceTokens; because expanded
5574 // macro arguments can have arbitrary translation-unit source order, we do not
5575 // advance the token index one by one until a token fails the range test.
5576 // We only advance once past all of the macro arg tokens if all of them
5577 // pass the range test. If one of them fails we keep the token index pointing
5578 // at the start of the macro arg tokens so that the failing token will be
5579 // annotated by a subsequent annotation try.
5580
5581 bool atLeastOneCompFail = false;
5582
5583 unsigned I = NextToken();
5584 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5585 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5586 if (TokLoc.isFileID())
5587 continue; // not macro arg token, it's parens or comma.
5588 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5589 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5590 Cursors[I] = updateC;
5591 } else
5592 atLeastOneCompFail = true;
5593 }
5594
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005595 if (atLeastOneCompFail)
5596 return false;
5597
5598 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5599 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005600}
5601
5602enum CXChildVisitResult
5603AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005604 SourceRange cursorRange = getRawCursorExtent(cursor);
5605 if (cursorRange.isInvalid())
5606 return CXChildVisit_Recurse;
5607
5608 if (!HasContextSensitiveKeywords) {
5609 // Objective-C properties can have context-sensitive keywords.
5610 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005611 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005612 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5613 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5614 }
5615 // Objective-C methods can have context-sensitive keywords.
5616 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5617 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005618 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005619 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5620 if (Method->getObjCDeclQualifier())
5621 HasContextSensitiveKeywords = true;
5622 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005623 for (const auto *P : Method->params()) {
5624 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 HasContextSensitiveKeywords = true;
5626 break;
5627 }
5628 }
5629 }
5630 }
5631 }
5632 // C++ methods can have context-sensitive keywords.
5633 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005634 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5636 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5637 HasContextSensitiveKeywords = true;
5638 }
5639 }
5640 // C++ classes can have context-sensitive keywords.
5641 else if (cursor.kind == CXCursor_StructDecl ||
5642 cursor.kind == CXCursor_ClassDecl ||
5643 cursor.kind == CXCursor_ClassTemplate ||
5644 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005645 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 if (D->hasAttr<FinalAttr>())
5647 HasContextSensitiveKeywords = true;
5648 }
5649 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005650
5651 // Don't override a property annotation with its getter/setter method.
5652 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5653 parent.kind == CXCursor_ObjCPropertyDecl)
5654 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005655
5656 if (clang_isPreprocessing(cursor.kind)) {
5657 // Items in the preprocessing record are kept separate from items in
5658 // declarations, so we keep a separate token index.
5659 unsigned SavedTokIdx = TokIdx;
5660 TokIdx = PreprocessingTokIdx;
5661
5662 // Skip tokens up until we catch up to the beginning of the preprocessing
5663 // entry.
5664 while (MoreTokens()) {
5665 const unsigned I = NextToken();
5666 SourceLocation TokLoc = GetTokenLoc(I);
5667 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5668 case RangeBefore:
5669 AdvanceToken();
5670 continue;
5671 case RangeAfter:
5672 case RangeOverlap:
5673 break;
5674 }
5675 break;
5676 }
5677
5678 // Look at all of the tokens within this range.
5679 while (MoreTokens()) {
5680 const unsigned I = NextToken();
5681 SourceLocation TokLoc = GetTokenLoc(I);
5682 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5683 case RangeBefore:
5684 llvm_unreachable("Infeasible");
5685 case RangeAfter:
5686 break;
5687 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005688 // For macro expansions, just note where the beginning of the macro
5689 // expansion occurs.
5690 if (cursor.kind == CXCursor_MacroExpansion) {
5691 if (TokLoc == cursorRange.getBegin())
5692 Cursors[I] = cursor;
5693 AdvanceToken();
5694 break;
5695 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005696 // We may have already annotated macro names inside macro definitions.
5697 if (Cursors[I].kind != CXCursor_MacroExpansion)
5698 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005700 continue;
5701 }
5702 break;
5703 }
5704
5705 // Save the preprocessing token index; restore the non-preprocessing
5706 // token index.
5707 PreprocessingTokIdx = TokIdx;
5708 TokIdx = SavedTokIdx;
5709 return CXChildVisit_Recurse;
5710 }
5711
5712 if (cursorRange.isInvalid())
5713 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005714
5715 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005716 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005717 const enum CXCursorKind K = clang_getCursorKind(parent);
5718 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005719 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5720 // Attributes are annotated out-of-order, skip tokens until we reach it.
5721 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 ? clang_getNullCursor() : parent;
5723
5724 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5725
5726 // Avoid having the cursor of an expression "overwrite" the annotation of the
5727 // variable declaration that it belongs to.
5728 // This can happen for C++ constructor expressions whose range generally
5729 // include the variable declaration, e.g.:
5730 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005731 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005732 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005733 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 const unsigned I = NextToken();
5735 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5736 E->getLocStart() == D->getLocation() &&
5737 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005738 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005739 AdvanceToken();
5740 }
5741 }
5742 }
5743
5744 // Before recursing into the children keep some state that we are going
5745 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5746 // extra work after the child nodes are visited.
5747 // Note that we don't call VisitChildren here to avoid traversing statements
5748 // code-recursively which can blow the stack.
5749
5750 PostChildrenInfo Info;
5751 Info.Cursor = cursor;
5752 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005753 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005754 Info.BeforeChildrenTokenIdx = NextToken();
5755 PostChildrenInfos.push_back(Info);
5756
5757 return CXChildVisit_Recurse;
5758}
5759
5760bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5761 if (PostChildrenInfos.empty())
5762 return false;
5763 const PostChildrenInfo &Info = PostChildrenInfos.back();
5764 if (!clang_equalCursors(Info.Cursor, cursor))
5765 return false;
5766
5767 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5768 const unsigned AfterChildren = NextToken();
5769 SourceRange cursorRange = Info.CursorRange;
5770
5771 // Scan the tokens that are at the end of the cursor, but are not captured
5772 // but the child cursors.
5773 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5774
5775 // Scan the tokens that are at the beginning of the cursor, but are not
5776 // capture by the child cursors.
5777 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5778 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5779 break;
5780
5781 Cursors[I] = cursor;
5782 }
5783
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005784 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5785 // encountered the attribute cursor.
5786 if (clang_isAttribute(cursor.kind))
5787 TokIdx = Info.BeforeReachingCursorIdx;
5788
Guy Benyei11169dd2012-12-18 14:30:41 +00005789 PostChildrenInfos.pop_back();
5790 return false;
5791}
5792
5793static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5794 CXCursor parent,
5795 CXClientData client_data) {
5796 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5797}
5798
5799static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5800 CXClientData client_data) {
5801 return static_cast<AnnotateTokensWorker*>(client_data)->
5802 postVisitChildren(cursor);
5803}
5804
5805namespace {
5806
5807/// \brief Uses the macro expansions in the preprocessing record to find
5808/// and mark tokens that are macro arguments. This info is used by the
5809/// AnnotateTokensWorker.
5810class MarkMacroArgTokensVisitor {
5811 SourceManager &SM;
5812 CXToken *Tokens;
5813 unsigned NumTokens;
5814 unsigned CurIdx;
5815
5816public:
5817 MarkMacroArgTokensVisitor(SourceManager &SM,
5818 CXToken *tokens, unsigned numTokens)
5819 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5820
5821 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5822 if (cursor.kind != CXCursor_MacroExpansion)
5823 return CXChildVisit_Continue;
5824
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005825 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005826 if (macroRange.getBegin() == macroRange.getEnd())
5827 return CXChildVisit_Continue; // it's not a function macro.
5828
5829 for (; CurIdx < NumTokens; ++CurIdx) {
5830 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5831 macroRange.getBegin()))
5832 break;
5833 }
5834
5835 if (CurIdx == NumTokens)
5836 return CXChildVisit_Break;
5837
5838 for (; CurIdx < NumTokens; ++CurIdx) {
5839 SourceLocation tokLoc = getTokenLoc(CurIdx);
5840 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5841 break;
5842
5843 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5844 }
5845
5846 if (CurIdx == NumTokens)
5847 return CXChildVisit_Break;
5848
5849 return CXChildVisit_Continue;
5850 }
5851
5852private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005853 CXToken &getTok(unsigned Idx) {
5854 assert(Idx < NumTokens);
5855 return Tokens[Idx];
5856 }
5857 const CXToken &getTok(unsigned Idx) const {
5858 assert(Idx < NumTokens);
5859 return Tokens[Idx];
5860 }
5861
Guy Benyei11169dd2012-12-18 14:30:41 +00005862 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005863 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005864 }
5865
5866 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5867 // The third field is reserved and currently not used. Use it here
5868 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005869 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005870 }
5871};
5872
5873} // end anonymous namespace
5874
5875static CXChildVisitResult
5876MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5877 CXClientData client_data) {
5878 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5879 parent);
5880}
5881
5882namespace {
5883 struct clang_annotateTokens_Data {
5884 CXTranslationUnit TU;
5885 ASTUnit *CXXUnit;
5886 CXToken *Tokens;
5887 unsigned NumTokens;
5888 CXCursor *Cursors;
5889 };
5890}
5891
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005892/// \brief Used by \c annotatePreprocessorTokens.
5893/// \returns true if lexing was finished, false otherwise.
5894static bool lexNext(Lexer &Lex, Token &Tok,
5895 unsigned &NextIdx, unsigned NumTokens) {
5896 if (NextIdx >= NumTokens)
5897 return true;
5898
5899 ++NextIdx;
5900 Lex.LexFromRawLexer(Tok);
5901 if (Tok.is(tok::eof))
5902 return true;
5903
5904 return false;
5905}
5906
Guy Benyei11169dd2012-12-18 14:30:41 +00005907static void annotatePreprocessorTokens(CXTranslationUnit TU,
5908 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005909 CXCursor *Cursors,
5910 CXToken *Tokens,
5911 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005912 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005913
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005914 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005915 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5916 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005917 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005918 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005919 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005920
5921 if (BeginLocInfo.first != EndLocInfo.first)
5922 return;
5923
5924 StringRef Buffer;
5925 bool Invalid = false;
5926 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5927 if (Buffer.empty() || Invalid)
5928 return;
5929
5930 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5931 CXXUnit->getASTContext().getLangOpts(),
5932 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5933 Buffer.end());
5934 Lex.SetCommentRetentionState(true);
5935
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005936 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005937 // Lex tokens in raw mode until we hit the end of the range, to avoid
5938 // entering #includes or expanding macros.
5939 while (true) {
5940 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005941 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5942 break;
5943 unsigned TokIdx = NextIdx-1;
5944 assert(Tok.getLocation() ==
5945 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005946
5947 reprocess:
5948 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005949 // We have found a preprocessing directive. Annotate the tokens
5950 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005951 //
5952 // FIXME: Some simple tests here could identify macro definitions and
5953 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005954
5955 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005956 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5957 break;
5958
Craig Topper69186e72014-06-08 08:38:04 +00005959 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005960 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005961 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5962 break;
5963
5964 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005965 IdentifierInfo &II =
5966 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005967 SourceLocation MappedTokLoc =
5968 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5969 MI = getMacroInfo(II, MappedTokLoc, TU);
5970 }
5971 }
5972
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005973 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005974 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005975 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5976 finished = true;
5977 break;
5978 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005979 // If we are in a macro definition, check if the token was ever a
5980 // macro name and annotate it if that's the case.
5981 if (MI) {
5982 SourceLocation SaveLoc = Tok.getLocation();
5983 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5984 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5985 Tok.setLocation(SaveLoc);
5986 if (MacroDef)
5987 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5988 Tok.getLocation(), TU);
5989 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005990 } while (!Tok.isAtStartOfLine());
5991
5992 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5993 assert(TokIdx <= LastIdx);
5994 SourceLocation EndLoc =
5995 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5996 CXCursor Cursor =
5997 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5998
5999 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006000 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006001
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006002 if (finished)
6003 break;
6004 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006005 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006006 }
6007}
6008
6009// This gets run a separate thread to avoid stack blowout.
6010static void clang_annotateTokensImpl(void *UserData) {
6011 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6012 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6013 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6014 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6015 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6016
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006017 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6019 setThreadBackgroundPriority();
6020
6021 // Determine the region of interest, which contains all of the tokens.
6022 SourceRange RegionOfInterest;
6023 RegionOfInterest.setBegin(
6024 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6025 RegionOfInterest.setEnd(
6026 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6027 Tokens[NumTokens-1])));
6028
Guy Benyei11169dd2012-12-18 14:30:41 +00006029 // Relex the tokens within the source range to look for preprocessing
6030 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006031 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006032
6033 // If begin location points inside a macro argument, set it to the expansion
6034 // location so we can have the full context when annotating semantically.
6035 {
6036 SourceManager &SM = CXXUnit->getSourceManager();
6037 SourceLocation Loc =
6038 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6039 if (Loc.isMacroID())
6040 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6041 }
6042
Guy Benyei11169dd2012-12-18 14:30:41 +00006043 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6044 // Search and mark tokens that are macro argument expansions.
6045 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6046 Tokens, NumTokens);
6047 CursorVisitor MacroArgMarker(TU,
6048 MarkMacroArgTokensVisitorDelegate, &Visitor,
6049 /*VisitPreprocessorLast=*/true,
6050 /*VisitIncludedEntities=*/false,
6051 RegionOfInterest);
6052 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6053 }
6054
6055 // Annotate all of the source locations in the region of interest that map to
6056 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006057 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006058
6059 // FIXME: We use a ridiculous stack size here because the data-recursion
6060 // algorithm uses a large stack frame than the non-data recursive version,
6061 // and AnnotationTokensWorker currently transforms the data-recursion
6062 // algorithm back into a traditional recursion by explicitly calling
6063 // VisitChildren(). We will need to remove this explicit recursive call.
6064 W.AnnotateTokens();
6065
6066 // If we ran into any entities that involve context-sensitive keywords,
6067 // take another pass through the tokens to mark them as such.
6068 if (W.hasContextSensitiveKeywords()) {
6069 for (unsigned I = 0; I != NumTokens; ++I) {
6070 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6071 continue;
6072
6073 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6074 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006075 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006076 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6077 if (Property->getPropertyAttributesAsWritten() != 0 &&
6078 llvm::StringSwitch<bool>(II->getName())
6079 .Case("readonly", true)
6080 .Case("assign", true)
6081 .Case("unsafe_unretained", true)
6082 .Case("readwrite", true)
6083 .Case("retain", true)
6084 .Case("copy", true)
6085 .Case("nonatomic", true)
6086 .Case("atomic", true)
6087 .Case("getter", true)
6088 .Case("setter", true)
6089 .Case("strong", true)
6090 .Case("weak", true)
6091 .Default(false))
6092 Tokens[I].int_data[0] = CXToken_Keyword;
6093 }
6094 continue;
6095 }
6096
6097 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6098 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6099 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6100 if (llvm::StringSwitch<bool>(II->getName())
6101 .Case("in", true)
6102 .Case("out", true)
6103 .Case("inout", true)
6104 .Case("oneway", true)
6105 .Case("bycopy", true)
6106 .Case("byref", true)
6107 .Default(false))
6108 Tokens[I].int_data[0] = CXToken_Keyword;
6109 continue;
6110 }
6111
6112 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6113 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6114 Tokens[I].int_data[0] = CXToken_Keyword;
6115 continue;
6116 }
6117 }
6118 }
6119}
6120
6121extern "C" {
6122
6123void clang_annotateTokens(CXTranslationUnit TU,
6124 CXToken *Tokens, unsigned NumTokens,
6125 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006126 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006127 LOG_BAD_TU(TU);
6128 return;
6129 }
6130 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006131 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006132 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006133 }
6134
6135 LOG_FUNC_SECTION {
6136 *Log << TU << ' ';
6137 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6138 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6139 *Log << clang_getRange(bloc, eloc);
6140 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006141
6142 // Any token we don't specifically annotate will have a NULL cursor.
6143 CXCursor C = clang_getNullCursor();
6144 for (unsigned I = 0; I != NumTokens; ++I)
6145 Cursors[I] = C;
6146
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006147 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006148 if (!CXXUnit)
6149 return;
6150
6151 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6152
6153 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6154 llvm::CrashRecoveryContext CRC;
6155 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6156 GetSafetyThreadStackSize() * 2)) {
6157 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6158 }
6159}
6160
6161} // end: extern "C"
6162
6163//===----------------------------------------------------------------------===//
6164// Operations for querying linkage of a cursor.
6165//===----------------------------------------------------------------------===//
6166
6167extern "C" {
6168CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6169 if (!clang_isDeclaration(cursor.kind))
6170 return CXLinkage_Invalid;
6171
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006172 const Decl *D = cxcursor::getCursorDecl(cursor);
6173 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006174 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006175 case NoLinkage:
6176 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006177 case InternalLinkage: return CXLinkage_Internal;
6178 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6179 case ExternalLinkage: return CXLinkage_External;
6180 };
6181
6182 return CXLinkage_Invalid;
6183}
6184} // end: extern "C"
6185
6186//===----------------------------------------------------------------------===//
6187// Operations for querying language of a cursor.
6188//===----------------------------------------------------------------------===//
6189
6190static CXLanguageKind getDeclLanguage(const Decl *D) {
6191 if (!D)
6192 return CXLanguage_C;
6193
6194 switch (D->getKind()) {
6195 default:
6196 break;
6197 case Decl::ImplicitParam:
6198 case Decl::ObjCAtDefsField:
6199 case Decl::ObjCCategory:
6200 case Decl::ObjCCategoryImpl:
6201 case Decl::ObjCCompatibleAlias:
6202 case Decl::ObjCImplementation:
6203 case Decl::ObjCInterface:
6204 case Decl::ObjCIvar:
6205 case Decl::ObjCMethod:
6206 case Decl::ObjCProperty:
6207 case Decl::ObjCPropertyImpl:
6208 case Decl::ObjCProtocol:
6209 return CXLanguage_ObjC;
6210 case Decl::CXXConstructor:
6211 case Decl::CXXConversion:
6212 case Decl::CXXDestructor:
6213 case Decl::CXXMethod:
6214 case Decl::CXXRecord:
6215 case Decl::ClassTemplate:
6216 case Decl::ClassTemplatePartialSpecialization:
6217 case Decl::ClassTemplateSpecialization:
6218 case Decl::Friend:
6219 case Decl::FriendTemplate:
6220 case Decl::FunctionTemplate:
6221 case Decl::LinkageSpec:
6222 case Decl::Namespace:
6223 case Decl::NamespaceAlias:
6224 case Decl::NonTypeTemplateParm:
6225 case Decl::StaticAssert:
6226 case Decl::TemplateTemplateParm:
6227 case Decl::TemplateTypeParm:
6228 case Decl::UnresolvedUsingTypename:
6229 case Decl::UnresolvedUsingValue:
6230 case Decl::Using:
6231 case Decl::UsingDirective:
6232 case Decl::UsingShadow:
6233 return CXLanguage_CPlusPlus;
6234 }
6235
6236 return CXLanguage_C;
6237}
6238
6239extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006240
6241static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6242 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6243 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006244
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006245 switch (D->getAvailability()) {
6246 case AR_Available:
6247 case AR_NotYetIntroduced:
6248 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006249 return getCursorAvailabilityForDecl(
6250 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006251 return CXAvailability_Available;
6252
6253 case AR_Deprecated:
6254 return CXAvailability_Deprecated;
6255
6256 case AR_Unavailable:
6257 return CXAvailability_NotAvailable;
6258 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006259
6260 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006261}
6262
Guy Benyei11169dd2012-12-18 14:30:41 +00006263enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6264 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006265 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6266 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006267
6268 return CXAvailability_Available;
6269}
6270
6271static CXVersion convertVersion(VersionTuple In) {
6272 CXVersion Out = { -1, -1, -1 };
6273 if (In.empty())
6274 return Out;
6275
6276 Out.Major = In.getMajor();
6277
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006278 Optional<unsigned> Minor = In.getMinor();
6279 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006280 Out.Minor = *Minor;
6281 else
6282 return Out;
6283
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006284 Optional<unsigned> Subminor = In.getSubminor();
6285 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006286 Out.Subminor = *Subminor;
6287
6288 return Out;
6289}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006290
6291static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6292 int *always_deprecated,
6293 CXString *deprecated_message,
6294 int *always_unavailable,
6295 CXString *unavailable_message,
6296 CXPlatformAvailability *availability,
6297 int availability_size) {
6298 bool HadAvailAttr = false;
6299 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006300 for (auto A : D->attrs()) {
6301 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006302 HadAvailAttr = true;
6303 if (always_deprecated)
6304 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006305 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006306 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006307 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006308 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006309 continue;
6310 }
6311
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006312 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006313 HadAvailAttr = true;
6314 if (always_unavailable)
6315 *always_unavailable = 1;
6316 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006317 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006318 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6319 }
6320 continue;
6321 }
6322
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006323 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006324 HadAvailAttr = true;
6325 if (N < availability_size) {
6326 availability[N].Platform
6327 = cxstring::createDup(Avail->getPlatform()->getName());
6328 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6329 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6330 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6331 availability[N].Unavailable = Avail->getUnavailable();
6332 availability[N].Message = cxstring::createDup(Avail->getMessage());
6333 }
6334 ++N;
6335 }
6336 }
6337
6338 if (!HadAvailAttr)
6339 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6340 return getCursorPlatformAvailabilityForDecl(
6341 cast<Decl>(EnumConst->getDeclContext()),
6342 always_deprecated,
6343 deprecated_message,
6344 always_unavailable,
6345 unavailable_message,
6346 availability,
6347 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006348
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006349 return N;
6350}
6351
Guy Benyei11169dd2012-12-18 14:30:41 +00006352int clang_getCursorPlatformAvailability(CXCursor cursor,
6353 int *always_deprecated,
6354 CXString *deprecated_message,
6355 int *always_unavailable,
6356 CXString *unavailable_message,
6357 CXPlatformAvailability *availability,
6358 int availability_size) {
6359 if (always_deprecated)
6360 *always_deprecated = 0;
6361 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006362 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006363 if (always_unavailable)
6364 *always_unavailable = 0;
6365 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006366 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006367
Guy Benyei11169dd2012-12-18 14:30:41 +00006368 if (!clang_isDeclaration(cursor.kind))
6369 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006370
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006371 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006372 if (!D)
6373 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006374
6375 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6376 deprecated_message,
6377 always_unavailable,
6378 unavailable_message,
6379 availability,
6380 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006381}
6382
6383void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6384 clang_disposeString(availability->Platform);
6385 clang_disposeString(availability->Message);
6386}
6387
6388CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6389 if (clang_isDeclaration(cursor.kind))
6390 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6391
6392 return CXLanguage_Invalid;
6393}
6394
6395 /// \brief If the given cursor is the "templated" declaration
6396 /// descibing a class or function template, return the class or
6397 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006398static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006399 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006400 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006401
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006402 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006403 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6404 return FunTmpl;
6405
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006406 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006407 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6408 return ClassTmpl;
6409
6410 return D;
6411}
6412
6413CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6414 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006415 if (const Decl *D = getCursorDecl(cursor)) {
6416 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006417 if (!DC)
6418 return clang_getNullCursor();
6419
6420 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6421 getCursorTU(cursor));
6422 }
6423 }
6424
6425 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006426 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006427 return MakeCXCursor(D, getCursorTU(cursor));
6428 }
6429
6430 return clang_getNullCursor();
6431}
6432
6433CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6434 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006435 if (const Decl *D = getCursorDecl(cursor)) {
6436 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006437 if (!DC)
6438 return clang_getNullCursor();
6439
6440 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6441 getCursorTU(cursor));
6442 }
6443 }
6444
6445 // FIXME: Note that we can't easily compute the lexical context of a
6446 // statement or expression, so we return nothing.
6447 return clang_getNullCursor();
6448}
6449
6450CXFile clang_getIncludedFile(CXCursor cursor) {
6451 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006452 return nullptr;
6453
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006454 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006455 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006456}
6457
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006458unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6459 if (C.kind != CXCursor_ObjCPropertyDecl)
6460 return CXObjCPropertyAttr_noattr;
6461
6462 unsigned Result = CXObjCPropertyAttr_noattr;
6463 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6464 ObjCPropertyDecl::PropertyAttributeKind Attr =
6465 PD->getPropertyAttributesAsWritten();
6466
6467#define SET_CXOBJCPROP_ATTR(A) \
6468 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6469 Result |= CXObjCPropertyAttr_##A
6470 SET_CXOBJCPROP_ATTR(readonly);
6471 SET_CXOBJCPROP_ATTR(getter);
6472 SET_CXOBJCPROP_ATTR(assign);
6473 SET_CXOBJCPROP_ATTR(readwrite);
6474 SET_CXOBJCPROP_ATTR(retain);
6475 SET_CXOBJCPROP_ATTR(copy);
6476 SET_CXOBJCPROP_ATTR(nonatomic);
6477 SET_CXOBJCPROP_ATTR(setter);
6478 SET_CXOBJCPROP_ATTR(atomic);
6479 SET_CXOBJCPROP_ATTR(weak);
6480 SET_CXOBJCPROP_ATTR(strong);
6481 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6482#undef SET_CXOBJCPROP_ATTR
6483
6484 return Result;
6485}
6486
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006487unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6488 if (!clang_isDeclaration(C.kind))
6489 return CXObjCDeclQualifier_None;
6490
6491 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6492 const Decl *D = getCursorDecl(C);
6493 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6494 QT = MD->getObjCDeclQualifier();
6495 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6496 QT = PD->getObjCDeclQualifier();
6497 if (QT == Decl::OBJC_TQ_None)
6498 return CXObjCDeclQualifier_None;
6499
6500 unsigned Result = CXObjCDeclQualifier_None;
6501 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6502 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6503 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6504 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6505 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6506 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6507
6508 return Result;
6509}
6510
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006511unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6512 if (!clang_isDeclaration(C.kind))
6513 return 0;
6514
6515 const Decl *D = getCursorDecl(C);
6516 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6517 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6518 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6519 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6520
6521 return 0;
6522}
6523
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006524unsigned clang_Cursor_isVariadic(CXCursor C) {
6525 if (!clang_isDeclaration(C.kind))
6526 return 0;
6527
6528 const Decl *D = getCursorDecl(C);
6529 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6530 return FD->isVariadic();
6531 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6532 return MD->isVariadic();
6533
6534 return 0;
6535}
6536
Guy Benyei11169dd2012-12-18 14:30:41 +00006537CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6538 if (!clang_isDeclaration(C.kind))
6539 return clang_getNullRange();
6540
6541 const Decl *D = getCursorDecl(C);
6542 ASTContext &Context = getCursorContext(C);
6543 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6544 if (!RC)
6545 return clang_getNullRange();
6546
6547 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6548}
6549
6550CXString clang_Cursor_getRawCommentText(CXCursor C) {
6551 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006552 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006553
6554 const Decl *D = getCursorDecl(C);
6555 ASTContext &Context = getCursorContext(C);
6556 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6557 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6558 StringRef();
6559
6560 // Don't duplicate the string because RawText points directly into source
6561 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006562 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006563}
6564
6565CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6566 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006567 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006568
6569 const Decl *D = getCursorDecl(C);
6570 const ASTContext &Context = getCursorContext(C);
6571 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6572
6573 if (RC) {
6574 StringRef BriefText = RC->getBriefText(Context);
6575
6576 // Don't duplicate the string because RawComment ensures that this memory
6577 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006578 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006579 }
6580
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006581 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006582}
6583
Guy Benyei11169dd2012-12-18 14:30:41 +00006584CXModule clang_Cursor_getModule(CXCursor C) {
6585 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006586 if (const ImportDecl *ImportD =
6587 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006588 return ImportD->getImportedModule();
6589 }
6590
Craig Topper69186e72014-06-08 08:38:04 +00006591 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006592}
6593
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006594CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6595 if (isNotUsableTU(TU)) {
6596 LOG_BAD_TU(TU);
6597 return nullptr;
6598 }
6599 if (!File)
6600 return nullptr;
6601 FileEntry *FE = static_cast<FileEntry *>(File);
6602
6603 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6604 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6605 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6606
6607 if (Module *Mod = Header.getModule()) {
6608 if (Header.getRole() != ModuleMap::ExcludedHeader)
6609 return Mod;
6610 }
6611 return nullptr;
6612}
6613
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006614CXFile clang_Module_getASTFile(CXModule CXMod) {
6615 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006616 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006617 Module *Mod = static_cast<Module*>(CXMod);
6618 return const_cast<FileEntry *>(Mod->getASTFile());
6619}
6620
Guy Benyei11169dd2012-12-18 14:30:41 +00006621CXModule clang_Module_getParent(CXModule CXMod) {
6622 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006623 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006624 Module *Mod = static_cast<Module*>(CXMod);
6625 return Mod->Parent;
6626}
6627
6628CXString clang_Module_getName(CXModule CXMod) {
6629 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006630 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006631 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006632 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006633}
6634
6635CXString clang_Module_getFullName(CXModule CXMod) {
6636 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006637 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006638 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006639 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006640}
6641
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006642int clang_Module_isSystem(CXModule CXMod) {
6643 if (!CXMod)
6644 return 0;
6645 Module *Mod = static_cast<Module*>(CXMod);
6646 return Mod->IsSystem;
6647}
6648
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006649unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6650 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006651 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006652 LOG_BAD_TU(TU);
6653 return 0;
6654 }
6655 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006656 return 0;
6657 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006658 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6659 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6660 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006661}
6662
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006663CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6664 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006665 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006666 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006667 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006668 }
6669 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006670 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006671 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006672 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006673
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006674 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6675 if (Index < TopHeaders.size())
6676 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006677
Craig Topper69186e72014-06-08 08:38:04 +00006678 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006679}
6680
6681} // end: extern "C"
6682
6683//===----------------------------------------------------------------------===//
6684// C++ AST instrospection.
6685//===----------------------------------------------------------------------===//
6686
6687extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006688unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6689 if (!clang_isDeclaration(C.kind))
6690 return 0;
6691
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006692 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006693 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006694 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006695 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6696}
6697
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006698unsigned clang_CXXMethod_isConst(CXCursor C) {
6699 if (!clang_isDeclaration(C.kind))
6700 return 0;
6701
6702 const Decl *D = cxcursor::getCursorDecl(C);
6703 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006704 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006705 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6706}
6707
Guy Benyei11169dd2012-12-18 14:30:41 +00006708unsigned clang_CXXMethod_isStatic(CXCursor C) {
6709 if (!clang_isDeclaration(C.kind))
6710 return 0;
6711
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006712 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006713 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006714 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006715 return (Method && Method->isStatic()) ? 1 : 0;
6716}
6717
6718unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6719 if (!clang_isDeclaration(C.kind))
6720 return 0;
6721
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006722 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006723 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006724 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006725 return (Method && Method->isVirtual()) ? 1 : 0;
6726}
6727} // end: extern "C"
6728
6729//===----------------------------------------------------------------------===//
6730// Attribute introspection.
6731//===----------------------------------------------------------------------===//
6732
6733extern "C" {
6734CXType clang_getIBOutletCollectionType(CXCursor C) {
6735 if (C.kind != CXCursor_IBOutletCollectionAttr)
6736 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6737
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006738 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006739 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6740
6741 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6742}
6743} // end: extern "C"
6744
6745//===----------------------------------------------------------------------===//
6746// Inspecting memory usage.
6747//===----------------------------------------------------------------------===//
6748
6749typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6750
6751static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6752 enum CXTUResourceUsageKind k,
6753 unsigned long amount) {
6754 CXTUResourceUsageEntry entry = { k, amount };
6755 entries.push_back(entry);
6756}
6757
6758extern "C" {
6759
6760const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6761 const char *str = "";
6762 switch (kind) {
6763 case CXTUResourceUsage_AST:
6764 str = "ASTContext: expressions, declarations, and types";
6765 break;
6766 case CXTUResourceUsage_Identifiers:
6767 str = "ASTContext: identifiers";
6768 break;
6769 case CXTUResourceUsage_Selectors:
6770 str = "ASTContext: selectors";
6771 break;
6772 case CXTUResourceUsage_GlobalCompletionResults:
6773 str = "Code completion: cached global results";
6774 break;
6775 case CXTUResourceUsage_SourceManagerContentCache:
6776 str = "SourceManager: content cache allocator";
6777 break;
6778 case CXTUResourceUsage_AST_SideTables:
6779 str = "ASTContext: side tables";
6780 break;
6781 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6782 str = "SourceManager: malloc'ed memory buffers";
6783 break;
6784 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6785 str = "SourceManager: mmap'ed memory buffers";
6786 break;
6787 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6788 str = "ExternalASTSource: malloc'ed memory buffers";
6789 break;
6790 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6791 str = "ExternalASTSource: mmap'ed memory buffers";
6792 break;
6793 case CXTUResourceUsage_Preprocessor:
6794 str = "Preprocessor: malloc'ed memory";
6795 break;
6796 case CXTUResourceUsage_PreprocessingRecord:
6797 str = "Preprocessor: PreprocessingRecord";
6798 break;
6799 case CXTUResourceUsage_SourceManager_DataStructures:
6800 str = "SourceManager: data structures and tables";
6801 break;
6802 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6803 str = "Preprocessor: header search tables";
6804 break;
6805 }
6806 return str;
6807}
6808
6809CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006810 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006811 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006812 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006813 return usage;
6814 }
6815
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006816 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006817 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006818 ASTContext &astContext = astUnit->getASTContext();
6819
6820 // How much memory is used by AST nodes and types?
6821 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6822 (unsigned long) astContext.getASTAllocatedMemory());
6823
6824 // How much memory is used by identifiers?
6825 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6826 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6827
6828 // How much memory is used for selectors?
6829 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6830 (unsigned long) astContext.Selectors.getTotalMemory());
6831
6832 // How much memory is used by ASTContext's side tables?
6833 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6834 (unsigned long) astContext.getSideTableAllocatedMemory());
6835
6836 // How much memory is used for caching global code completion results?
6837 unsigned long completionBytes = 0;
6838 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006839 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006840 completionBytes = completionAllocator->getTotalMemory();
6841 }
6842 createCXTUResourceUsageEntry(*entries,
6843 CXTUResourceUsage_GlobalCompletionResults,
6844 completionBytes);
6845
6846 // How much memory is being used by SourceManager's content cache?
6847 createCXTUResourceUsageEntry(*entries,
6848 CXTUResourceUsage_SourceManagerContentCache,
6849 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6850
6851 // How much memory is being used by the MemoryBuffer's in SourceManager?
6852 const SourceManager::MemoryBufferSizes &srcBufs =
6853 astUnit->getSourceManager().getMemoryBufferSizes();
6854
6855 createCXTUResourceUsageEntry(*entries,
6856 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6857 (unsigned long) srcBufs.malloc_bytes);
6858 createCXTUResourceUsageEntry(*entries,
6859 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6860 (unsigned long) srcBufs.mmap_bytes);
6861 createCXTUResourceUsageEntry(*entries,
6862 CXTUResourceUsage_SourceManager_DataStructures,
6863 (unsigned long) astContext.getSourceManager()
6864 .getDataStructureSizes());
6865
6866 // How much memory is being used by the ExternalASTSource?
6867 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6868 const ExternalASTSource::MemoryBufferSizes &sizes =
6869 esrc->getMemoryBufferSizes();
6870
6871 createCXTUResourceUsageEntry(*entries,
6872 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6873 (unsigned long) sizes.malloc_bytes);
6874 createCXTUResourceUsageEntry(*entries,
6875 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6876 (unsigned long) sizes.mmap_bytes);
6877 }
6878
6879 // How much memory is being used by the Preprocessor?
6880 Preprocessor &pp = astUnit->getPreprocessor();
6881 createCXTUResourceUsageEntry(*entries,
6882 CXTUResourceUsage_Preprocessor,
6883 pp.getTotalMemory());
6884
6885 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6886 createCXTUResourceUsageEntry(*entries,
6887 CXTUResourceUsage_PreprocessingRecord,
6888 pRec->getTotalMemory());
6889 }
6890
6891 createCXTUResourceUsageEntry(*entries,
6892 CXTUResourceUsage_Preprocessor_HeaderSearch,
6893 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006894
Guy Benyei11169dd2012-12-18 14:30:41 +00006895 CXTUResourceUsage usage = { (void*) entries.get(),
6896 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006897 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006898 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006899 return usage;
6900}
6901
6902void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6903 if (usage.data)
6904 delete (MemUsageEntries*) usage.data;
6905}
6906
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006907CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6908 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006909 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006910 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006911
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006912 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006913 LOG_BAD_TU(TU);
6914 return skipped;
6915 }
6916
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006917 if (!file)
6918 return skipped;
6919
6920 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6921 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6922 if (!ppRec)
6923 return skipped;
6924
6925 ASTContext &Ctx = astUnit->getASTContext();
6926 SourceManager &sm = Ctx.getSourceManager();
6927 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6928 FileID wantedFileID = sm.translateFile(fileEntry);
6929
6930 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6931 std::vector<SourceRange> wantedRanges;
6932 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6933 i != ei; ++i) {
6934 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6935 wantedRanges.push_back(*i);
6936 }
6937
6938 skipped->count = wantedRanges.size();
6939 skipped->ranges = new CXSourceRange[skipped->count];
6940 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6941 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6942
6943 return skipped;
6944}
6945
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006946void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6947 if (ranges) {
6948 delete[] ranges->ranges;
6949 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006950 }
6951}
6952
Guy Benyei11169dd2012-12-18 14:30:41 +00006953} // end extern "C"
6954
6955void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6956 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6957 for (unsigned I = 0; I != Usage.numEntries; ++I)
6958 fprintf(stderr, " %s: %lu\n",
6959 clang_getTUResourceUsageName(Usage.entries[I].kind),
6960 Usage.entries[I].amount);
6961
6962 clang_disposeCXTUResourceUsage(Usage);
6963}
6964
6965//===----------------------------------------------------------------------===//
6966// Misc. utility functions.
6967//===----------------------------------------------------------------------===//
6968
6969/// Default to using an 8 MB stack size on "safety" threads.
6970static unsigned SafetyStackThreadSize = 8 << 20;
6971
6972namespace clang {
6973
6974bool RunSafely(llvm::CrashRecoveryContext &CRC,
6975 void (*Fn)(void*), void *UserData,
6976 unsigned Size) {
6977 if (!Size)
6978 Size = GetSafetyThreadStackSize();
6979 if (Size)
6980 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6981 return CRC.RunSafely(Fn, UserData);
6982}
6983
6984unsigned GetSafetyThreadStackSize() {
6985 return SafetyStackThreadSize;
6986}
6987
6988void SetSafetyThreadStackSize(unsigned Value) {
6989 SafetyStackThreadSize = Value;
6990}
6991
6992}
6993
6994void clang::setThreadBackgroundPriority() {
6995 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6996 return;
6997
Alp Toker1a86ad22014-07-06 06:24:00 +00006998#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006999 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7000#endif
7001}
7002
7003void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7004 if (!Unit)
7005 return;
7006
7007 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7008 DEnd = Unit->stored_diag_end();
7009 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007010 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007011 CXString Msg = clang_formatDiagnostic(&Diag,
7012 clang_defaultDiagnosticDisplayOptions());
7013 fprintf(stderr, "%s\n", clang_getCString(Msg));
7014 clang_disposeString(Msg);
7015 }
7016#ifdef LLVM_ON_WIN32
7017 // On Windows, force a flush, since there may be multiple copies of
7018 // stderr and stdout in the file system, all with different buffers
7019 // but writing to the same device.
7020 fflush(stderr);
7021#endif
7022}
7023
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007024MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7025 SourceLocation MacroDefLoc,
7026 CXTranslationUnit TU){
7027 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007028 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007029 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007030 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007031
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007032 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007033 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007034 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007035 if (MD) {
7036 for (MacroDirective::DefInfo
7037 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7038 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7039 return Def.getMacroInfo();
7040 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007041 }
7042
Craig Topper69186e72014-06-08 08:38:04 +00007043 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007044}
7045
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007046const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7047 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007048 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007049 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007050 const IdentifierInfo *II = MacroDef->getName();
7051 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007052 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007053
7054 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7055}
7056
7057MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7058 const Token &Tok,
7059 CXTranslationUnit TU) {
7060 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007061 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007062 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007063 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007064
7065 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007066 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007067 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7068 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007069 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007070
7071 // Check that the token is inside the definition and not its argument list.
7072 SourceManager &SM = Unit->getSourceManager();
7073 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007074 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007075 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007076 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007077
7078 Preprocessor &PP = Unit->getPreprocessor();
7079 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7080 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007081 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007082
Alp Toker2d57cea2014-05-17 04:53:25 +00007083 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007084 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007085 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007086
7087 // Check that the identifier is not one of the macro arguments.
7088 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007089 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007090
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007091 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7092 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007093 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007094
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007095 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007096}
7097
7098MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7099 SourceLocation Loc,
7100 CXTranslationUnit TU) {
7101 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007102 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007103
7104 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007105 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007106 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007107 Preprocessor &PP = Unit->getPreprocessor();
7108 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007109 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007110 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7111 Token Tok;
7112 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007113 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007114
7115 return checkForMacroInMacroDefinition(MI, Tok, TU);
7116}
7117
Guy Benyei11169dd2012-12-18 14:30:41 +00007118extern "C" {
7119
7120CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007121 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007122}
7123
7124} // end: extern "C"
7125
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007126Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7127 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007128 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007129 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007130 if (Unit->isMainFileAST())
7131 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007132 return *this;
7133 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007134 } else {
7135 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007136 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007137 return *this;
7138}
7139
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007140Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7141 *this << FE->getName();
7142 return *this;
7143}
7144
7145Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7146 CXString cursorName = clang_getCursorDisplayName(cursor);
7147 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7148 clang_disposeString(cursorName);
7149 return *this;
7150}
7151
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007152Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7153 CXFile File;
7154 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007155 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007156 CXString FileName = clang_getFileName(File);
7157 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7158 clang_disposeString(FileName);
7159 return *this;
7160}
7161
7162Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7163 CXSourceLocation BLoc = clang_getRangeStart(range);
7164 CXSourceLocation ELoc = clang_getRangeEnd(range);
7165
7166 CXFile BFile;
7167 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007168 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007169
7170 CXFile EFile;
7171 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007172 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007173
7174 CXString BFileName = clang_getFileName(BFile);
7175 if (BFile == EFile) {
7176 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7177 BLine, BColumn, ELine, EColumn);
7178 } else {
7179 CXString EFileName = clang_getFileName(EFile);
7180 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7181 BLine, BColumn)
7182 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7183 ELine, EColumn);
7184 clang_disposeString(EFileName);
7185 }
7186 clang_disposeString(BFileName);
7187 return *this;
7188}
7189
7190Logger &cxindex::Logger::operator<<(CXString Str) {
7191 *this << clang_getCString(Str);
7192 return *this;
7193}
7194
7195Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7196 LogOS << Fmt;
7197 return *this;
7198}
7199
Chandler Carruth37ad2582014-06-27 15:14:39 +00007200static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7201
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007202cxindex::Logger::~Logger() {
7203 LogOS.flush();
7204
Chandler Carruth37ad2582014-06-27 15:14:39 +00007205 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007206
7207 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7208
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007209 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007210 OS << "[libclang:" << Name << ':';
7211
Alp Toker1a86ad22014-07-06 06:24:00 +00007212#ifdef USE_DARWIN_THREADS
7213 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007214 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7215 OS << tid << ':';
7216#endif
7217
7218 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7219 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7220 OS << Msg.str() << '\n';
7221
7222 if (Trace) {
7223 llvm::sys::PrintStackTrace(stderr);
7224 OS << "--------------------------------------------------\n";
7225 }
7226}