blob: 6d241170ca82fa31378730d3abc8c9a4fe98b68d [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
243 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
244 Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
458
459 continue;
460 }
461
462 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
465
466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000572 if (MacroDefinition *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
667bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669 return Visit(TSInfo->getTypeLoc());
670
671 return false;
672}
673
674bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682 return VisitDeclContext(D);
683}
684
685bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686 ClassTemplateSpecializationDecl *D) {
687 bool ShouldVisitBody = false;
688 switch (D->getSpecializationKind()) {
689 case TSK_Undeclared:
690 case TSK_ImplicitInstantiation:
691 // Nothing to visit
692 return false;
693
694 case TSK_ExplicitInstantiationDeclaration:
695 case TSK_ExplicitInstantiationDefinition:
696 break;
697
698 case TSK_ExplicitSpecialization:
699 ShouldVisitBody = true;
700 break;
701 }
702
703 // Visit the template arguments used in the specialization.
704 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000706 if (TemplateSpecializationTypeLoc TSTLoc =
707 TL.getAs<TemplateSpecializationTypeLoc>()) {
708 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000710 return true;
711 }
712 }
713
714 if (ShouldVisitBody && VisitCXXRecordDecl(D))
715 return true;
716
717 return false;
718}
719
720bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721 ClassTemplatePartialSpecializationDecl *D) {
722 // FIXME: Visit the "outer" template parameter lists on the TagDecl
723 // before visiting these template parameters.
724 if (VisitTemplateParameters(D->getTemplateParameters()))
725 return true;
726
727 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000728 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732 return true;
733
734 return VisitCXXRecordDecl(D);
735}
736
737bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738 // Visit the default argument.
739 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741 if (Visit(DefArg->getTypeLoc()))
742 return true;
743
744 return false;
745}
746
747bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748 if (Expr *Init = D->getInitExpr())
749 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750 return false;
751}
752
753bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000754 unsigned NumParamList = DD->getNumTemplateParameterLists();
755 for (unsigned i = 0; i < NumParamList; i++) {
756 TemplateParameterList* Params = DD->getTemplateParameterList(i);
757 if (VisitTemplateParameters(Params))
758 return true;
759 }
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762 if (Visit(TSInfo->getTypeLoc()))
763 return true;
764
765 // Visit the nested-name-specifier, if present.
766 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
768 return true;
769
770 return false;
771}
772
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000773/// \brief Compare two base or member initializers based on their source order.
774static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775 CXXCtorInitializer *const *Y) {
776 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777}
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 unsigned NumParamList = ND->getNumTemplateParameterLists();
781 for (unsigned i = 0; i < NumParamList; i++) {
782 TemplateParameterList* Params = ND->getTemplateParameterList(i);
783 if (VisitTemplateParameters(Params))
784 return true;
785 }
786
Guy Benyei11169dd2012-12-18 14:30:41 +0000787 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788 // Visit the function declaration's syntactic components in the order
789 // written. This requires a bit of work.
790 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000791 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000792
793 // If we have a function declared directly (without the use of a typedef),
794 // visit just the return type. Otherwise, just visit the function's type
795 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000796 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000797 (!FTL && Visit(TL)))
798 return true;
799
800 // Visit the nested-name-specifier, if present.
801 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
803 return true;
804
805 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000806 if (!isa<CXXDestructorDecl>(ND))
807 if (VisitDeclarationNameInfo(ND->getNameInfo()))
808 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000809
810 // FIXME: Visit explicitly-specified template arguments!
811
812 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000813 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 return true;
815
Bill Wendling44426052012-12-20 19:22:21 +0000816 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 }
818
819 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821 // Find the initializers that were written in the source.
822 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 for (auto *I : Constructor->inits()) {
824 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 continue;
826
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 }
829
830 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000831 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832 &CompareCXXCtorInitializers);
833
Guy Benyei11169dd2012-12-18 14:30:41 +0000834 // Visit the initializers in source order
835 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836 CXXCtorInitializer *Init = WrittenInits[I];
837 if (Init->isAnyMemberInitializer()) {
838 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839 Init->getMemberLocation(), TU)))
840 return true;
841 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842 if (Visit(TInfo->getTypeLoc()))
843 return true;
844 }
845
846 // Visit the initializer value.
847 if (Expr *Initializer = Init->getInit())
848 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849 return true;
850 }
851 }
852
853 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854 return true;
855 }
856
857 return false;
858}
859
860bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861 if (VisitDeclaratorDecl(D))
862 return true;
863
864 if (Expr *BitWidth = D->getBitWidth())
865 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871 if (VisitDeclaratorDecl(D))
872 return true;
873
874 if (Expr *Init = D->getInit())
875 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876
877 return false;
878}
879
880bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881 if (VisitDeclaratorDecl(D))
882 return true;
883
884 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885 if (Expr *DefArg = D->getDefaultArgument())
886 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887
888 return false;
889}
890
891bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitFunctionDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901 // FIXME: Visit the "outer" template parameter lists on the TagDecl
902 // before visiting these template parameters.
903 if (VisitTemplateParameters(D->getTemplateParameters()))
904 return true;
905
906 return VisitCXXRecordDecl(D->getTemplatedDecl());
907}
908
909bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914 VisitTemplateArgumentLoc(D->getDefaultArgument()))
915 return true;
916
917 return false;
918}
919
920bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000921 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000922 if (Visit(TSInfo->getTypeLoc()))
923 return true;
924
Aaron Ballman43b68be2014-03-07 17:50:17 +0000925 for (const auto *P : ND->params()) {
926 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000927 return true;
928 }
929
930 if (ND->isThisDeclarationADefinition() &&
931 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
932 return true;
933
934 return false;
935}
936
937template <typename DeclIt>
938static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
939 SourceManager &SM, SourceLocation EndLoc,
940 SmallVectorImpl<Decl *> &Decls) {
941 DeclIt next = *DI_current;
942 while (++next != DE_current) {
943 Decl *D_next = *next;
944 if (!D_next)
945 break;
946 SourceLocation L = D_next->getLocStart();
947 if (!L.isValid())
948 break;
949 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
950 *DI_current = next;
951 Decls.push_back(D_next);
952 continue;
953 }
954 break;
955 }
956}
957
Guy Benyei11169dd2012-12-18 14:30:41 +0000958bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
959 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
960 // an @implementation can lexically contain Decls that are not properly
961 // nested in the AST. When we identify such cases, we need to retrofit
962 // this nesting here.
963 if (!DI_current && !FileDI_current)
964 return VisitDeclContext(D);
965
966 // Scan the Decls that immediately come after the container
967 // in the current DeclContext. If any fall within the
968 // container's lexical region, stash them into a vector
969 // for later processing.
970 SmallVector<Decl *, 24> DeclsInContainer;
971 SourceLocation EndLoc = D->getSourceRange().getEnd();
972 SourceManager &SM = AU->getSourceManager();
973 if (EndLoc.isValid()) {
974 if (DI_current) {
975 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
976 DeclsInContainer);
977 } else {
978 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
979 DeclsInContainer);
980 }
981 }
982
983 // The common case.
984 if (DeclsInContainer.empty())
985 return VisitDeclContext(D);
986
987 // Get all the Decls in the DeclContext, and sort them with the
988 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 for (auto *SubDecl : D->decls()) {
990 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
991 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000992 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000993 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000994 }
995
996 // Now sort the Decls so that they appear in lexical order.
997 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000998 [&SM](Decl *A, Decl *B) {
999 SourceLocation L_A = A->getLocStart();
1000 SourceLocation L_B = B->getLocStart();
1001 assert(L_A.isValid() && L_B.isValid());
1002 return SM.isBeforeInTranslationUnit(L_A, L_B);
1003 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001004
1005 // Now visit the decls.
1006 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1007 E = DeclsInContainer.end(); I != E; ++I) {
1008 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001009 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001010 if (!V.hasValue())
1011 continue;
1012 if (!V.getValue())
1013 return false;
1014 if (Visit(Cursor, true))
1015 return true;
1016 }
1017 return false;
1018}
1019
1020bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1021 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1022 TU)))
1023 return true;
1024
1025 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1026 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1027 E = ND->protocol_end(); I != E; ++I, ++PL)
1028 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1029 return true;
1030
1031 return VisitObjCContainerDecl(ND);
1032}
1033
1034bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1035 if (!PID->isThisDeclarationADefinition())
1036 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1037
1038 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1039 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1040 E = PID->protocol_end(); I != E; ++I, ++PL)
1041 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042 return true;
1043
1044 return VisitObjCContainerDecl(PID);
1045}
1046
1047bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1048 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1049 return true;
1050
1051 // FIXME: This implements a workaround with @property declarations also being
1052 // installed in the DeclContext for the @interface. Eventually this code
1053 // should be removed.
1054 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1055 if (!CDecl || !CDecl->IsClassExtension())
1056 return false;
1057
1058 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1059 if (!ID)
1060 return false;
1061
1062 IdentifierInfo *PropertyId = PD->getIdentifier();
1063 ObjCPropertyDecl *prevDecl =
1064 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1065
1066 if (!prevDecl)
1067 return false;
1068
1069 // Visit synthesized methods since they will be skipped when visiting
1070 // the @interface.
1071 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1072 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1073 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1074 return true;
1075
1076 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1077 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1078 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1079 return true;
1080
1081 return false;
1082}
1083
1084bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1085 if (!D->isThisDeclarationADefinition()) {
1086 // Forward declaration is treated like a reference.
1087 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1088 }
1089
1090 // Issue callbacks for super class.
1091 if (D->getSuperClass() &&
1092 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1093 D->getSuperClassLoc(),
1094 TU)))
1095 return true;
1096
1097 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1098 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1099 E = D->protocol_end(); I != E; ++I, ++PL)
1100 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1101 return true;
1102
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1107 return VisitObjCContainerDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1111 // 'ID' could be null when dealing with invalid code.
1112 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1113 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1114 return true;
1115
1116 return VisitObjCImplDecl(D);
1117}
1118
1119bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1120#if 0
1121 // Issue callbacks for super class.
1122 // FIXME: No source location information!
1123 if (D->getSuperClass() &&
1124 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125 D->getSuperClassLoc(),
1126 TU)))
1127 return true;
1128#endif
1129
1130 return VisitObjCImplDecl(D);
1131}
1132
1133bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1134 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1135 if (PD->isIvarNameSpecified())
1136 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1137
1138 return false;
1139}
1140
1141bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1142 return VisitDeclContext(D);
1143}
1144
1145bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1146 // Visit nested-name-specifier.
1147 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1148 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149 return true;
1150
1151 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1152 D->getTargetNameLoc(), TU));
1153}
1154
1155bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1156 // Visit nested-name-specifier.
1157 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1158 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1159 return true;
1160 }
1161
1162 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1163 return true;
1164
1165 return VisitDeclarationNameInfo(D->getNameInfo());
1166}
1167
1168bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1169 // Visit nested-name-specifier.
1170 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172 return true;
1173
1174 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1175 D->getIdentLocation(), TU));
1176}
1177
1178bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1179 // Visit nested-name-specifier.
1180 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1181 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1182 return true;
1183 }
1184
1185 return VisitDeclarationNameInfo(D->getNameInfo());
1186}
1187
1188bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1189 UnresolvedUsingTypenameDecl *D) {
1190 // Visit nested-name-specifier.
1191 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1192 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1193 return true;
1194
1195 return false;
1196}
1197
1198bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1199 switch (Name.getName().getNameKind()) {
1200 case clang::DeclarationName::Identifier:
1201 case clang::DeclarationName::CXXLiteralOperatorName:
1202 case clang::DeclarationName::CXXOperatorName:
1203 case clang::DeclarationName::CXXUsingDirective:
1204 return false;
1205
1206 case clang::DeclarationName::CXXConstructorName:
1207 case clang::DeclarationName::CXXDestructorName:
1208 case clang::DeclarationName::CXXConversionFunctionName:
1209 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1210 return Visit(TSInfo->getTypeLoc());
1211 return false;
1212
1213 case clang::DeclarationName::ObjCZeroArgSelector:
1214 case clang::DeclarationName::ObjCOneArgSelector:
1215 case clang::DeclarationName::ObjCMultiArgSelector:
1216 // FIXME: Per-identifier location info?
1217 return false;
1218 }
1219
1220 llvm_unreachable("Invalid DeclarationName::Kind!");
1221}
1222
1223bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1224 SourceRange Range) {
1225 // FIXME: This whole routine is a hack to work around the lack of proper
1226 // source information in nested-name-specifiers (PR5791). Since we do have
1227 // a beginning source location, we can visit the first component of the
1228 // nested-name-specifier, if it's a single-token component.
1229 if (!NNS)
1230 return false;
1231
1232 // Get the first component in the nested-name-specifier.
1233 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1234 NNS = Prefix;
1235
1236 switch (NNS->getKind()) {
1237 case NestedNameSpecifier::Namespace:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1239 TU));
1240
1241 case NestedNameSpecifier::NamespaceAlias:
1242 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1243 Range.getBegin(), TU));
1244
1245 case NestedNameSpecifier::TypeSpec: {
1246 // If the type has a form where we know that the beginning of the source
1247 // range matches up with a reference cursor. Visit the appropriate reference
1248 // cursor.
1249 const Type *T = NNS->getAsType();
1250 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1251 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1252 if (const TagType *Tag = dyn_cast<TagType>(T))
1253 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1254 if (const TemplateSpecializationType *TST
1255 = dyn_cast<TemplateSpecializationType>(T))
1256 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1257 break;
1258 }
1259
1260 case NestedNameSpecifier::TypeSpecWithTemplate:
1261 case NestedNameSpecifier::Global:
1262 case NestedNameSpecifier::Identifier:
1263 break;
1264 }
1265
1266 return false;
1267}
1268
1269bool
1270CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1271 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1272 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1273 Qualifiers.push_back(Qualifier);
1274
1275 while (!Qualifiers.empty()) {
1276 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1277 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1278 switch (NNS->getKind()) {
1279 case NestedNameSpecifier::Namespace:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::NamespaceAlias:
1288 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1289 Q.getLocalBeginLoc(),
1290 TU)))
1291 return true;
1292
1293 break;
1294
1295 case NestedNameSpecifier::TypeSpec:
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 if (Visit(Q.getTypeLoc()))
1298 return true;
1299
1300 break;
1301
1302 case NestedNameSpecifier::Global:
1303 case NestedNameSpecifier::Identifier:
1304 break;
1305 }
1306 }
1307
1308 return false;
1309}
1310
1311bool CursorVisitor::VisitTemplateParameters(
1312 const TemplateParameterList *Params) {
1313 if (!Params)
1314 return false;
1315
1316 for (TemplateParameterList::const_iterator P = Params->begin(),
1317 PEnd = Params->end();
1318 P != PEnd; ++P) {
1319 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1320 return true;
1321 }
1322
1323 return false;
1324}
1325
1326bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1327 switch (Name.getKind()) {
1328 case TemplateName::Template:
1329 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1330
1331 case TemplateName::OverloadedTemplate:
1332 // Visit the overloaded template set.
1333 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1334 return true;
1335
1336 return false;
1337
1338 case TemplateName::DependentTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return false;
1341
1342 case TemplateName::QualifiedTemplate:
1343 // FIXME: Visit nested-name-specifier.
1344 return Visit(MakeCursorTemplateRef(
1345 Name.getAsQualifiedTemplateName()->getDecl(),
1346 Loc, TU));
1347
1348 case TemplateName::SubstTemplateTemplateParm:
1349 return Visit(MakeCursorTemplateRef(
1350 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1351 Loc, TU));
1352
1353 case TemplateName::SubstTemplateTemplateParmPack:
1354 return Visit(MakeCursorTemplateRef(
1355 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1356 Loc, TU));
1357 }
1358
1359 llvm_unreachable("Invalid TemplateName::Kind!");
1360}
1361
1362bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1363 switch (TAL.getArgument().getKind()) {
1364 case TemplateArgument::Null:
1365 case TemplateArgument::Integral:
1366 case TemplateArgument::Pack:
1367 return false;
1368
1369 case TemplateArgument::Type:
1370 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1371 return Visit(TSInfo->getTypeLoc());
1372 return false;
1373
1374 case TemplateArgument::Declaration:
1375 if (Expr *E = TAL.getSourceDeclExpression())
1376 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1377 return false;
1378
1379 case TemplateArgument::NullPtr:
1380 if (Expr *E = TAL.getSourceNullPtrExpression())
1381 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1382 return false;
1383
1384 case TemplateArgument::Expression:
1385 if (Expr *E = TAL.getSourceExpression())
1386 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1387 return false;
1388
1389 case TemplateArgument::Template:
1390 case TemplateArgument::TemplateExpansion:
1391 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1392 return true;
1393
1394 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1395 TAL.getTemplateNameLoc());
1396 }
1397
1398 llvm_unreachable("Invalid TemplateArgument::Kind!");
1399}
1400
1401bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1402 return VisitDeclContext(D);
1403}
1404
1405bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1406 return Visit(TL.getUnqualifiedLoc());
1407}
1408
1409bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1410 ASTContext &Context = AU->getASTContext();
1411
1412 // Some builtin types (such as Objective-C's "id", "sel", and
1413 // "Class") have associated declarations. Create cursors for those.
1414 QualType VisitType;
1415 switch (TL.getTypePtr()->getKind()) {
1416
1417 case BuiltinType::Void:
1418 case BuiltinType::NullPtr:
1419 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001420 case BuiltinType::OCLImage1d:
1421 case BuiltinType::OCLImage1dArray:
1422 case BuiltinType::OCLImage1dBuffer:
1423 case BuiltinType::OCLImage2d:
1424 case BuiltinType::OCLImage2dArray:
1425 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001426 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001427 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001428#define BUILTIN_TYPE(Id, SingletonId)
1429#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#include "clang/AST/BuiltinTypes.def"
1434 break;
1435
1436 case BuiltinType::ObjCId:
1437 VisitType = Context.getObjCIdType();
1438 break;
1439
1440 case BuiltinType::ObjCClass:
1441 VisitType = Context.getObjCClassType();
1442 break;
1443
1444 case BuiltinType::ObjCSel:
1445 VisitType = Context.getObjCSelType();
1446 break;
1447 }
1448
1449 if (!VisitType.isNull()) {
1450 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1451 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1452 TU));
1453 }
1454
1455 return false;
1456}
1457
1458bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1463 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1464}
1465
1466bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1467 if (TL.isDefinition())
1468 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1469
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1474 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1475}
1476
1477bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1478 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1479 return true;
1480
1481 return false;
1482}
1483
1484bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1485 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1486 return true;
1487
1488 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1489 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1490 TU)))
1491 return true;
1492 }
1493
1494 return false;
1495}
1496
1497bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1502 return Visit(TL.getInnerLoc());
1503}
1504
1505bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1522 return Visit(TL.getPointeeLoc());
1523}
1524
1525bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1526 return Visit(TL.getModifiedLoc());
1527}
1528
1529bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1530 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001531 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 return true;
1533
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001534 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1535 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001536 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1537 return true;
1538
1539 return false;
1540}
1541
1542bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1543 if (Visit(TL.getElementLoc()))
1544 return true;
1545
1546 if (Expr *Size = TL.getSizeExpr())
1547 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1548
1549 return false;
1550}
1551
Reid Kleckner8a365022013-06-24 17:51:48 +00001552bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Reid Kleckner0503a872013-12-05 01:23:43 +00001556bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1557 return Visit(TL.getOriginalLoc());
1558}
1559
Guy Benyei11169dd2012-12-18 14:30:41 +00001560bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1561 TemplateSpecializationTypeLoc TL) {
1562 // Visit the template name.
1563 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1564 TL.getTemplateNameLoc()))
1565 return true;
1566
1567 // Visit the template arguments.
1568 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1569 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1570 return true;
1571
1572 return false;
1573}
1574
1575bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1576 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1577}
1578
1579bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1580 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1581 return Visit(TSInfo->getTypeLoc());
1582
1583 return false;
1584}
1585
1586bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1587 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1588 return Visit(TSInfo->getTypeLoc());
1589
1590 return false;
1591}
1592
1593bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1594 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1595 return true;
1596
1597 return false;
1598}
1599
1600bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1601 DependentTemplateSpecializationTypeLoc TL) {
1602 // Visit the nested-name-specifier, if there is one.
1603 if (TL.getQualifierLoc() &&
1604 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1605 return true;
1606
1607 // Visit the template arguments.
1608 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1609 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1610 return true;
1611
1612 return false;
1613}
1614
1615bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1616 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1617 return true;
1618
1619 return Visit(TL.getNamedTypeLoc());
1620}
1621
1622bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1623 return Visit(TL.getPatternLoc());
1624}
1625
1626bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1627 if (Expr *E = TL.getUnderlyingExpr())
1628 return Visit(MakeCXCursor(E, StmtParent, TU));
1629
1630 return false;
1631}
1632
1633bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1634 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1635}
1636
1637bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1638 return Visit(TL.getValueLoc());
1639}
1640
1641#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1642bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1643 return Visit##PARENT##Loc(TL); \
1644}
1645
1646DEFAULT_TYPELOC_IMPL(Complex, Type)
1647DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1648DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1652DEFAULT_TYPELOC_IMPL(Vector, Type)
1653DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1654DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1655DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1656DEFAULT_TYPELOC_IMPL(Record, TagType)
1657DEFAULT_TYPELOC_IMPL(Enum, TagType)
1658DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1659DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1660DEFAULT_TYPELOC_IMPL(Auto, Type)
1661
1662bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1663 // Visit the nested-name-specifier, if present.
1664 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1665 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1666 return true;
1667
1668 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001669 for (const auto &I : D->bases()) {
1670 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001671 return true;
1672 }
1673 }
1674
1675 return VisitTagDecl(D);
1676}
1677
1678bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001679 for (const auto *I : D->attrs())
1680 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001681 return true;
1682
1683 return false;
1684}
1685
1686//===----------------------------------------------------------------------===//
1687// Data-recursive visitor methods.
1688//===----------------------------------------------------------------------===//
1689
1690namespace {
1691#define DEF_JOB(NAME, DATA, KIND)\
1692class NAME : public VisitorJob {\
1693public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001694 NAME(const DATA *d, CXCursor parent) : \
1695 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001696 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001697 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001698};
1699
1700DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1701DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1702DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1703DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1704DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1705 ExplicitTemplateArgsVisitKind)
1706DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1707DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1708DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1709#undef DEF_JOB
1710
1711class DeclVisit : public VisitorJob {
1712public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001713 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001715 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 static bool classof(const VisitorJob *VJ) {
1717 return VJ->getKind() == DeclVisitKind;
1718 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001719 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001720 bool isFirst() const { return data[1] ? true : false; }
1721};
1722class TypeLocVisit : public VisitorJob {
1723public:
1724 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1725 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1726 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1727
1728 static bool classof(const VisitorJob *VJ) {
1729 return VJ->getKind() == TypeLocVisitKind;
1730 }
1731
1732 TypeLoc get() const {
1733 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001734 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 }
1736};
1737
1738class LabelRefVisit : public VisitorJob {
1739public:
1740 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1741 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1742 labelLoc.getPtrEncoding()) {}
1743
1744 static bool classof(const VisitorJob *VJ) {
1745 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1746 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 const LabelDecl *get() const {
1748 return static_cast<const LabelDecl *>(data[0]);
1749 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 SourceLocation getLoc() const {
1751 return SourceLocation::getFromPtrEncoding(data[1]); }
1752};
1753
1754class NestedNameSpecifierLocVisit : public VisitorJob {
1755public:
1756 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1757 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1758 Qualifier.getNestedNameSpecifier(),
1759 Qualifier.getOpaqueData()) { }
1760
1761 static bool classof(const VisitorJob *VJ) {
1762 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1763 }
1764
1765 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 return NestedNameSpecifierLoc(
1767 const_cast<NestedNameSpecifier *>(
1768 static_cast<const NestedNameSpecifier *>(data[0])),
1769 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 }
1771};
1772
1773class DeclarationNameInfoVisit : public VisitorJob {
1774public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001775 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001776 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001777 static bool classof(const VisitorJob *VJ) {
1778 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1779 }
1780 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001781 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 switch (S->getStmtClass()) {
1783 default:
1784 llvm_unreachable("Unhandled Stmt");
1785 case clang::Stmt::MSDependentExistsStmtClass:
1786 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1787 case Stmt::CXXDependentScopeMemberExprClass:
1788 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1789 case Stmt::DependentScopeDeclRefExprClass:
1790 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001791 case Stmt::OMPCriticalDirectiveClass:
1792 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 }
1794 }
1795};
1796class MemberRefVisit : public VisitorJob {
1797public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001799 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1800 L.getPtrEncoding()) {}
1801 static bool classof(const VisitorJob *VJ) {
1802 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1803 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804 const FieldDecl *get() const {
1805 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001806 }
1807 SourceLocation getLoc() const {
1808 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1809 }
1810};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001811class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001812 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001813 VisitorWorkList &WL;
1814 CXCursor Parent;
1815public:
1816 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1817 : WL(wl), Parent(parent) {}
1818
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001819 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1820 void VisitBlockExpr(const BlockExpr *B);
1821 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1822 void VisitCompoundStmt(const CompoundStmt *S);
1823 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1824 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1825 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1826 void VisitCXXNewExpr(const CXXNewExpr *E);
1827 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1828 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1829 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1830 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1831 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1832 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1833 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1834 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1835 void VisitDeclRefExpr(const DeclRefExpr *D);
1836 void VisitDeclStmt(const DeclStmt *S);
1837 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1838 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1839 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1840 void VisitForStmt(const ForStmt *FS);
1841 void VisitGotoStmt(const GotoStmt *GS);
1842 void VisitIfStmt(const IfStmt *If);
1843 void VisitInitListExpr(const InitListExpr *IE);
1844 void VisitMemberExpr(const MemberExpr *M);
1845 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1846 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1847 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1848 void VisitOverloadExpr(const OverloadExpr *E);
1849 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1850 void VisitStmt(const Stmt *S);
1851 void VisitSwitchStmt(const SwitchStmt *S);
1852 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1854 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1855 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1856 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1857 void VisitVAArgExpr(const VAArgExpr *E);
1858 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1859 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1860 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1861 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001862 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001863 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001865 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001866 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001867 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001868 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001869 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001870 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001871 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001872 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001873 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001874 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001875 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001876 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001877 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001878 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001879 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001880 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001881 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001882 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883
Guy Benyei11169dd2012-12-18 14:30:41 +00001884private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1887 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1889 void AddStmt(const Stmt *S);
1890 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001893 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001894};
1895} // end anonyous namespace
1896
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001898 // 'S' should always be non-null, since it comes from the
1899 // statement we are visiting.
1900 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1901}
1902
1903void
1904EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1905 if (Qualifier)
1906 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1907}
1908
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001909void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001910 if (S)
1911 WL.push_back(StmtVisit(S, Parent));
1912}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001914 if (D)
1915 WL.push_back(DeclVisit(D, Parent, isFirst));
1916}
1917void EnqueueVisitor::
1918 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1919 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001920 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001921}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001922void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001923 if (D)
1924 WL.push_back(MemberRefVisit(D, L, Parent));
1925}
1926void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1927 if (TI)
1928 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1929 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001930void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001931 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001932 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001933 AddStmt(*Child);
1934 }
1935 if (size == WL.size())
1936 return;
1937 // Now reverse the entries we just added. This will match the DFS
1938 // ordering performed by the worklist.
1939 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1940 std::reverse(I, E);
1941}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001942namespace {
1943class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1944 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001945 /// \brief Process clauses with list of variables.
1946 template <typename T>
1947 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001948public:
1949 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1950#define OPENMP_CLAUSE(Name, Class) \
1951 void Visit##Class(const Class *C);
1952#include "clang/Basic/OpenMPKinds.def"
1953};
1954
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001955void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1956 Visitor->AddStmt(C->getCondition());
1957}
1958
Alexey Bataev3778b602014-07-17 07:32:53 +00001959void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1960 Visitor->AddStmt(C->getCondition());
1961}
1962
Alexey Bataev568a8332014-03-06 06:15:19 +00001963void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1964 Visitor->AddStmt(C->getNumThreads());
1965}
1966
Alexey Bataev62c87d22014-03-21 04:51:18 +00001967void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1968 Visitor->AddStmt(C->getSafelen());
1969}
1970
Alexander Musman8bd31e62014-05-27 15:12:19 +00001971void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1972 Visitor->AddStmt(C->getNumForLoops());
1973}
1974
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001975void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001976
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001977void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1978
Alexey Bataev56dafe82014-06-20 07:16:17 +00001979void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1980 Visitor->AddStmt(C->getChunkSize());
1981}
1982
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001983void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1984
Alexey Bataev236070f2014-06-20 11:19:47 +00001985void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1986
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001987void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1988
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001989void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1990
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001991void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1992
Alexey Bataevdea47612014-07-23 07:46:59 +00001993void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1994
Alexey Bataev67a4f222014-07-23 10:25:33 +00001995void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
1996
Alexey Bataev459dec02014-07-24 06:46:57 +00001997void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
1998
Alexey Bataev82bad8b2014-07-24 08:55:34 +00001999void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2000
Alexey Bataev756c1962013-09-24 03:17:45 +00002001template<typename T>
2002void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002003 for (const auto *I : Node->varlists())
2004 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00002005}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002006
2007void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002008 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002009}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002010void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2011 const OMPFirstprivateClause *C) {
2012 VisitOMPClauseList(C);
2013}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002014void OMPClauseEnqueue::VisitOMPLastprivateClause(
2015 const OMPLastprivateClause *C) {
2016 VisitOMPClauseList(C);
2017}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002018void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002019 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002020}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002021void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2022 VisitOMPClauseList(C);
2023}
Alexander Musman8dba6642014-04-22 13:09:42 +00002024void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2025 VisitOMPClauseList(C);
2026 Visitor->AddStmt(C->getStep());
2027}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002028void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2029 VisitOMPClauseList(C);
2030 Visitor->AddStmt(C->getAlignment());
2031}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002032void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2033 VisitOMPClauseList(C);
2034}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002035void
2036OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2037 VisitOMPClauseList(C);
2038}
Alexey Bataev6125da92014-07-21 11:26:11 +00002039void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2040 VisitOMPClauseList(C);
2041}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002042}
Alexey Bataev756c1962013-09-24 03:17:45 +00002043
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002044void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2045 unsigned size = WL.size();
2046 OMPClauseEnqueue Visitor(this);
2047 Visitor.Visit(S);
2048 if (size == WL.size())
2049 return;
2050 // Now reverse the entries we just added. This will match the DFS
2051 // ordering performed by the worklist.
2052 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2053 std::reverse(I, E);
2054}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002059 AddDecl(B->getBlockDecl());
2060}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002061void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002062 EnqueueChildren(E);
2063 AddTypeLoc(E->getTypeSourceInfo());
2064}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2066 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 E = S->body_rend(); I != E; ++I) {
2068 AddStmt(*I);
2069 }
2070}
2071void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002072VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002073 AddStmt(S->getSubStmt());
2074 AddDeclarationNameInfo(S);
2075 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2076 AddNestedNameSpecifierLoc(QualifierLoc);
2077}
2078
2079void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2082 AddDeclarationNameInfo(E);
2083 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2084 AddNestedNameSpecifierLoc(QualifierLoc);
2085 if (!E->isImplicitAccess())
2086 AddStmt(E->getBase());
2087}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 // Enqueue the initializer , if any.
2090 AddStmt(E->getInitializer());
2091 // Enqueue the array size, if any.
2092 AddStmt(E->getArraySize());
2093 // Enqueue the allocated type.
2094 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2095 // Enqueue the placement arguments.
2096 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2097 AddStmt(E->getPlacementArg(I-1));
2098}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002100 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2101 AddStmt(CE->getArg(I-1));
2102 AddStmt(CE->getCallee());
2103 AddStmt(CE->getArg(0));
2104}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002105void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2106 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002107 // Visit the name of the type being destroyed.
2108 AddTypeLoc(E->getDestroyedTypeInfo());
2109 // Visit the scope type that looks disturbingly like the nested-name-specifier
2110 // but isn't.
2111 AddTypeLoc(E->getScopeTypeInfo());
2112 // Visit the nested-name-specifier.
2113 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2114 AddNestedNameSpecifierLoc(QualifierLoc);
2115 // Visit base expression.
2116 AddStmt(E->getBase());
2117}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2119 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 AddTypeLoc(E->getTypeSourceInfo());
2121}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2123 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 EnqueueChildren(E);
2125 AddTypeLoc(E->getTypeSourceInfo());
2126}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002127void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 EnqueueChildren(E);
2129 if (E->isTypeOperand())
2130 AddTypeLoc(E->getTypeOperandSourceInfo());
2131}
2132
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002133void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2134 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 EnqueueChildren(E);
2136 AddTypeLoc(E->getTypeSourceInfo());
2137}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 EnqueueChildren(E);
2140 if (E->isTypeOperand())
2141 AddTypeLoc(E->getTypeOperandSourceInfo());
2142}
2143
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002144void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002145 EnqueueChildren(S);
2146 AddDecl(S->getExceptionDecl());
2147}
2148
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 if (DR->hasExplicitTemplateArgs()) {
2151 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2152 }
2153 WL.push_back(DeclRefExprParts(DR, Parent));
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2156 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002157 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2158 AddDeclarationNameInfo(E);
2159 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2160}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002162 unsigned size = WL.size();
2163 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002164 for (const auto *D : S->decls()) {
2165 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002166 isFirst = false;
2167 }
2168 if (size == WL.size())
2169 return;
2170 // Now reverse the entries we just added. This will match the DFS
2171 // ordering performed by the worklist.
2172 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2173 std::reverse(I, E);
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002177 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002178 D = E->designators_rbegin(), DEnd = E->designators_rend();
2179 D != DEnd; ++D) {
2180 if (D->isFieldDesignator()) {
2181 if (FieldDecl *Field = D->getField())
2182 AddMemberRef(Field, D->getFieldLoc());
2183 continue;
2184 }
2185 if (D->isArrayDesignator()) {
2186 AddStmt(E->getArrayIndex(*D));
2187 continue;
2188 }
2189 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2190 AddStmt(E->getArrayRangeEnd(*D));
2191 AddStmt(E->getArrayRangeStart(*D));
2192 }
2193}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 EnqueueChildren(E);
2196 AddTypeLoc(E->getTypeInfoAsWritten());
2197}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 AddStmt(FS->getBody());
2200 AddStmt(FS->getInc());
2201 AddStmt(FS->getCond());
2202 AddDecl(FS->getConditionVariable());
2203 AddStmt(FS->getInit());
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2207}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 AddStmt(If->getElse());
2210 AddStmt(If->getThen());
2211 AddStmt(If->getCond());
2212 AddDecl(If->getConditionVariable());
2213}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 // We care about the syntactic form of the initializer list, only.
2216 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2217 IE = Syntactic;
2218 EnqueueChildren(IE);
2219}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 WL.push_back(MemberExprParts(M, Parent));
2222
2223 // If the base of the member access expression is an implicit 'this', don't
2224 // visit it.
2225 // FIXME: If we ever want to show these implicit accesses, this will be
2226 // unfortunate. However, clang_getCursor() relies on this behavior.
2227 if (!M->isImplicitAccess())
2228 AddStmt(M->getBase());
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 AddTypeLoc(E->getEncodedTypeSourceInfo());
2232}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002233void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002234 EnqueueChildren(M);
2235 AddTypeLoc(M->getClassReceiverTypeInfo());
2236}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002238 // Visit the components of the offsetof expression.
2239 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2240 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2241 const OffsetOfNode &Node = E->getComponent(I-1);
2242 switch (Node.getKind()) {
2243 case OffsetOfNode::Array:
2244 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2245 break;
2246 case OffsetOfNode::Field:
2247 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2248 break;
2249 case OffsetOfNode::Identifier:
2250 case OffsetOfNode::Base:
2251 continue;
2252 }
2253 }
2254 // Visit the type into which we're computing the offset.
2255 AddTypeLoc(E->getTypeSourceInfo());
2256}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2259 WL.push_back(OverloadExprParts(E, Parent));
2260}
2261void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 EnqueueChildren(E);
2264 if (E->isArgumentType())
2265 AddTypeLoc(E->getArgumentTypeInfo());
2266}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 EnqueueChildren(S);
2269}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 AddStmt(S->getBody());
2272 AddStmt(S->getCond());
2273 AddDecl(S->getConditionVariable());
2274}
2275
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 AddStmt(W->getBody());
2278 AddStmt(W->getCond());
2279 AddDecl(W->getConditionVariable());
2280}
2281
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002283 for (unsigned I = E->getNumArgs(); I > 0; --I)
2284 AddTypeLoc(E->getArg(I-1));
2285}
2286
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002287void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002288 AddTypeLoc(E->getQueriedTypeSourceInfo());
2289}
2290
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002291void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002292 EnqueueChildren(E);
2293}
2294
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002295void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002296 VisitOverloadExpr(U);
2297 if (!U->isImplicitAccess())
2298 AddStmt(U->getBase());
2299}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002300void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002301 AddStmt(E->getSubExpr());
2302 AddTypeLoc(E->getWrittenTypeInfo());
2303}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002304void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002305 WL.push_back(SizeOfPackExprParts(E, Parent));
2306}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002307void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002308 // If the opaque value has a source expression, just transparently
2309 // visit that. This is useful for (e.g.) pseudo-object expressions.
2310 if (Expr *SourceExpr = E->getSourceExpr())
2311 return Visit(SourceExpr);
2312}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 AddStmt(E->getBody());
2315 WL.push_back(LambdaExprParts(E, Parent));
2316}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002317void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002318 // Treat the expression like its syntactic form.
2319 Visit(E->getSyntacticForm());
2320}
2321
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002322void EnqueueVisitor::VisitOMPExecutableDirective(
2323 const OMPExecutableDirective *D) {
2324 EnqueueChildren(D);
2325 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2326 E = D->clauses().end();
2327 I != E; ++I)
2328 EnqueueChildren(*I);
2329}
2330
Alexander Musman3aaab662014-08-19 11:27:13 +00002331void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2332 VisitOMPExecutableDirective(D);
2333}
2334
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002335void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2336 VisitOMPExecutableDirective(D);
2337}
2338
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002339void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002340 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002341}
2342
Alexey Bataevf29276e2014-06-18 04:14:57 +00002343void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002344 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002345}
2346
Alexander Musmanf82886e2014-09-18 05:12:34 +00002347void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2348 VisitOMPLoopDirective(D);
2349}
2350
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002351void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2352 VisitOMPExecutableDirective(D);
2353}
2354
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002355void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2356 VisitOMPExecutableDirective(D);
2357}
2358
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002359void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2360 VisitOMPExecutableDirective(D);
2361}
2362
Alexander Musman80c22892014-07-17 08:54:58 +00002363void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2364 VisitOMPExecutableDirective(D);
2365}
2366
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002367void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2368 VisitOMPExecutableDirective(D);
2369 AddDeclarationNameInfo(D);
2370}
2371
Alexey Bataev4acb8592014-07-07 13:01:15 +00002372void
2373EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002374 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002375}
2376
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002377void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2378 const OMPParallelSectionsDirective *D) {
2379 VisitOMPExecutableDirective(D);
2380}
2381
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002382void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2383 VisitOMPExecutableDirective(D);
2384}
2385
Alexey Bataev68446b72014-07-18 07:47:19 +00002386void
2387EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2388 VisitOMPExecutableDirective(D);
2389}
2390
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002391void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2392 VisitOMPExecutableDirective(D);
2393}
2394
Alexey Bataev2df347a2014-07-18 10:17:07 +00002395void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2396 VisitOMPExecutableDirective(D);
2397}
2398
Alexey Bataev6125da92014-07-21 11:26:11 +00002399void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2400 VisitOMPExecutableDirective(D);
2401}
2402
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002403void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2404 VisitOMPExecutableDirective(D);
2405}
2406
Alexey Bataev0162e452014-07-22 10:10:35 +00002407void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2408 VisitOMPExecutableDirective(D);
2409}
2410
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002411void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2412 VisitOMPExecutableDirective(D);
2413}
2414
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002415void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002416 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2417}
2418
2419bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2420 if (RegionOfInterest.isValid()) {
2421 SourceRange Range = getRawCursorExtent(C);
2422 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2423 return false;
2424 }
2425 return true;
2426}
2427
2428bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2429 while (!WL.empty()) {
2430 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002431 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002432
2433 // Set the Parent field, then back to its old value once we're done.
2434 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2435
2436 switch (LI.getKind()) {
2437 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 if (!D)
2440 continue;
2441
2442 // For now, perform default visitation for Decls.
2443 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2444 cast<DeclVisit>(&LI)->isFirst())))
2445 return true;
2446
2447 continue;
2448 }
2449 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2450 const ASTTemplateArgumentListInfo *ArgList =
2451 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2452 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2453 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2454 Arg != ArgEnd; ++Arg) {
2455 if (VisitTemplateArgumentLoc(*Arg))
2456 return true;
2457 }
2458 continue;
2459 }
2460 case VisitorJob::TypeLocVisitKind: {
2461 // Perform default visitation for TypeLocs.
2462 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2463 return true;
2464 continue;
2465 }
2466 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002467 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002468 if (LabelStmt *stmt = LS->getStmt()) {
2469 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2470 TU))) {
2471 return true;
2472 }
2473 }
2474 continue;
2475 }
2476
2477 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2478 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2479 if (VisitNestedNameSpecifierLoc(V->get()))
2480 return true;
2481 continue;
2482 }
2483
2484 case VisitorJob::DeclarationNameInfoVisitKind: {
2485 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2486 ->get()))
2487 return true;
2488 continue;
2489 }
2490 case VisitorJob::MemberRefVisitKind: {
2491 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2492 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2493 return true;
2494 continue;
2495 }
2496 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002497 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002498 if (!S)
2499 continue;
2500
2501 // Update the current cursor.
2502 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2503 if (!IsInRegionOfInterest(Cursor))
2504 continue;
2505 switch (Visitor(Cursor, Parent, ClientData)) {
2506 case CXChildVisit_Break: return true;
2507 case CXChildVisit_Continue: break;
2508 case CXChildVisit_Recurse:
2509 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002510 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002511 EnqueueWorkList(WL, S);
2512 break;
2513 }
2514 continue;
2515 }
2516 case VisitorJob::MemberExprPartsKind: {
2517 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002518 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002519
2520 // Visit the nested-name-specifier
2521 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2522 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2523 return true;
2524
2525 // Visit the declaration name.
2526 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2527 return true;
2528
2529 // Visit the explicitly-specified template arguments, if any.
2530 if (M->hasExplicitTemplateArgs()) {
2531 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2532 *ArgEnd = Arg + M->getNumTemplateArgs();
2533 Arg != ArgEnd; ++Arg) {
2534 if (VisitTemplateArgumentLoc(*Arg))
2535 return true;
2536 }
2537 }
2538 continue;
2539 }
2540 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002541 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002542 // Visit nested-name-specifier, if present.
2543 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2544 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2545 return true;
2546 // Visit declaration name.
2547 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2548 return true;
2549 continue;
2550 }
2551 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002552 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002553 // Visit the nested-name-specifier.
2554 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2555 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2556 return true;
2557 // Visit the declaration name.
2558 if (VisitDeclarationNameInfo(O->getNameInfo()))
2559 return true;
2560 // Visit the overloaded declaration reference.
2561 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2562 return true;
2563 continue;
2564 }
2565 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002566 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002567 NamedDecl *Pack = E->getPack();
2568 if (isa<TemplateTypeParmDecl>(Pack)) {
2569 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2570 E->getPackLoc(), TU)))
2571 return true;
2572
2573 continue;
2574 }
2575
2576 if (isa<TemplateTemplateParmDecl>(Pack)) {
2577 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2578 E->getPackLoc(), TU)))
2579 return true;
2580
2581 continue;
2582 }
2583
2584 // Non-type template parameter packs and function parameter packs are
2585 // treated like DeclRefExpr cursors.
2586 continue;
2587 }
2588
2589 case VisitorJob::LambdaExprPartsKind: {
2590 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002591 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002592 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2593 CEnd = E->explicit_capture_end();
2594 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002595 // FIXME: Lambda init-captures.
2596 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002597 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002598
Guy Benyei11169dd2012-12-18 14:30:41 +00002599 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2600 C->getLocation(),
2601 TU)))
2602 return true;
2603 }
2604
2605 // Visit parameters and return type, if present.
2606 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2607 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2608 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2609 // Visit the whole type.
2610 if (Visit(TL))
2611 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002612 } else if (FunctionProtoTypeLoc Proto =
2613 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002614 if (E->hasExplicitParameters()) {
2615 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002616 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2617 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002618 return true;
2619 } else {
2620 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002621 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002622 return true;
2623 }
2624 }
2625 }
2626 break;
2627 }
2628
2629 case VisitorJob::PostChildrenVisitKind:
2630 if (PostChildrenVisitor(Parent, ClientData))
2631 return true;
2632 break;
2633 }
2634 }
2635 return false;
2636}
2637
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002638bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002639 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002640 if (!WorkListFreeList.empty()) {
2641 WL = WorkListFreeList.back();
2642 WL->clear();
2643 WorkListFreeList.pop_back();
2644 }
2645 else {
2646 WL = new VisitorWorkList();
2647 WorkListCache.push_back(WL);
2648 }
2649 EnqueueWorkList(*WL, S);
2650 bool result = RunVisitorWorkList(*WL);
2651 WorkListFreeList.push_back(WL);
2652 return result;
2653}
2654
2655namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002656typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002657RefNamePieces
2658buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2659 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2660 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002661 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2662 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2663 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2664
2665 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2666
2667 RefNamePieces Pieces;
2668
2669 if (WantQualifier && QLoc.isValid())
2670 Pieces.push_back(QLoc);
2671
2672 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2673 Pieces.push_back(NI.getLoc());
2674
2675 if (WantTemplateArgs && TemplateArgs)
2676 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2677 TemplateArgs->RAngleLoc));
2678
2679 if (Kind == DeclarationName::CXXOperatorName) {
2680 Pieces.push_back(SourceLocation::getFromRawEncoding(
2681 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2682 Pieces.push_back(SourceLocation::getFromRawEncoding(
2683 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2684 }
2685
2686 if (WantSinglePiece) {
2687 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2688 Pieces.clear();
2689 Pieces.push_back(R);
2690 }
2691
2692 return Pieces;
2693}
2694}
2695
2696//===----------------------------------------------------------------------===//
2697// Misc. API hooks.
2698//===----------------------------------------------------------------------===//
2699
Chad Rosier05c71aa2013-03-27 18:28:23 +00002700static void fatal_error_handler(void *user_data, const std::string& reason,
2701 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002702 // Write the result out to stderr avoiding errs() because raw_ostreams can
2703 // call report_fatal_error.
2704 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2705 ::abort();
2706}
2707
Chandler Carruth66660742014-06-27 16:37:27 +00002708namespace {
2709struct RegisterFatalErrorHandler {
2710 RegisterFatalErrorHandler() {
2711 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2712 }
2713};
2714}
2715
2716static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2717
Guy Benyei11169dd2012-12-18 14:30:41 +00002718extern "C" {
2719CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2720 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002721 // We use crash recovery to make some of our APIs more reliable, implicitly
2722 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002723 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2724 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002725
Chandler Carruth66660742014-06-27 16:37:27 +00002726 // Look through the managed static to trigger construction of the managed
2727 // static which registers our fatal error handler. This ensures it is only
2728 // registered once.
2729 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002730
2731 CIndexer *CIdxr = new CIndexer();
2732 if (excludeDeclarationsFromPCH)
2733 CIdxr->setOnlyLocalDecls();
2734 if (displayDiagnostics)
2735 CIdxr->setDisplayDiagnostics();
2736
2737 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2738 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2739 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2740 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2741 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2742 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2743
2744 return CIdxr;
2745}
2746
2747void clang_disposeIndex(CXIndex CIdx) {
2748 if (CIdx)
2749 delete static_cast<CIndexer *>(CIdx);
2750}
2751
2752void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2753 if (CIdx)
2754 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2755}
2756
2757unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2758 if (CIdx)
2759 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2760 return 0;
2761}
2762
2763void clang_toggleCrashRecovery(unsigned isEnabled) {
2764 if (isEnabled)
2765 llvm::CrashRecoveryContext::Enable();
2766 else
2767 llvm::CrashRecoveryContext::Disable();
2768}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002769
Guy Benyei11169dd2012-12-18 14:30:41 +00002770CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2771 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002772 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002773 enum CXErrorCode Result =
2774 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002775 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002776 assert((TU && Result == CXError_Success) ||
2777 (!TU && Result != CXError_Success));
2778 return TU;
2779}
2780
2781enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2782 const char *ast_filename,
2783 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002784 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002785 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002786
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002787 if (!CIdx || !ast_filename || !out_TU)
2788 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002789
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002790 LOG_FUNC_SECTION {
2791 *Log << ast_filename;
2792 }
2793
Guy Benyei11169dd2012-12-18 14:30:41 +00002794 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2795 FileSystemOptions FileSystemOpts;
2796
2797 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
David Blaikie6f7382d2014-08-10 19:08:04 +00002798 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2799 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2800 /*CaptureDiagnostics=*/true,
2801 /*AllowPCHWithCompilerErrors=*/true,
2802 /*UserFilesAreVolatile=*/true);
2803 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002804 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002805}
2806
2807unsigned clang_defaultEditingTranslationUnitOptions() {
2808 return CXTranslationUnit_PrecompiledPreamble |
2809 CXTranslationUnit_CacheCompletionResults;
2810}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002811
Guy Benyei11169dd2012-12-18 14:30:41 +00002812CXTranslationUnit
2813clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2814 const char *source_filename,
2815 int num_command_line_args,
2816 const char * const *command_line_args,
2817 unsigned num_unsaved_files,
2818 struct CXUnsavedFile *unsaved_files) {
2819 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2820 return clang_parseTranslationUnit(CIdx, source_filename,
2821 command_line_args, num_command_line_args,
2822 unsaved_files, num_unsaved_files,
2823 Options);
2824}
2825
2826struct ParseTranslationUnitInfo {
2827 CXIndex CIdx;
2828 const char *source_filename;
2829 const char *const *command_line_args;
2830 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002831 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002832 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002833 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002834 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002835};
2836static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002837 const ParseTranslationUnitInfo *PTUI =
2838 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002839 CXIndex CIdx = PTUI->CIdx;
2840 const char *source_filename = PTUI->source_filename;
2841 const char * const *command_line_args = PTUI->command_line_args;
2842 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002843 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002844 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002845
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002846 // Set up the initial return values.
2847 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002848 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002849
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002850 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002851 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002852 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002853 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002854 }
2855
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2857
2858 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2859 setThreadBackgroundPriority();
2860
2861 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2862 // FIXME: Add a flag for modules.
2863 TranslationUnitKind TUKind
2864 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002865 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002866 = options & CXTranslationUnit_CacheCompletionResults;
2867 bool IncludeBriefCommentsInCodeCompletion
2868 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2869 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2870 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2871
2872 // Configure the diagnostics.
2873 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002874 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002875
2876 // Recover resources if we crash before exiting this function.
2877 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2878 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002879 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002880
Ahmed Charlesb8984322014-03-07 20:03:18 +00002881 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2882 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002883
2884 // Recover resources if we crash before exiting this function.
2885 llvm::CrashRecoveryContextCleanupRegistrar<
2886 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2887
Alp Toker9d85b182014-07-07 01:23:14 +00002888 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002889 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002890 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002891 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002892 }
2893
Ahmed Charlesb8984322014-03-07 20:03:18 +00002894 std::unique_ptr<std::vector<const char *>> Args(
2895 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002896
2897 // Recover resources if we crash before exiting this method.
2898 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2899 ArgsCleanup(Args.get());
2900
2901 // Since the Clang C library is primarily used by batch tools dealing with
2902 // (often very broken) source code, where spell-checking can have a
2903 // significant negative impact on performance (particularly when
2904 // precompiled headers are involved), we disable it by default.
2905 // Only do this if we haven't found a spell-checking-related argument.
2906 bool FoundSpellCheckingArgument = false;
2907 for (int I = 0; I != num_command_line_args; ++I) {
2908 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2909 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2910 FoundSpellCheckingArgument = true;
2911 break;
2912 }
2913 }
2914 if (!FoundSpellCheckingArgument)
2915 Args->push_back("-fno-spell-checking");
2916
2917 Args->insert(Args->end(), command_line_args,
2918 command_line_args + num_command_line_args);
2919
2920 // The 'source_filename' argument is optional. If the caller does not
2921 // specify it then it is assumed that the source file is specified
2922 // in the actual argument list.
2923 // Put the source file after command_line_args otherwise if '-x' flag is
2924 // present it will be unused.
2925 if (source_filename)
2926 Args->push_back(source_filename);
2927
2928 // Do we need the detailed preprocessing record?
2929 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2930 Args->push_back("-Xclang");
2931 Args->push_back("-detailed-preprocessing-record");
2932 }
2933
2934 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002935 std::unique_ptr<ASTUnit> ErrUnit;
2936 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002937 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002938 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2939 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2940 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2941 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2942 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2943 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002944
2945 if (NumErrors != Diags->getClient()->getNumErrors()) {
2946 // Make sure to check that 'Unit' is non-NULL.
2947 if (CXXIdx->getDisplayDiagnostics())
2948 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2949 }
2950
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002951 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2952 PTUI->result = CXError_ASTReadError;
2953 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002954 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002955 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2956 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002957}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002958
2959CXTranslationUnit
2960clang_parseTranslationUnit(CXIndex CIdx,
2961 const char *source_filename,
2962 const char *const *command_line_args,
2963 int num_command_line_args,
2964 struct CXUnsavedFile *unsaved_files,
2965 unsigned num_unsaved_files,
2966 unsigned options) {
2967 CXTranslationUnit TU;
2968 enum CXErrorCode Result = clang_parseTranslationUnit2(
2969 CIdx, source_filename, command_line_args, num_command_line_args,
2970 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002971 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002972 assert((TU && Result == CXError_Success) ||
2973 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002974 return TU;
2975}
2976
2977enum CXErrorCode clang_parseTranslationUnit2(
2978 CXIndex CIdx,
2979 const char *source_filename,
2980 const char *const *command_line_args,
2981 int num_command_line_args,
2982 struct CXUnsavedFile *unsaved_files,
2983 unsigned num_unsaved_files,
2984 unsigned options,
2985 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002986 LOG_FUNC_SECTION {
2987 *Log << source_filename << ": ";
2988 for (int i = 0; i != num_command_line_args; ++i)
2989 *Log << command_line_args[i] << " ";
2990 }
2991
Alp Toker9d85b182014-07-07 01:23:14 +00002992 if (num_unsaved_files && !unsaved_files)
2993 return CXError_InvalidArguments;
2994
Alp Toker5c532982014-07-07 22:42:03 +00002995 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002996 ParseTranslationUnitInfo PTUI = {
2997 CIdx,
2998 source_filename,
2999 command_line_args,
3000 num_command_line_args,
3001 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3002 options,
3003 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003004 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003005 llvm::CrashRecoveryContext CRC;
3006
3007 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3008 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3009 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3010 fprintf(stderr, " 'command_line_args' : [");
3011 for (int i = 0; i != num_command_line_args; ++i) {
3012 if (i)
3013 fprintf(stderr, ", ");
3014 fprintf(stderr, "'%s'", command_line_args[i]);
3015 }
3016 fprintf(stderr, "],\n");
3017 fprintf(stderr, " 'unsaved_files' : [");
3018 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3019 if (i)
3020 fprintf(stderr, ", ");
3021 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3022 unsaved_files[i].Length);
3023 }
3024 fprintf(stderr, "],\n");
3025 fprintf(stderr, " 'options' : %d,\n", options);
3026 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003027
3028 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003029 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003030 if (CXTranslationUnit *TU = PTUI.out_TU)
3031 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003032 }
Alp Toker5c532982014-07-07 22:42:03 +00003033
3034 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003035}
3036
3037unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3038 return CXSaveTranslationUnit_None;
3039}
3040
3041namespace {
3042
3043struct SaveTranslationUnitInfo {
3044 CXTranslationUnit TU;
3045 const char *FileName;
3046 unsigned options;
3047 CXSaveError result;
3048};
3049
3050}
3051
3052static void clang_saveTranslationUnit_Impl(void *UserData) {
3053 SaveTranslationUnitInfo *STUI =
3054 static_cast<SaveTranslationUnitInfo*>(UserData);
3055
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003056 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003057 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3058 setThreadBackgroundPriority();
3059
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003060 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003061 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3062}
3063
3064int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3065 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003066 LOG_FUNC_SECTION {
3067 *Log << TU << ' ' << FileName;
3068 }
3069
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003070 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003071 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003072 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003073 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003074
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003075 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003076 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3077 if (!CXXUnit->hasSema())
3078 return CXSaveError_InvalidTU;
3079
3080 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3081
3082 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3083 getenv("LIBCLANG_NOTHREADS")) {
3084 clang_saveTranslationUnit_Impl(&STUI);
3085
3086 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3087 PrintLibclangResourceUsage(TU);
3088
3089 return STUI.result;
3090 }
3091
3092 // We have an AST that has invalid nodes due to compiler errors.
3093 // Use a crash recovery thread for protection.
3094
3095 llvm::CrashRecoveryContext CRC;
3096
3097 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3098 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3099 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3100 fprintf(stderr, " 'options' : %d,\n", options);
3101 fprintf(stderr, "}\n");
3102
3103 return CXSaveError_Unknown;
3104
3105 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3106 PrintLibclangResourceUsage(TU);
3107 }
3108
3109 return STUI.result;
3110}
3111
3112void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3113 if (CTUnit) {
3114 // If the translation unit has been marked as unsafe to free, just discard
3115 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003116 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3117 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003118 return;
3119
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003120 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003121 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3123 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003124 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003125 delete CTUnit;
3126 }
3127}
3128
3129unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3130 return CXReparse_None;
3131}
3132
3133struct ReparseTranslationUnitInfo {
3134 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003135 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003136 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003137 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003138};
3139
3140static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003141 const ReparseTranslationUnitInfo *RTUI =
3142 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003143 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003144 unsigned options = RTUI->options;
3145 (void) options;
3146
3147 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003148 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003149 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003150 RTUI->result = CXError_InvalidArguments;
3151 return;
3152 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003153
3154 // Reset the associated diagnostics.
3155 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003156 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003157
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003158 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3160 setThreadBackgroundPriority();
3161
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003162 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003164
3165 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3166 new std::vector<ASTUnit::RemappedFile>());
3167
Guy Benyei11169dd2012-12-18 14:30:41 +00003168 // Recover resources if we crash before exiting this function.
3169 llvm::CrashRecoveryContextCleanupRegistrar<
3170 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003171
3172 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003173 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003174 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003175 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003177
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003178 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003179 RTUI->result = CXError_Success;
3180 else if (isASTReadError(CXXUnit))
3181 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003182}
3183
3184int clang_reparseTranslationUnit(CXTranslationUnit TU,
3185 unsigned num_unsaved_files,
3186 struct CXUnsavedFile *unsaved_files,
3187 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003188 LOG_FUNC_SECTION {
3189 *Log << TU;
3190 }
3191
Alp Toker9d85b182014-07-07 01:23:14 +00003192 if (num_unsaved_files && !unsaved_files)
3193 return CXError_InvalidArguments;
3194
Alp Toker5c532982014-07-07 22:42:03 +00003195 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003196 ReparseTranslationUnitInfo RTUI = {
3197 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003198 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003199
3200 if (getenv("LIBCLANG_NOTHREADS")) {
3201 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003202 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 }
3204
3205 llvm::CrashRecoveryContext CRC;
3206
3207 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3208 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003209 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003210 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3212 PrintLibclangResourceUsage(TU);
3213
Alp Toker5c532982014-07-07 22:42:03 +00003214 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003215}
3216
3217
3218CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003219 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003220 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003221 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003222 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003223
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003224 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003225 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003226}
3227
3228CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003229 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003230 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003231 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003232 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003233
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003234 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3236}
3237
3238} // end: extern "C"
3239
3240//===----------------------------------------------------------------------===//
3241// CXFile Operations.
3242//===----------------------------------------------------------------------===//
3243
3244extern "C" {
3245CXString clang_getFileName(CXFile SFile) {
3246 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003247 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003248
3249 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003250 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003251}
3252
3253time_t clang_getFileTime(CXFile SFile) {
3254 if (!SFile)
3255 return 0;
3256
3257 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3258 return FEnt->getModificationTime();
3259}
3260
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003261CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003262 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003263 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003264 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003265 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003266
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003267 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003268
3269 FileManager &FMgr = CXXUnit->getFileManager();
3270 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3271}
3272
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003273unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3274 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003275 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003276 LOG_BAD_TU(TU);
3277 return 0;
3278 }
3279
3280 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 return 0;
3282
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003283 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 FileEntry *FEnt = static_cast<FileEntry *>(file);
3285 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3286 .isFileMultipleIncludeGuarded(FEnt);
3287}
3288
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003289int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3290 if (!file || !outID)
3291 return 1;
3292
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003293 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003294 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3295 outID->data[0] = ID.getDevice();
3296 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003297 outID->data[2] = FEnt->getModificationTime();
3298 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003299}
3300
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003301int clang_File_isEqual(CXFile file1, CXFile file2) {
3302 if (file1 == file2)
3303 return true;
3304
3305 if (!file1 || !file2)
3306 return false;
3307
3308 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3309 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3310 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3311}
3312
Guy Benyei11169dd2012-12-18 14:30:41 +00003313} // end: extern "C"
3314
3315//===----------------------------------------------------------------------===//
3316// CXCursor Operations.
3317//===----------------------------------------------------------------------===//
3318
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003319static const Decl *getDeclFromExpr(const Stmt *E) {
3320 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 return getDeclFromExpr(CE->getSubExpr());
3322
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003323 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003325 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003327 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003329 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 if (PRE->isExplicitProperty())
3331 return PRE->getExplicitProperty();
3332 // It could be messaging both getter and setter as in:
3333 // ++myobj.myprop;
3334 // in which case prefer to associate the setter since it is less obvious
3335 // from inspecting the source that the setter is going to get called.
3336 if (PRE->isMessagingSetter())
3337 return PRE->getImplicitPropertySetter();
3338 return PRE->getImplicitPropertyGetter();
3339 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003340 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003342 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 if (Expr *Src = OVE->getSourceExpr())
3344 return getDeclFromExpr(Src);
3345
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003346 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003348 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 if (!CE->isElidable())
3350 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003351 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 return OME->getMethodDecl();
3353
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003354 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003356 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3358 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003359 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3361 isa<ParmVarDecl>(SizeOfPack->getPack()))
3362 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003363
3364 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003365}
3366
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003367static SourceLocation getLocationFromExpr(const Expr *E) {
3368 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 return getLocationFromExpr(CE->getSubExpr());
3370
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003371 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003373 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003375 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003377 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003379 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003381 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 return PropRef->getLocation();
3383
3384 return E->getLocStart();
3385}
3386
3387extern "C" {
3388
3389unsigned clang_visitChildren(CXCursor parent,
3390 CXCursorVisitor visitor,
3391 CXClientData client_data) {
3392 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3393 /*VisitPreprocessorLast=*/false);
3394 return CursorVis.VisitChildren(parent);
3395}
3396
3397#ifndef __has_feature
3398#define __has_feature(x) 0
3399#endif
3400#if __has_feature(blocks)
3401typedef enum CXChildVisitResult
3402 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3403
3404static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3405 CXClientData client_data) {
3406 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3407 return block(cursor, parent);
3408}
3409#else
3410// If we are compiled with a compiler that doesn't have native blocks support,
3411// define and call the block manually, so the
3412typedef struct _CXChildVisitResult
3413{
3414 void *isa;
3415 int flags;
3416 int reserved;
3417 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3418 CXCursor);
3419} *CXCursorVisitorBlock;
3420
3421static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3422 CXClientData client_data) {
3423 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3424 return block->invoke(block, cursor, parent);
3425}
3426#endif
3427
3428
3429unsigned clang_visitChildrenWithBlock(CXCursor parent,
3430 CXCursorVisitorBlock block) {
3431 return clang_visitChildren(parent, visitWithBlock, block);
3432}
3433
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003434static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003436 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003437
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003438 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003440 if (const ObjCPropertyImplDecl *PropImpl =
3441 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003443 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003444
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003445 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003447 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003448
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003449 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 }
3451
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003452 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003453 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003454
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003455 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3457 // and returns different names. NamedDecl returns the class name and
3458 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003459 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003460
3461 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003462 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003463
3464 SmallString<1024> S;
3465 llvm::raw_svector_ostream os(S);
3466 ND->printName(os);
3467
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003468 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003469}
3470
3471CXString clang_getCursorSpelling(CXCursor C) {
3472 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003473 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003474
3475 if (clang_isReference(C.kind)) {
3476 switch (C.kind) {
3477 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003478 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003479 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 }
3481 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003482 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003483 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 }
3485 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003486 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003488 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 }
3490 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003491 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003492 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 }
3494 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003495 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 assert(Type && "Missing type decl");
3497
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003498 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 getAsString());
3500 }
3501 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003502 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 assert(Template && "Missing template decl");
3504
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003505 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 }
3507
3508 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003509 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 assert(NS && "Missing namespace decl");
3511
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003512 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003513 }
3514
3515 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003516 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 assert(Field && "Missing member decl");
3518
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003519 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 }
3521
3522 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003523 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 assert(Label && "Missing label");
3525
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003526 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 }
3528
3529 case CXCursor_OverloadedDeclRef: {
3530 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3532 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003533 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003534 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003536 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003537 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 OverloadedTemplateStorage *Ovl
3539 = Storage.get<OverloadedTemplateStorage*>();
3540 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003541 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003542 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 }
3544
3545 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003546 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 assert(Var && "Missing variable decl");
3548
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003549 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003550 }
3551
3552 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003553 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 }
3555 }
3556
3557 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003558 const Expr *E = getCursorExpr(C);
3559
3560 if (C.kind == CXCursor_ObjCStringLiteral ||
3561 C.kind == CXCursor_StringLiteral) {
3562 const StringLiteral *SLit;
3563 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3564 SLit = OSL->getString();
3565 } else {
3566 SLit = cast<StringLiteral>(E);
3567 }
3568 SmallString<256> Buf;
3569 llvm::raw_svector_ostream OS(Buf);
3570 SLit->outputString(OS);
3571 return cxstring::createDup(OS.str());
3572 }
3573
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003574 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 if (D)
3576 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003577 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 }
3579
3580 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003581 const Stmt *S = getCursorStmt(C);
3582 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003583 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003584
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003585 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 }
3587
3588 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003589 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 ->getNameStart());
3591
3592 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003593 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 ->getNameStart());
3595
3596 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003597 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003598
3599 if (clang_isDeclaration(C.kind))
3600 return getDeclSpelling(getCursorDecl(C));
3601
3602 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003603 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003604 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 }
3606
3607 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003608 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003609 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 }
3611
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003612 if (C.kind == CXCursor_PackedAttr) {
3613 return cxstring::createRef("packed");
3614 }
3615
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003616 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003617}
3618
3619CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3620 unsigned pieceIndex,
3621 unsigned options) {
3622 if (clang_Cursor_isNull(C))
3623 return clang_getNullRange();
3624
3625 ASTContext &Ctx = getCursorContext(C);
3626
3627 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003628 const Stmt *S = getCursorStmt(C);
3629 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 if (pieceIndex > 0)
3631 return clang_getNullRange();
3632 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3633 }
3634
3635 return clang_getNullRange();
3636 }
3637
3638 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003639 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3641 if (pieceIndex >= ME->getNumSelectorLocs())
3642 return clang_getNullRange();
3643 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3644 }
3645 }
3646
3647 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3648 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003649 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3651 if (pieceIndex >= MD->getNumSelectorLocs())
3652 return clang_getNullRange();
3653 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3654 }
3655 }
3656
3657 if (C.kind == CXCursor_ObjCCategoryDecl ||
3658 C.kind == CXCursor_ObjCCategoryImplDecl) {
3659 if (pieceIndex > 0)
3660 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003661 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3663 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003664 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3666 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3667 }
3668
3669 if (C.kind == CXCursor_ModuleImportDecl) {
3670 if (pieceIndex > 0)
3671 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003672 if (const ImportDecl *ImportD =
3673 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3675 if (!Locs.empty())
3676 return cxloc::translateSourceRange(Ctx,
3677 SourceRange(Locs.front(), Locs.back()));
3678 }
3679 return clang_getNullRange();
3680 }
3681
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003682 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3683 C.kind == CXCursor_ConversionFunction) {
3684 if (pieceIndex > 0)
3685 return clang_getNullRange();
3686 if (const FunctionDecl *FD =
3687 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3688 DeclarationNameInfo FunctionName = FD->getNameInfo();
3689 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3690 }
3691 return clang_getNullRange();
3692 }
3693
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 // FIXME: A CXCursor_InclusionDirective should give the location of the
3695 // filename, but we don't keep track of this.
3696
3697 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3698 // but we don't keep track of this.
3699
3700 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3701 // but we don't keep track of this.
3702
3703 // Default handling, give the location of the cursor.
3704
3705 if (pieceIndex > 0)
3706 return clang_getNullRange();
3707
3708 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3709 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3710 return cxloc::translateSourceRange(Ctx, Loc);
3711}
3712
Eli Bendersky44a206f2014-07-31 18:04:56 +00003713CXString clang_Cursor_getMangling(CXCursor C) {
3714 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3715 return cxstring::createEmpty();
3716
Eli Bendersky44a206f2014-07-31 18:04:56 +00003717 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003718 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003719 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3720 return cxstring::createEmpty();
3721
Eli Bendersky79759592014-08-01 15:01:10 +00003722 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003723 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003724 ASTContext &Ctx = ND->getASTContext();
3725 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003726
Eli Bendersky79759592014-08-01 15:01:10 +00003727 std::string FrontendBuf;
3728 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3729 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003730
Eli Bendersky79759592014-08-01 15:01:10 +00003731 // Now apply backend mangling.
3732 std::unique_ptr<llvm::DataLayout> DL(
3733 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3734 llvm::Mangler BackendMangler(DL.get());
3735
3736 std::string FinalBuf;
3737 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3738 BackendMangler.getNameWithPrefix(FinalBufOS,
3739 llvm::Twine(FrontendBufOS.str()));
3740
3741 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003742}
3743
Guy Benyei11169dd2012-12-18 14:30:41 +00003744CXString clang_getCursorDisplayName(CXCursor C) {
3745 if (!clang_isDeclaration(C.kind))
3746 return clang_getCursorSpelling(C);
3747
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003748 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003750 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003751
3752 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003753 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 D = FunTmpl->getTemplatedDecl();
3755
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003756 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 SmallString<64> Str;
3758 llvm::raw_svector_ostream OS(Str);
3759 OS << *Function;
3760 if (Function->getPrimaryTemplate())
3761 OS << "<>";
3762 OS << "(";
3763 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3764 if (I)
3765 OS << ", ";
3766 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3767 }
3768
3769 if (Function->isVariadic()) {
3770 if (Function->getNumParams())
3771 OS << ", ";
3772 OS << "...";
3773 }
3774 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003775 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 }
3777
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003778 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 SmallString<64> Str;
3780 llvm::raw_svector_ostream OS(Str);
3781 OS << *ClassTemplate;
3782 OS << "<";
3783 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3784 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3785 if (I)
3786 OS << ", ";
3787
3788 NamedDecl *Param = Params->getParam(I);
3789 if (Param->getIdentifier()) {
3790 OS << Param->getIdentifier()->getName();
3791 continue;
3792 }
3793
3794 // There is no parameter name, which makes this tricky. Try to come up
3795 // with something useful that isn't too long.
3796 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3797 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3798 else if (NonTypeTemplateParmDecl *NTTP
3799 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3800 OS << NTTP->getType().getAsString(Policy);
3801 else
3802 OS << "template<...> class";
3803 }
3804
3805 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003806 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 }
3808
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003809 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3811 // If the type was explicitly written, use that.
3812 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003813 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003814
Benjamin Kramer9170e912013-02-22 15:46:01 +00003815 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 llvm::raw_svector_ostream OS(Str);
3817 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003818 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 ClassSpec->getTemplateArgs().data(),
3820 ClassSpec->getTemplateArgs().size(),
3821 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003822 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 }
3824
3825 return clang_getCursorSpelling(C);
3826}
3827
3828CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3829 switch (Kind) {
3830 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003958 case CXCursor_ObjCSelfExpr:
3959 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004048 case CXCursor_SEHLeaveStmt:
4049 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004073 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004078 case CXCursor_PackedAttr:
4079 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004080 case CXCursor_PureAttr:
4081 return cxstring::createRef("attribute(pure)");
4082 case CXCursor_ConstAttr:
4083 return cxstring::createRef("attribute(const)");
4084 case CXCursor_NoDuplicateAttr:
4085 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004086 case CXCursor_CUDAConstantAttr:
4087 return cxstring::createRef("attribute(constant)");
4088 case CXCursor_CUDADeviceAttr:
4089 return cxstring::createRef("attribute(device)");
4090 case CXCursor_CUDAGlobalAttr:
4091 return cxstring::createRef("attribute(global)");
4092 case CXCursor_CUDAHostAttr:
4093 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004094 case CXCursor_CUDASharedAttr:
4095 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004144 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004145 return cxstring::createRef("OMPParallelDirective");
4146 case CXCursor_OMPSimdDirective:
4147 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004148 case CXCursor_OMPForDirective:
4149 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004150 case CXCursor_OMPForSimdDirective:
4151 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004152 case CXCursor_OMPSectionsDirective:
4153 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004154 case CXCursor_OMPSectionDirective:
4155 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004156 case CXCursor_OMPSingleDirective:
4157 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004158 case CXCursor_OMPMasterDirective:
4159 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004160 case CXCursor_OMPCriticalDirective:
4161 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004162 case CXCursor_OMPParallelForDirective:
4163 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004164 case CXCursor_OMPParallelSectionsDirective:
4165 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004166 case CXCursor_OMPTaskDirective:
4167 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004168 case CXCursor_OMPTaskyieldDirective:
4169 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004170 case CXCursor_OMPBarrierDirective:
4171 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004172 case CXCursor_OMPTaskwaitDirective:
4173 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004174 case CXCursor_OMPFlushDirective:
4175 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004176 case CXCursor_OMPOrderedDirective:
4177 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004178 case CXCursor_OMPAtomicDirective:
4179 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004180 case CXCursor_OMPTargetDirective:
4181 return cxstring::createRef("OMPTargetDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 }
4183
4184 llvm_unreachable("Unhandled CXCursorKind");
4185}
4186
4187struct GetCursorData {
4188 SourceLocation TokenBeginLoc;
4189 bool PointsAtMacroArgExpansion;
4190 bool VisitedObjCPropertyImplDecl;
4191 SourceLocation VisitedDeclaratorDeclStartLoc;
4192 CXCursor &BestCursor;
4193
4194 GetCursorData(SourceManager &SM,
4195 SourceLocation tokenBegin, CXCursor &outputCursor)
4196 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4197 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4198 VisitedObjCPropertyImplDecl = false;
4199 }
4200};
4201
4202static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4203 CXCursor parent,
4204 CXClientData client_data) {
4205 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4206 CXCursor *BestCursor = &Data->BestCursor;
4207
4208 // If we point inside a macro argument we should provide info of what the
4209 // token is so use the actual cursor, don't replace it with a macro expansion
4210 // cursor.
4211 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4212 return CXChildVisit_Recurse;
4213
4214 if (clang_isDeclaration(cursor.kind)) {
4215 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004216 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4218 if (MD->isImplicit())
4219 return CXChildVisit_Break;
4220
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004221 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4223 // Check that when we have multiple @class references in the same line,
4224 // that later ones do not override the previous ones.
4225 // If we have:
4226 // @class Foo, Bar;
4227 // source ranges for both start at '@', so 'Bar' will end up overriding
4228 // 'Foo' even though the cursor location was at 'Foo'.
4229 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4230 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004231 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4233 if (PrevID != ID &&
4234 !PrevID->isThisDeclarationADefinition() &&
4235 !ID->isThisDeclarationADefinition())
4236 return CXChildVisit_Break;
4237 }
4238
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004239 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4241 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4242 // Check that when we have multiple declarators in the same line,
4243 // that later ones do not override the previous ones.
4244 // If we have:
4245 // int Foo, Bar;
4246 // source ranges for both start at 'int', so 'Bar' will end up overriding
4247 // 'Foo' even though the cursor location was at 'Foo'.
4248 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4249 return CXChildVisit_Break;
4250 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4251
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004252 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4254 (void)PropImp;
4255 // Check that when we have multiple @synthesize in the same line,
4256 // that later ones do not override the previous ones.
4257 // If we have:
4258 // @synthesize Foo, Bar;
4259 // source ranges for both start at '@', so 'Bar' will end up overriding
4260 // 'Foo' even though the cursor location was at 'Foo'.
4261 if (Data->VisitedObjCPropertyImplDecl)
4262 return CXChildVisit_Break;
4263 Data->VisitedObjCPropertyImplDecl = true;
4264 }
4265 }
4266
4267 if (clang_isExpression(cursor.kind) &&
4268 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004269 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004270 // Avoid having the cursor of an expression replace the declaration cursor
4271 // when the expression source range overlaps the declaration range.
4272 // This can happen for C++ constructor expressions whose range generally
4273 // include the variable declaration, e.g.:
4274 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4275 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4276 D->getLocation() == Data->TokenBeginLoc)
4277 return CXChildVisit_Break;
4278 }
4279 }
4280
4281 // If our current best cursor is the construction of a temporary object,
4282 // don't replace that cursor with a type reference, because we want
4283 // clang_getCursor() to point at the constructor.
4284 if (clang_isExpression(BestCursor->kind) &&
4285 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4286 cursor.kind == CXCursor_TypeRef) {
4287 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4288 // as having the actual point on the type reference.
4289 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4290 return CXChildVisit_Recurse;
4291 }
4292
4293 *BestCursor = cursor;
4294 return CXChildVisit_Recurse;
4295}
4296
4297CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004298 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004299 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004301 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004302
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004303 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4305
4306 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4307 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4308
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004309 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004310 CXFile SearchFile;
4311 unsigned SearchLine, SearchColumn;
4312 CXFile ResultFile;
4313 unsigned ResultLine, ResultColumn;
4314 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4315 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4316 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004317
4318 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4319 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004320 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004321 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004322 SearchFileName = clang_getFileName(SearchFile);
4323 ResultFileName = clang_getFileName(ResultFile);
4324 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4325 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004326 *Log << llvm::format("(%s:%d:%d) = %s",
4327 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4328 clang_getCString(KindSpelling))
4329 << llvm::format("(%s:%d:%d):%s%s",
4330 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4331 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 clang_disposeString(SearchFileName);
4333 clang_disposeString(ResultFileName);
4334 clang_disposeString(KindSpelling);
4335 clang_disposeString(USR);
4336
4337 CXCursor Definition = clang_getCursorDefinition(Result);
4338 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4339 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4340 CXString DefinitionKindSpelling
4341 = clang_getCursorKindSpelling(Definition.kind);
4342 CXFile DefinitionFile;
4343 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004344 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004345 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004346 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004347 *Log << llvm::format(" -> %s(%s:%d:%d)",
4348 clang_getCString(DefinitionKindSpelling),
4349 clang_getCString(DefinitionFileName),
4350 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004351 clang_disposeString(DefinitionFileName);
4352 clang_disposeString(DefinitionKindSpelling);
4353 }
4354 }
4355
4356 return Result;
4357}
4358
4359CXCursor clang_getNullCursor(void) {
4360 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4361}
4362
4363unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004364 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4365 // can't set consistently. For example, when visiting a DeclStmt we will set
4366 // it but we don't set it on the result of clang_getCursorDefinition for
4367 // a reference of the same declaration.
4368 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4369 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4370 // to provide that kind of info.
4371 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004372 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004373 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004374 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004375
Guy Benyei11169dd2012-12-18 14:30:41 +00004376 return X == Y;
4377}
4378
4379unsigned clang_hashCursor(CXCursor C) {
4380 unsigned Index = 0;
4381 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4382 Index = 1;
4383
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004384 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004385 std::make_pair(C.kind, C.data[Index]));
4386}
4387
4388unsigned clang_isInvalid(enum CXCursorKind K) {
4389 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4390}
4391
4392unsigned clang_isDeclaration(enum CXCursorKind K) {
4393 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4394 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4395}
4396
4397unsigned clang_isReference(enum CXCursorKind K) {
4398 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4399}
4400
4401unsigned clang_isExpression(enum CXCursorKind K) {
4402 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4403}
4404
4405unsigned clang_isStatement(enum CXCursorKind K) {
4406 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4407}
4408
4409unsigned clang_isAttribute(enum CXCursorKind K) {
4410 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4411}
4412
4413unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4414 return K == CXCursor_TranslationUnit;
4415}
4416
4417unsigned clang_isPreprocessing(enum CXCursorKind K) {
4418 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4419}
4420
4421unsigned clang_isUnexposed(enum CXCursorKind K) {
4422 switch (K) {
4423 case CXCursor_UnexposedDecl:
4424 case CXCursor_UnexposedExpr:
4425 case CXCursor_UnexposedStmt:
4426 case CXCursor_UnexposedAttr:
4427 return true;
4428 default:
4429 return false;
4430 }
4431}
4432
4433CXCursorKind clang_getCursorKind(CXCursor C) {
4434 return C.kind;
4435}
4436
4437CXSourceLocation clang_getCursorLocation(CXCursor C) {
4438 if (clang_isReference(C.kind)) {
4439 switch (C.kind) {
4440 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004441 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 = getCursorObjCSuperClassRef(C);
4443 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4444 }
4445
4446 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004447 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004448 = getCursorObjCProtocolRef(C);
4449 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4450 }
4451
4452 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004453 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004454 = getCursorObjCClassRef(C);
4455 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4456 }
4457
4458 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004459 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4461 }
4462
4463 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004464 std::pair<const TemplateDecl *, SourceLocation> P =
4465 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4467 }
4468
4469 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004470 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4472 }
4473
4474 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004475 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4477 }
4478
4479 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004480 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4482 }
4483
4484 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004485 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 if (!BaseSpec)
4487 return clang_getNullLocation();
4488
4489 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4490 return cxloc::translateSourceLocation(getCursorContext(C),
4491 TSInfo->getTypeLoc().getBeginLoc());
4492
4493 return cxloc::translateSourceLocation(getCursorContext(C),
4494 BaseSpec->getLocStart());
4495 }
4496
4497 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004498 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4500 }
4501
4502 case CXCursor_OverloadedDeclRef:
4503 return cxloc::translateSourceLocation(getCursorContext(C),
4504 getCursorOverloadedDeclRef(C).second);
4505
4506 default:
4507 // FIXME: Need a way to enumerate all non-reference cases.
4508 llvm_unreachable("Missed a reference kind");
4509 }
4510 }
4511
4512 if (clang_isExpression(C.kind))
4513 return cxloc::translateSourceLocation(getCursorContext(C),
4514 getLocationFromExpr(getCursorExpr(C)));
4515
4516 if (clang_isStatement(C.kind))
4517 return cxloc::translateSourceLocation(getCursorContext(C),
4518 getCursorStmt(C)->getLocStart());
4519
4520 if (C.kind == CXCursor_PreprocessingDirective) {
4521 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4522 return cxloc::translateSourceLocation(getCursorContext(C), L);
4523 }
4524
4525 if (C.kind == CXCursor_MacroExpansion) {
4526 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004527 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 return cxloc::translateSourceLocation(getCursorContext(C), L);
4529 }
4530
4531 if (C.kind == CXCursor_MacroDefinition) {
4532 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4533 return cxloc::translateSourceLocation(getCursorContext(C), L);
4534 }
4535
4536 if (C.kind == CXCursor_InclusionDirective) {
4537 SourceLocation L
4538 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4539 return cxloc::translateSourceLocation(getCursorContext(C), L);
4540 }
4541
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004542 if (clang_isAttribute(C.kind)) {
4543 SourceLocation L
4544 = cxcursor::getCursorAttr(C)->getLocation();
4545 return cxloc::translateSourceLocation(getCursorContext(C), L);
4546 }
4547
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 if (!clang_isDeclaration(C.kind))
4549 return clang_getNullLocation();
4550
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004551 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 if (!D)
4553 return clang_getNullLocation();
4554
4555 SourceLocation Loc = D->getLocation();
4556 // FIXME: Multiple variables declared in a single declaration
4557 // currently lack the information needed to correctly determine their
4558 // ranges when accounting for the type-specifier. We use context
4559 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4560 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004561 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 if (!cxcursor::isFirstInDeclGroup(C))
4563 Loc = VD->getLocation();
4564 }
4565
4566 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004567 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 Loc = MD->getSelectorStartLoc();
4569
4570 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4571}
4572
4573} // end extern "C"
4574
4575CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4576 assert(TU);
4577
4578 // Guard against an invalid SourceLocation, or we may assert in one
4579 // of the following calls.
4580 if (SLoc.isInvalid())
4581 return clang_getNullCursor();
4582
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004583 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004584
4585 // Translate the given source location to make it point at the beginning of
4586 // the token under the cursor.
4587 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4588 CXXUnit->getASTContext().getLangOpts());
4589
4590 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4591 if (SLoc.isValid()) {
4592 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4593 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4594 /*VisitPreprocessorLast=*/true,
4595 /*VisitIncludedEntities=*/false,
4596 SourceLocation(SLoc));
4597 CursorVis.visitFileRegion();
4598 }
4599
4600 return Result;
4601}
4602
4603static SourceRange getRawCursorExtent(CXCursor C) {
4604 if (clang_isReference(C.kind)) {
4605 switch (C.kind) {
4606 case CXCursor_ObjCSuperClassRef:
4607 return getCursorObjCSuperClassRef(C).second;
4608
4609 case CXCursor_ObjCProtocolRef:
4610 return getCursorObjCProtocolRef(C).second;
4611
4612 case CXCursor_ObjCClassRef:
4613 return getCursorObjCClassRef(C).second;
4614
4615 case CXCursor_TypeRef:
4616 return getCursorTypeRef(C).second;
4617
4618 case CXCursor_TemplateRef:
4619 return getCursorTemplateRef(C).second;
4620
4621 case CXCursor_NamespaceRef:
4622 return getCursorNamespaceRef(C).second;
4623
4624 case CXCursor_MemberRef:
4625 return getCursorMemberRef(C).second;
4626
4627 case CXCursor_CXXBaseSpecifier:
4628 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4629
4630 case CXCursor_LabelRef:
4631 return getCursorLabelRef(C).second;
4632
4633 case CXCursor_OverloadedDeclRef:
4634 return getCursorOverloadedDeclRef(C).second;
4635
4636 case CXCursor_VariableRef:
4637 return getCursorVariableRef(C).second;
4638
4639 default:
4640 // FIXME: Need a way to enumerate all non-reference cases.
4641 llvm_unreachable("Missed a reference kind");
4642 }
4643 }
4644
4645 if (clang_isExpression(C.kind))
4646 return getCursorExpr(C)->getSourceRange();
4647
4648 if (clang_isStatement(C.kind))
4649 return getCursorStmt(C)->getSourceRange();
4650
4651 if (clang_isAttribute(C.kind))
4652 return getCursorAttr(C)->getRange();
4653
4654 if (C.kind == CXCursor_PreprocessingDirective)
4655 return cxcursor::getCursorPreprocessingDirective(C);
4656
4657 if (C.kind == CXCursor_MacroExpansion) {
4658 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004659 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004660 return TU->mapRangeFromPreamble(Range);
4661 }
4662
4663 if (C.kind == CXCursor_MacroDefinition) {
4664 ASTUnit *TU = getCursorASTUnit(C);
4665 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4666 return TU->mapRangeFromPreamble(Range);
4667 }
4668
4669 if (C.kind == CXCursor_InclusionDirective) {
4670 ASTUnit *TU = getCursorASTUnit(C);
4671 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4672 return TU->mapRangeFromPreamble(Range);
4673 }
4674
4675 if (C.kind == CXCursor_TranslationUnit) {
4676 ASTUnit *TU = getCursorASTUnit(C);
4677 FileID MainID = TU->getSourceManager().getMainFileID();
4678 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4679 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4680 return SourceRange(Start, End);
4681 }
4682
4683 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004684 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 if (!D)
4686 return SourceRange();
4687
4688 SourceRange R = D->getSourceRange();
4689 // FIXME: Multiple variables declared in a single declaration
4690 // currently lack the information needed to correctly determine their
4691 // ranges when accounting for the type-specifier. We use context
4692 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4693 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004694 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 if (!cxcursor::isFirstInDeclGroup(C))
4696 R.setBegin(VD->getLocation());
4697 }
4698 return R;
4699 }
4700 return SourceRange();
4701}
4702
4703/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4704/// the decl-specifier-seq for declarations.
4705static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4706 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004707 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004708 if (!D)
4709 return SourceRange();
4710
4711 SourceRange R = D->getSourceRange();
4712
4713 // Adjust the start of the location for declarations preceded by
4714 // declaration specifiers.
4715 SourceLocation StartLoc;
4716 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4717 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4718 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004719 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004720 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4721 StartLoc = TI->getTypeLoc().getLocStart();
4722 }
4723
4724 if (StartLoc.isValid() && R.getBegin().isValid() &&
4725 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4726 R.setBegin(StartLoc);
4727
4728 // FIXME: Multiple variables declared in a single declaration
4729 // currently lack the information needed to correctly determine their
4730 // ranges when accounting for the type-specifier. We use context
4731 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4732 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004733 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 if (!cxcursor::isFirstInDeclGroup(C))
4735 R.setBegin(VD->getLocation());
4736 }
4737
4738 return R;
4739 }
4740
4741 return getRawCursorExtent(C);
4742}
4743
4744extern "C" {
4745
4746CXSourceRange clang_getCursorExtent(CXCursor C) {
4747 SourceRange R = getRawCursorExtent(C);
4748 if (R.isInvalid())
4749 return clang_getNullRange();
4750
4751 return cxloc::translateSourceRange(getCursorContext(C), R);
4752}
4753
4754CXCursor clang_getCursorReferenced(CXCursor C) {
4755 if (clang_isInvalid(C.kind))
4756 return clang_getNullCursor();
4757
4758 CXTranslationUnit tu = getCursorTU(C);
4759 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004760 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 if (!D)
4762 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004763 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004765 if (const ObjCPropertyImplDecl *PropImpl =
4766 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4768 return MakeCXCursor(Property, tu);
4769
4770 return C;
4771 }
4772
4773 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004774 const Expr *E = getCursorExpr(C);
4775 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004776 if (D) {
4777 CXCursor declCursor = MakeCXCursor(D, tu);
4778 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4779 declCursor);
4780 return declCursor;
4781 }
4782
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004783 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 return MakeCursorOverloadedDeclRef(Ovl, tu);
4785
4786 return clang_getNullCursor();
4787 }
4788
4789 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004790 const Stmt *S = getCursorStmt(C);
4791 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004792 if (LabelDecl *label = Goto->getLabel())
4793 if (LabelStmt *labelS = label->getStmt())
4794 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4795
4796 return clang_getNullCursor();
4797 }
4798
4799 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004800 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 return MakeMacroDefinitionCursor(Def, tu);
4802 }
4803
4804 if (!clang_isReference(C.kind))
4805 return clang_getNullCursor();
4806
4807 switch (C.kind) {
4808 case CXCursor_ObjCSuperClassRef:
4809 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4810
4811 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004812 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4813 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 return MakeCXCursor(Def, tu);
4815
4816 return MakeCXCursor(Prot, tu);
4817 }
4818
4819 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004820 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4821 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 return MakeCXCursor(Def, tu);
4823
4824 return MakeCXCursor(Class, tu);
4825 }
4826
4827 case CXCursor_TypeRef:
4828 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4829
4830 case CXCursor_TemplateRef:
4831 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4832
4833 case CXCursor_NamespaceRef:
4834 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4835
4836 case CXCursor_MemberRef:
4837 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4838
4839 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004840 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004841 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4842 tu ));
4843 }
4844
4845 case CXCursor_LabelRef:
4846 // FIXME: We end up faking the "parent" declaration here because we
4847 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004848 return MakeCXCursor(getCursorLabelRef(C).first,
4849 cxtu::getASTUnit(tu)->getASTContext()
4850 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 tu);
4852
4853 case CXCursor_OverloadedDeclRef:
4854 return C;
4855
4856 case CXCursor_VariableRef:
4857 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4858
4859 default:
4860 // We would prefer to enumerate all non-reference cursor kinds here.
4861 llvm_unreachable("Unhandled reference cursor kind");
4862 }
4863}
4864
4865CXCursor clang_getCursorDefinition(CXCursor C) {
4866 if (clang_isInvalid(C.kind))
4867 return clang_getNullCursor();
4868
4869 CXTranslationUnit TU = getCursorTU(C);
4870
4871 bool WasReference = false;
4872 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4873 C = clang_getCursorReferenced(C);
4874 WasReference = true;
4875 }
4876
4877 if (C.kind == CXCursor_MacroExpansion)
4878 return clang_getCursorReferenced(C);
4879
4880 if (!clang_isDeclaration(C.kind))
4881 return clang_getNullCursor();
4882
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004883 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 if (!D)
4885 return clang_getNullCursor();
4886
4887 switch (D->getKind()) {
4888 // Declaration kinds that don't really separate the notions of
4889 // declaration and definition.
4890 case Decl::Namespace:
4891 case Decl::Typedef:
4892 case Decl::TypeAlias:
4893 case Decl::TypeAliasTemplate:
4894 case Decl::TemplateTypeParm:
4895 case Decl::EnumConstant:
4896 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004897 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004898 case Decl::IndirectField:
4899 case Decl::ObjCIvar:
4900 case Decl::ObjCAtDefsField:
4901 case Decl::ImplicitParam:
4902 case Decl::ParmVar:
4903 case Decl::NonTypeTemplateParm:
4904 case Decl::TemplateTemplateParm:
4905 case Decl::ObjCCategoryImpl:
4906 case Decl::ObjCImplementation:
4907 case Decl::AccessSpec:
4908 case Decl::LinkageSpec:
4909 case Decl::ObjCPropertyImpl:
4910 case Decl::FileScopeAsm:
4911 case Decl::StaticAssert:
4912 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004913 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 case Decl::Label: // FIXME: Is this right??
4915 case Decl::ClassScopeFunctionSpecialization:
4916 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004917 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004918 return C;
4919
4920 // Declaration kinds that don't make any sense here, but are
4921 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004922 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 case Decl::TranslationUnit:
4924 break;
4925
4926 // Declaration kinds for which the definition is not resolvable.
4927 case Decl::UnresolvedUsingTypename:
4928 case Decl::UnresolvedUsingValue:
4929 break;
4930
4931 case Decl::UsingDirective:
4932 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4933 TU);
4934
4935 case Decl::NamespaceAlias:
4936 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4937
4938 case Decl::Enum:
4939 case Decl::Record:
4940 case Decl::CXXRecord:
4941 case Decl::ClassTemplateSpecialization:
4942 case Decl::ClassTemplatePartialSpecialization:
4943 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4944 return MakeCXCursor(Def, TU);
4945 return clang_getNullCursor();
4946
4947 case Decl::Function:
4948 case Decl::CXXMethod:
4949 case Decl::CXXConstructor:
4950 case Decl::CXXDestructor:
4951 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004952 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004954 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 return clang_getNullCursor();
4956 }
4957
Larisse Voufo39a1e502013-08-06 01:03:05 +00004958 case Decl::Var:
4959 case Decl::VarTemplateSpecialization:
4960 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004961 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004962 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004963 return MakeCXCursor(Def, TU);
4964 return clang_getNullCursor();
4965 }
4966
4967 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004968 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004969 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4970 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4971 return clang_getNullCursor();
4972 }
4973
4974 case Decl::ClassTemplate: {
4975 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4976 ->getDefinition())
4977 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4978 TU);
4979 return clang_getNullCursor();
4980 }
4981
Larisse Voufo39a1e502013-08-06 01:03:05 +00004982 case Decl::VarTemplate: {
4983 if (VarDecl *Def =
4984 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4985 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4986 return clang_getNullCursor();
4987 }
4988
Guy Benyei11169dd2012-12-18 14:30:41 +00004989 case Decl::Using:
4990 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4991 D->getLocation(), TU);
4992
4993 case Decl::UsingShadow:
4994 return clang_getCursorDefinition(
4995 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4996 TU));
4997
4998 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004999 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 if (Method->isThisDeclarationADefinition())
5001 return C;
5002
5003 // Dig out the method definition in the associated
5004 // @implementation, if we have it.
5005 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005006 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5008 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5009 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5010 Method->isInstanceMethod()))
5011 if (Def->isThisDeclarationADefinition())
5012 return MakeCXCursor(Def, TU);
5013
5014 return clang_getNullCursor();
5015 }
5016
5017 case Decl::ObjCCategory:
5018 if (ObjCCategoryImplDecl *Impl
5019 = cast<ObjCCategoryDecl>(D)->getImplementation())
5020 return MakeCXCursor(Impl, TU);
5021 return clang_getNullCursor();
5022
5023 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005024 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005025 return MakeCXCursor(Def, TU);
5026 return clang_getNullCursor();
5027
5028 case Decl::ObjCInterface: {
5029 // There are two notions of a "definition" for an Objective-C
5030 // class: the interface and its implementation. When we resolved a
5031 // reference to an Objective-C class, produce the @interface as
5032 // the definition; when we were provided with the interface,
5033 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005034 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005035 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005036 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005037 return MakeCXCursor(Def, TU);
5038 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5039 return MakeCXCursor(Impl, TU);
5040 return clang_getNullCursor();
5041 }
5042
5043 case Decl::ObjCProperty:
5044 // FIXME: We don't really know where to find the
5045 // ObjCPropertyImplDecls that implement this property.
5046 return clang_getNullCursor();
5047
5048 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005049 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005051 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005052 return MakeCXCursor(Def, TU);
5053
5054 return clang_getNullCursor();
5055
5056 case Decl::Friend:
5057 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5058 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5059 return clang_getNullCursor();
5060
5061 case Decl::FriendTemplate:
5062 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5063 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5064 return clang_getNullCursor();
5065 }
5066
5067 return clang_getNullCursor();
5068}
5069
5070unsigned clang_isCursorDefinition(CXCursor C) {
5071 if (!clang_isDeclaration(C.kind))
5072 return 0;
5073
5074 return clang_getCursorDefinition(C) == C;
5075}
5076
5077CXCursor clang_getCanonicalCursor(CXCursor C) {
5078 if (!clang_isDeclaration(C.kind))
5079 return C;
5080
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005081 if (const Decl *D = getCursorDecl(C)) {
5082 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5084 return MakeCXCursor(CatD, getCursorTU(C));
5085
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005086 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5087 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005088 return MakeCXCursor(IFD, getCursorTU(C));
5089
5090 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5091 }
5092
5093 return C;
5094}
5095
5096int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5097 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5098}
5099
5100unsigned clang_getNumOverloadedDecls(CXCursor C) {
5101 if (C.kind != CXCursor_OverloadedDeclRef)
5102 return 0;
5103
5104 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005105 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 return E->getNumDecls();
5107
5108 if (OverloadedTemplateStorage *S
5109 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5110 return S->size();
5111
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005112 const Decl *D = Storage.get<const Decl *>();
5113 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 return Using->shadow_size();
5115
5116 return 0;
5117}
5118
5119CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5120 if (cursor.kind != CXCursor_OverloadedDeclRef)
5121 return clang_getNullCursor();
5122
5123 if (index >= clang_getNumOverloadedDecls(cursor))
5124 return clang_getNullCursor();
5125
5126 CXTranslationUnit TU = getCursorTU(cursor);
5127 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005128 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005129 return MakeCXCursor(E->decls_begin()[index], TU);
5130
5131 if (OverloadedTemplateStorage *S
5132 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5133 return MakeCXCursor(S->begin()[index], TU);
5134
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005135 const Decl *D = Storage.get<const Decl *>();
5136 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005137 // FIXME: This is, unfortunately, linear time.
5138 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5139 std::advance(Pos, index);
5140 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5141 }
5142
5143 return clang_getNullCursor();
5144}
5145
5146void clang_getDefinitionSpellingAndExtent(CXCursor C,
5147 const char **startBuf,
5148 const char **endBuf,
5149 unsigned *startLine,
5150 unsigned *startColumn,
5151 unsigned *endLine,
5152 unsigned *endColumn) {
5153 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005154 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005155 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5156
5157 SourceManager &SM = FD->getASTContext().getSourceManager();
5158 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5159 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5160 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5161 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5162 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5163 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5164}
5165
5166
5167CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5168 unsigned PieceIndex) {
5169 RefNamePieces Pieces;
5170
5171 switch (C.kind) {
5172 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005173 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5175 E->getQualifierLoc().getSourceRange());
5176 break;
5177
5178 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005179 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5181 E->getQualifierLoc().getSourceRange(),
5182 E->getOptionalExplicitTemplateArgs());
5183 break;
5184
5185 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005186 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005187 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005188 const Expr *Callee = OCE->getCallee();
5189 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 Callee = ICE->getSubExpr();
5191
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005192 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5194 DRE->getQualifierLoc().getSourceRange());
5195 }
5196 break;
5197
5198 default:
5199 break;
5200 }
5201
5202 if (Pieces.empty()) {
5203 if (PieceIndex == 0)
5204 return clang_getCursorExtent(C);
5205 } else if (PieceIndex < Pieces.size()) {
5206 SourceRange R = Pieces[PieceIndex];
5207 if (R.isValid())
5208 return cxloc::translateSourceRange(getCursorContext(C), R);
5209 }
5210
5211 return clang_getNullRange();
5212}
5213
5214void clang_enableStackTraces(void) {
5215 llvm::sys::PrintStackTraceOnErrorSignal();
5216}
5217
5218void clang_executeOnThread(void (*fn)(void*), void *user_data,
5219 unsigned stack_size) {
5220 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5221}
5222
5223} // end: extern "C"
5224
5225//===----------------------------------------------------------------------===//
5226// Token-based Operations.
5227//===----------------------------------------------------------------------===//
5228
5229/* CXToken layout:
5230 * int_data[0]: a CXTokenKind
5231 * int_data[1]: starting token location
5232 * int_data[2]: token length
5233 * int_data[3]: reserved
5234 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5235 * otherwise unused.
5236 */
5237extern "C" {
5238
5239CXTokenKind clang_getTokenKind(CXToken CXTok) {
5240 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5241}
5242
5243CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5244 switch (clang_getTokenKind(CXTok)) {
5245 case CXToken_Identifier:
5246 case CXToken_Keyword:
5247 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005248 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005249 ->getNameStart());
5250
5251 case CXToken_Literal: {
5252 // We have stashed the starting pointer in the ptr_data field. Use it.
5253 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005254 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 }
5256
5257 case CXToken_Punctuation:
5258 case CXToken_Comment:
5259 break;
5260 }
5261
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005262 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005263 LOG_BAD_TU(TU);
5264 return cxstring::createEmpty();
5265 }
5266
Guy Benyei11169dd2012-12-18 14:30:41 +00005267 // We have to find the starting buffer pointer the hard way, by
5268 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005269 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005271 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005272
5273 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5274 std::pair<FileID, unsigned> LocInfo
5275 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5276 bool Invalid = false;
5277 StringRef Buffer
5278 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5279 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005280 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005281
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005282 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005283}
5284
5285CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005286 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005287 LOG_BAD_TU(TU);
5288 return clang_getNullLocation();
5289 }
5290
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005291 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 if (!CXXUnit)
5293 return clang_getNullLocation();
5294
5295 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5296 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5297}
5298
5299CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005300 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005301 LOG_BAD_TU(TU);
5302 return clang_getNullRange();
5303 }
5304
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005305 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 if (!CXXUnit)
5307 return clang_getNullRange();
5308
5309 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5310 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5311}
5312
5313static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5314 SmallVectorImpl<CXToken> &CXTokens) {
5315 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5316 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005317 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005319 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005320
5321 // Cannot tokenize across files.
5322 if (BeginLocInfo.first != EndLocInfo.first)
5323 return;
5324
5325 // Create a lexer
5326 bool Invalid = false;
5327 StringRef Buffer
5328 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5329 if (Invalid)
5330 return;
5331
5332 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5333 CXXUnit->getASTContext().getLangOpts(),
5334 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5335 Lex.SetCommentRetentionState(true);
5336
5337 // Lex tokens until we hit the end of the range.
5338 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5339 Token Tok;
5340 bool previousWasAt = false;
5341 do {
5342 // Lex the next token
5343 Lex.LexFromRawLexer(Tok);
5344 if (Tok.is(tok::eof))
5345 break;
5346
5347 // Initialize the CXToken.
5348 CXToken CXTok;
5349
5350 // - Common fields
5351 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5352 CXTok.int_data[2] = Tok.getLength();
5353 CXTok.int_data[3] = 0;
5354
5355 // - Kind-specific fields
5356 if (Tok.isLiteral()) {
5357 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005358 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005359 } else if (Tok.is(tok::raw_identifier)) {
5360 // Lookup the identifier to determine whether we have a keyword.
5361 IdentifierInfo *II
5362 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5363
5364 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5365 CXTok.int_data[0] = CXToken_Keyword;
5366 }
5367 else {
5368 CXTok.int_data[0] = Tok.is(tok::identifier)
5369 ? CXToken_Identifier
5370 : CXToken_Keyword;
5371 }
5372 CXTok.ptr_data = II;
5373 } else if (Tok.is(tok::comment)) {
5374 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005375 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 } else {
5377 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005378 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005379 }
5380 CXTokens.push_back(CXTok);
5381 previousWasAt = Tok.is(tok::at);
5382 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5383}
5384
5385void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5386 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005387 LOG_FUNC_SECTION {
5388 *Log << TU << ' ' << Range;
5389 }
5390
Guy Benyei11169dd2012-12-18 14:30:41 +00005391 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005392 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005393 if (NumTokens)
5394 *NumTokens = 0;
5395
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005396 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005397 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005398 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005399 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005400
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005401 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005402 if (!CXXUnit || !Tokens || !NumTokens)
5403 return;
5404
5405 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5406
5407 SourceRange R = cxloc::translateCXSourceRange(Range);
5408 if (R.isInvalid())
5409 return;
5410
5411 SmallVector<CXToken, 32> CXTokens;
5412 getTokens(CXXUnit, R, CXTokens);
5413
5414 if (CXTokens.empty())
5415 return;
5416
5417 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5418 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5419 *NumTokens = CXTokens.size();
5420}
5421
5422void clang_disposeTokens(CXTranslationUnit TU,
5423 CXToken *Tokens, unsigned NumTokens) {
5424 free(Tokens);
5425}
5426
5427} // end: extern "C"
5428
5429//===----------------------------------------------------------------------===//
5430// Token annotation APIs.
5431//===----------------------------------------------------------------------===//
5432
Guy Benyei11169dd2012-12-18 14:30:41 +00005433static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5434 CXCursor parent,
5435 CXClientData client_data);
5436static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5437 CXClientData client_data);
5438
5439namespace {
5440class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 CXToken *Tokens;
5442 CXCursor *Cursors;
5443 unsigned NumTokens;
5444 unsigned TokIdx;
5445 unsigned PreprocessingTokIdx;
5446 CursorVisitor AnnotateVis;
5447 SourceManager &SrcMgr;
5448 bool HasContextSensitiveKeywords;
5449
5450 struct PostChildrenInfo {
5451 CXCursor Cursor;
5452 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005453 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005454 unsigned BeforeChildrenTokenIdx;
5455 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005456 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005457
5458 CXToken &getTok(unsigned Idx) {
5459 assert(Idx < NumTokens);
5460 return Tokens[Idx];
5461 }
5462 const CXToken &getTok(unsigned Idx) const {
5463 assert(Idx < NumTokens);
5464 return Tokens[Idx];
5465 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005466 bool MoreTokens() const { return TokIdx < NumTokens; }
5467 unsigned NextToken() const { return TokIdx; }
5468 void AdvanceToken() { ++TokIdx; }
5469 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005470 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 }
5472 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005473 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 }
5475 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005476 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 }
5478
5479 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005480 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 SourceRange);
5482
5483public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005484 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005485 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005486 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005488 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 AnnotateTokensVisitor, this,
5490 /*VisitPreprocessorLast=*/true,
5491 /*VisitIncludedEntities=*/false,
5492 RegionOfInterest,
5493 /*VisitDeclsOnly=*/false,
5494 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005495 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005496 HasContextSensitiveKeywords(false) { }
5497
5498 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5499 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5500 bool postVisitChildren(CXCursor cursor);
5501 void AnnotateTokens();
5502
5503 /// \brief Determine whether the annotator saw any cursors that have
5504 /// context-sensitive keywords.
5505 bool hasContextSensitiveKeywords() const {
5506 return HasContextSensitiveKeywords;
5507 }
5508
5509 ~AnnotateTokensWorker() {
5510 assert(PostChildrenInfos.empty());
5511 }
5512};
5513}
5514
5515void AnnotateTokensWorker::AnnotateTokens() {
5516 // Walk the AST within the region of interest, annotating tokens
5517 // along the way.
5518 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005519}
Guy Benyei11169dd2012-12-18 14:30:41 +00005520
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005521static inline void updateCursorAnnotation(CXCursor &Cursor,
5522 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005523 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005524 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005525 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005526}
5527
5528/// \brief It annotates and advances tokens with a cursor until the comparison
5529//// between the cursor location and the source range is the same as
5530/// \arg compResult.
5531///
5532/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5533/// Pass RangeOverlap to annotate tokens inside a range.
5534void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5535 RangeComparisonResult compResult,
5536 SourceRange range) {
5537 while (MoreTokens()) {
5538 const unsigned I = NextToken();
5539 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005540 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5541 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005542
5543 SourceLocation TokLoc = GetTokenLoc(I);
5544 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005545 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 AdvanceToken();
5547 continue;
5548 }
5549 break;
5550 }
5551}
5552
5553/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005554/// \returns true if it advanced beyond all macro tokens, false otherwise.
5555bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 CXCursor updateC,
5557 RangeComparisonResult compResult,
5558 SourceRange range) {
5559 assert(MoreTokens());
5560 assert(isFunctionMacroToken(NextToken()) &&
5561 "Should be called only for macro arg tokens");
5562
5563 // This works differently than annotateAndAdvanceTokens; because expanded
5564 // macro arguments can have arbitrary translation-unit source order, we do not
5565 // advance the token index one by one until a token fails the range test.
5566 // We only advance once past all of the macro arg tokens if all of them
5567 // pass the range test. If one of them fails we keep the token index pointing
5568 // at the start of the macro arg tokens so that the failing token will be
5569 // annotated by a subsequent annotation try.
5570
5571 bool atLeastOneCompFail = false;
5572
5573 unsigned I = NextToken();
5574 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5575 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5576 if (TokLoc.isFileID())
5577 continue; // not macro arg token, it's parens or comma.
5578 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5579 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5580 Cursors[I] = updateC;
5581 } else
5582 atLeastOneCompFail = true;
5583 }
5584
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005585 if (atLeastOneCompFail)
5586 return false;
5587
5588 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5589 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005590}
5591
5592enum CXChildVisitResult
5593AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005594 SourceRange cursorRange = getRawCursorExtent(cursor);
5595 if (cursorRange.isInvalid())
5596 return CXChildVisit_Recurse;
5597
5598 if (!HasContextSensitiveKeywords) {
5599 // Objective-C properties can have context-sensitive keywords.
5600 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005601 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005602 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5603 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5604 }
5605 // Objective-C methods can have context-sensitive keywords.
5606 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5607 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005608 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005609 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5610 if (Method->getObjCDeclQualifier())
5611 HasContextSensitiveKeywords = true;
5612 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005613 for (const auto *P : Method->params()) {
5614 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005615 HasContextSensitiveKeywords = true;
5616 break;
5617 }
5618 }
5619 }
5620 }
5621 }
5622 // C++ methods can have context-sensitive keywords.
5623 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005624 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5626 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5627 HasContextSensitiveKeywords = true;
5628 }
5629 }
5630 // C++ classes can have context-sensitive keywords.
5631 else if (cursor.kind == CXCursor_StructDecl ||
5632 cursor.kind == CXCursor_ClassDecl ||
5633 cursor.kind == CXCursor_ClassTemplate ||
5634 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005635 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005636 if (D->hasAttr<FinalAttr>())
5637 HasContextSensitiveKeywords = true;
5638 }
5639 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005640
5641 // Don't override a property annotation with its getter/setter method.
5642 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5643 parent.kind == CXCursor_ObjCPropertyDecl)
5644 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005645
5646 if (clang_isPreprocessing(cursor.kind)) {
5647 // Items in the preprocessing record are kept separate from items in
5648 // declarations, so we keep a separate token index.
5649 unsigned SavedTokIdx = TokIdx;
5650 TokIdx = PreprocessingTokIdx;
5651
5652 // Skip tokens up until we catch up to the beginning of the preprocessing
5653 // entry.
5654 while (MoreTokens()) {
5655 const unsigned I = NextToken();
5656 SourceLocation TokLoc = GetTokenLoc(I);
5657 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5658 case RangeBefore:
5659 AdvanceToken();
5660 continue;
5661 case RangeAfter:
5662 case RangeOverlap:
5663 break;
5664 }
5665 break;
5666 }
5667
5668 // Look at all of the tokens within this range.
5669 while (MoreTokens()) {
5670 const unsigned I = NextToken();
5671 SourceLocation TokLoc = GetTokenLoc(I);
5672 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5673 case RangeBefore:
5674 llvm_unreachable("Infeasible");
5675 case RangeAfter:
5676 break;
5677 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005678 // For macro expansions, just note where the beginning of the macro
5679 // expansion occurs.
5680 if (cursor.kind == CXCursor_MacroExpansion) {
5681 if (TokLoc == cursorRange.getBegin())
5682 Cursors[I] = cursor;
5683 AdvanceToken();
5684 break;
5685 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005686 // We may have already annotated macro names inside macro definitions.
5687 if (Cursors[I].kind != CXCursor_MacroExpansion)
5688 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005689 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 continue;
5691 }
5692 break;
5693 }
5694
5695 // Save the preprocessing token index; restore the non-preprocessing
5696 // token index.
5697 PreprocessingTokIdx = TokIdx;
5698 TokIdx = SavedTokIdx;
5699 return CXChildVisit_Recurse;
5700 }
5701
5702 if (cursorRange.isInvalid())
5703 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005704
5705 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005706 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005707 const enum CXCursorKind K = clang_getCursorKind(parent);
5708 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005709 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5710 // Attributes are annotated out-of-order, skip tokens until we reach it.
5711 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005712 ? clang_getNullCursor() : parent;
5713
5714 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5715
5716 // Avoid having the cursor of an expression "overwrite" the annotation of the
5717 // variable declaration that it belongs to.
5718 // This can happen for C++ constructor expressions whose range generally
5719 // include the variable declaration, e.g.:
5720 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005721 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005722 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005723 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 const unsigned I = NextToken();
5725 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5726 E->getLocStart() == D->getLocation() &&
5727 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005728 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005729 AdvanceToken();
5730 }
5731 }
5732 }
5733
5734 // Before recursing into the children keep some state that we are going
5735 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5736 // extra work after the child nodes are visited.
5737 // Note that we don't call VisitChildren here to avoid traversing statements
5738 // code-recursively which can blow the stack.
5739
5740 PostChildrenInfo Info;
5741 Info.Cursor = cursor;
5742 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005743 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005744 Info.BeforeChildrenTokenIdx = NextToken();
5745 PostChildrenInfos.push_back(Info);
5746
5747 return CXChildVisit_Recurse;
5748}
5749
5750bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5751 if (PostChildrenInfos.empty())
5752 return false;
5753 const PostChildrenInfo &Info = PostChildrenInfos.back();
5754 if (!clang_equalCursors(Info.Cursor, cursor))
5755 return false;
5756
5757 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5758 const unsigned AfterChildren = NextToken();
5759 SourceRange cursorRange = Info.CursorRange;
5760
5761 // Scan the tokens that are at the end of the cursor, but are not captured
5762 // but the child cursors.
5763 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5764
5765 // Scan the tokens that are at the beginning of the cursor, but are not
5766 // capture by the child cursors.
5767 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5768 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5769 break;
5770
5771 Cursors[I] = cursor;
5772 }
5773
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005774 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5775 // encountered the attribute cursor.
5776 if (clang_isAttribute(cursor.kind))
5777 TokIdx = Info.BeforeReachingCursorIdx;
5778
Guy Benyei11169dd2012-12-18 14:30:41 +00005779 PostChildrenInfos.pop_back();
5780 return false;
5781}
5782
5783static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5784 CXCursor parent,
5785 CXClientData client_data) {
5786 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5787}
5788
5789static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5790 CXClientData client_data) {
5791 return static_cast<AnnotateTokensWorker*>(client_data)->
5792 postVisitChildren(cursor);
5793}
5794
5795namespace {
5796
5797/// \brief Uses the macro expansions in the preprocessing record to find
5798/// and mark tokens that are macro arguments. This info is used by the
5799/// AnnotateTokensWorker.
5800class MarkMacroArgTokensVisitor {
5801 SourceManager &SM;
5802 CXToken *Tokens;
5803 unsigned NumTokens;
5804 unsigned CurIdx;
5805
5806public:
5807 MarkMacroArgTokensVisitor(SourceManager &SM,
5808 CXToken *tokens, unsigned numTokens)
5809 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5810
5811 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5812 if (cursor.kind != CXCursor_MacroExpansion)
5813 return CXChildVisit_Continue;
5814
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005815 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005816 if (macroRange.getBegin() == macroRange.getEnd())
5817 return CXChildVisit_Continue; // it's not a function macro.
5818
5819 for (; CurIdx < NumTokens; ++CurIdx) {
5820 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5821 macroRange.getBegin()))
5822 break;
5823 }
5824
5825 if (CurIdx == NumTokens)
5826 return CXChildVisit_Break;
5827
5828 for (; CurIdx < NumTokens; ++CurIdx) {
5829 SourceLocation tokLoc = getTokenLoc(CurIdx);
5830 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5831 break;
5832
5833 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5834 }
5835
5836 if (CurIdx == NumTokens)
5837 return CXChildVisit_Break;
5838
5839 return CXChildVisit_Continue;
5840 }
5841
5842private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005843 CXToken &getTok(unsigned Idx) {
5844 assert(Idx < NumTokens);
5845 return Tokens[Idx];
5846 }
5847 const CXToken &getTok(unsigned Idx) const {
5848 assert(Idx < NumTokens);
5849 return Tokens[Idx];
5850 }
5851
Guy Benyei11169dd2012-12-18 14:30:41 +00005852 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005853 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005854 }
5855
5856 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5857 // The third field is reserved and currently not used. Use it here
5858 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005859 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005860 }
5861};
5862
5863} // end anonymous namespace
5864
5865static CXChildVisitResult
5866MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5867 CXClientData client_data) {
5868 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5869 parent);
5870}
5871
5872namespace {
5873 struct clang_annotateTokens_Data {
5874 CXTranslationUnit TU;
5875 ASTUnit *CXXUnit;
5876 CXToken *Tokens;
5877 unsigned NumTokens;
5878 CXCursor *Cursors;
5879 };
5880}
5881
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005882/// \brief Used by \c annotatePreprocessorTokens.
5883/// \returns true if lexing was finished, false otherwise.
5884static bool lexNext(Lexer &Lex, Token &Tok,
5885 unsigned &NextIdx, unsigned NumTokens) {
5886 if (NextIdx >= NumTokens)
5887 return true;
5888
5889 ++NextIdx;
5890 Lex.LexFromRawLexer(Tok);
5891 if (Tok.is(tok::eof))
5892 return true;
5893
5894 return false;
5895}
5896
Guy Benyei11169dd2012-12-18 14:30:41 +00005897static void annotatePreprocessorTokens(CXTranslationUnit TU,
5898 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005899 CXCursor *Cursors,
5900 CXToken *Tokens,
5901 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005902 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005903
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005904 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005905 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5906 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005907 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005908 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005909 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005910
5911 if (BeginLocInfo.first != EndLocInfo.first)
5912 return;
5913
5914 StringRef Buffer;
5915 bool Invalid = false;
5916 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5917 if (Buffer.empty() || Invalid)
5918 return;
5919
5920 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5921 CXXUnit->getASTContext().getLangOpts(),
5922 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5923 Buffer.end());
5924 Lex.SetCommentRetentionState(true);
5925
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005926 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005927 // Lex tokens in raw mode until we hit the end of the range, to avoid
5928 // entering #includes or expanding macros.
5929 while (true) {
5930 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005931 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5932 break;
5933 unsigned TokIdx = NextIdx-1;
5934 assert(Tok.getLocation() ==
5935 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005936
5937 reprocess:
5938 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005939 // We have found a preprocessing directive. Annotate the tokens
5940 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005941 //
5942 // FIXME: Some simple tests here could identify macro definitions and
5943 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005944
5945 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005946 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5947 break;
5948
Craig Topper69186e72014-06-08 08:38:04 +00005949 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005950 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005951 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5952 break;
5953
5954 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005955 IdentifierInfo &II =
5956 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005957 SourceLocation MappedTokLoc =
5958 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5959 MI = getMacroInfo(II, MappedTokLoc, TU);
5960 }
5961 }
5962
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005963 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005964 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005965 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5966 finished = true;
5967 break;
5968 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005969 // If we are in a macro definition, check if the token was ever a
5970 // macro name and annotate it if that's the case.
5971 if (MI) {
5972 SourceLocation SaveLoc = Tok.getLocation();
5973 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5974 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5975 Tok.setLocation(SaveLoc);
5976 if (MacroDef)
5977 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5978 Tok.getLocation(), TU);
5979 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005980 } while (!Tok.isAtStartOfLine());
5981
5982 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5983 assert(TokIdx <= LastIdx);
5984 SourceLocation EndLoc =
5985 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5986 CXCursor Cursor =
5987 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5988
5989 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005990 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005991
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005992 if (finished)
5993 break;
5994 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005995 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005996 }
5997}
5998
5999// This gets run a separate thread to avoid stack blowout.
6000static void clang_annotateTokensImpl(void *UserData) {
6001 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6002 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6003 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6004 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6005 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6006
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006007 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006008 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6009 setThreadBackgroundPriority();
6010
6011 // Determine the region of interest, which contains all of the tokens.
6012 SourceRange RegionOfInterest;
6013 RegionOfInterest.setBegin(
6014 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6015 RegionOfInterest.setEnd(
6016 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6017 Tokens[NumTokens-1])));
6018
Guy Benyei11169dd2012-12-18 14:30:41 +00006019 // Relex the tokens within the source range to look for preprocessing
6020 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006021 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006022
6023 // If begin location points inside a macro argument, set it to the expansion
6024 // location so we can have the full context when annotating semantically.
6025 {
6026 SourceManager &SM = CXXUnit->getSourceManager();
6027 SourceLocation Loc =
6028 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6029 if (Loc.isMacroID())
6030 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6031 }
6032
Guy Benyei11169dd2012-12-18 14:30:41 +00006033 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6034 // Search and mark tokens that are macro argument expansions.
6035 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6036 Tokens, NumTokens);
6037 CursorVisitor MacroArgMarker(TU,
6038 MarkMacroArgTokensVisitorDelegate, &Visitor,
6039 /*VisitPreprocessorLast=*/true,
6040 /*VisitIncludedEntities=*/false,
6041 RegionOfInterest);
6042 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6043 }
6044
6045 // Annotate all of the source locations in the region of interest that map to
6046 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006047 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006048
6049 // FIXME: We use a ridiculous stack size here because the data-recursion
6050 // algorithm uses a large stack frame than the non-data recursive version,
6051 // and AnnotationTokensWorker currently transforms the data-recursion
6052 // algorithm back into a traditional recursion by explicitly calling
6053 // VisitChildren(). We will need to remove this explicit recursive call.
6054 W.AnnotateTokens();
6055
6056 // If we ran into any entities that involve context-sensitive keywords,
6057 // take another pass through the tokens to mark them as such.
6058 if (W.hasContextSensitiveKeywords()) {
6059 for (unsigned I = 0; I != NumTokens; ++I) {
6060 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6061 continue;
6062
6063 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6064 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006065 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006066 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6067 if (Property->getPropertyAttributesAsWritten() != 0 &&
6068 llvm::StringSwitch<bool>(II->getName())
6069 .Case("readonly", true)
6070 .Case("assign", true)
6071 .Case("unsafe_unretained", true)
6072 .Case("readwrite", true)
6073 .Case("retain", true)
6074 .Case("copy", true)
6075 .Case("nonatomic", true)
6076 .Case("atomic", true)
6077 .Case("getter", true)
6078 .Case("setter", true)
6079 .Case("strong", true)
6080 .Case("weak", true)
6081 .Default(false))
6082 Tokens[I].int_data[0] = CXToken_Keyword;
6083 }
6084 continue;
6085 }
6086
6087 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6088 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6089 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6090 if (llvm::StringSwitch<bool>(II->getName())
6091 .Case("in", true)
6092 .Case("out", true)
6093 .Case("inout", true)
6094 .Case("oneway", true)
6095 .Case("bycopy", true)
6096 .Case("byref", true)
6097 .Default(false))
6098 Tokens[I].int_data[0] = CXToken_Keyword;
6099 continue;
6100 }
6101
6102 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6103 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6104 Tokens[I].int_data[0] = CXToken_Keyword;
6105 continue;
6106 }
6107 }
6108 }
6109}
6110
6111extern "C" {
6112
6113void clang_annotateTokens(CXTranslationUnit TU,
6114 CXToken *Tokens, unsigned NumTokens,
6115 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006116 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006117 LOG_BAD_TU(TU);
6118 return;
6119 }
6120 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006121 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006122 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006123 }
6124
6125 LOG_FUNC_SECTION {
6126 *Log << TU << ' ';
6127 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6128 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6129 *Log << clang_getRange(bloc, eloc);
6130 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006131
6132 // Any token we don't specifically annotate will have a NULL cursor.
6133 CXCursor C = clang_getNullCursor();
6134 for (unsigned I = 0; I != NumTokens; ++I)
6135 Cursors[I] = C;
6136
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006137 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006138 if (!CXXUnit)
6139 return;
6140
6141 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6142
6143 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6144 llvm::CrashRecoveryContext CRC;
6145 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6146 GetSafetyThreadStackSize() * 2)) {
6147 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6148 }
6149}
6150
6151} // end: extern "C"
6152
6153//===----------------------------------------------------------------------===//
6154// Operations for querying linkage of a cursor.
6155//===----------------------------------------------------------------------===//
6156
6157extern "C" {
6158CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6159 if (!clang_isDeclaration(cursor.kind))
6160 return CXLinkage_Invalid;
6161
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006162 const Decl *D = cxcursor::getCursorDecl(cursor);
6163 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006164 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006165 case NoLinkage:
6166 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006167 case InternalLinkage: return CXLinkage_Internal;
6168 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6169 case ExternalLinkage: return CXLinkage_External;
6170 };
6171
6172 return CXLinkage_Invalid;
6173}
6174} // end: extern "C"
6175
6176//===----------------------------------------------------------------------===//
6177// Operations for querying language of a cursor.
6178//===----------------------------------------------------------------------===//
6179
6180static CXLanguageKind getDeclLanguage(const Decl *D) {
6181 if (!D)
6182 return CXLanguage_C;
6183
6184 switch (D->getKind()) {
6185 default:
6186 break;
6187 case Decl::ImplicitParam:
6188 case Decl::ObjCAtDefsField:
6189 case Decl::ObjCCategory:
6190 case Decl::ObjCCategoryImpl:
6191 case Decl::ObjCCompatibleAlias:
6192 case Decl::ObjCImplementation:
6193 case Decl::ObjCInterface:
6194 case Decl::ObjCIvar:
6195 case Decl::ObjCMethod:
6196 case Decl::ObjCProperty:
6197 case Decl::ObjCPropertyImpl:
6198 case Decl::ObjCProtocol:
6199 return CXLanguage_ObjC;
6200 case Decl::CXXConstructor:
6201 case Decl::CXXConversion:
6202 case Decl::CXXDestructor:
6203 case Decl::CXXMethod:
6204 case Decl::CXXRecord:
6205 case Decl::ClassTemplate:
6206 case Decl::ClassTemplatePartialSpecialization:
6207 case Decl::ClassTemplateSpecialization:
6208 case Decl::Friend:
6209 case Decl::FriendTemplate:
6210 case Decl::FunctionTemplate:
6211 case Decl::LinkageSpec:
6212 case Decl::Namespace:
6213 case Decl::NamespaceAlias:
6214 case Decl::NonTypeTemplateParm:
6215 case Decl::StaticAssert:
6216 case Decl::TemplateTemplateParm:
6217 case Decl::TemplateTypeParm:
6218 case Decl::UnresolvedUsingTypename:
6219 case Decl::UnresolvedUsingValue:
6220 case Decl::Using:
6221 case Decl::UsingDirective:
6222 case Decl::UsingShadow:
6223 return CXLanguage_CPlusPlus;
6224 }
6225
6226 return CXLanguage_C;
6227}
6228
6229extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006230
6231static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6232 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6233 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006234
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006235 switch (D->getAvailability()) {
6236 case AR_Available:
6237 case AR_NotYetIntroduced:
6238 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006239 return getCursorAvailabilityForDecl(
6240 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006241 return CXAvailability_Available;
6242
6243 case AR_Deprecated:
6244 return CXAvailability_Deprecated;
6245
6246 case AR_Unavailable:
6247 return CXAvailability_NotAvailable;
6248 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006249
6250 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006251}
6252
Guy Benyei11169dd2012-12-18 14:30:41 +00006253enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6254 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006255 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6256 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006257
6258 return CXAvailability_Available;
6259}
6260
6261static CXVersion convertVersion(VersionTuple In) {
6262 CXVersion Out = { -1, -1, -1 };
6263 if (In.empty())
6264 return Out;
6265
6266 Out.Major = In.getMajor();
6267
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006268 Optional<unsigned> Minor = In.getMinor();
6269 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006270 Out.Minor = *Minor;
6271 else
6272 return Out;
6273
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006274 Optional<unsigned> Subminor = In.getSubminor();
6275 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006276 Out.Subminor = *Subminor;
6277
6278 return Out;
6279}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006280
6281static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6282 int *always_deprecated,
6283 CXString *deprecated_message,
6284 int *always_unavailable,
6285 CXString *unavailable_message,
6286 CXPlatformAvailability *availability,
6287 int availability_size) {
6288 bool HadAvailAttr = false;
6289 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006290 for (auto A : D->attrs()) {
6291 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006292 HadAvailAttr = true;
6293 if (always_deprecated)
6294 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006295 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006296 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006297 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006298 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006299 continue;
6300 }
6301
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006302 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006303 HadAvailAttr = true;
6304 if (always_unavailable)
6305 *always_unavailable = 1;
6306 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006307 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006308 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6309 }
6310 continue;
6311 }
6312
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006313 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006314 HadAvailAttr = true;
6315 if (N < availability_size) {
6316 availability[N].Platform
6317 = cxstring::createDup(Avail->getPlatform()->getName());
6318 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6319 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6320 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6321 availability[N].Unavailable = Avail->getUnavailable();
6322 availability[N].Message = cxstring::createDup(Avail->getMessage());
6323 }
6324 ++N;
6325 }
6326 }
6327
6328 if (!HadAvailAttr)
6329 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6330 return getCursorPlatformAvailabilityForDecl(
6331 cast<Decl>(EnumConst->getDeclContext()),
6332 always_deprecated,
6333 deprecated_message,
6334 always_unavailable,
6335 unavailable_message,
6336 availability,
6337 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006338
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006339 return N;
6340}
6341
Guy Benyei11169dd2012-12-18 14:30:41 +00006342int clang_getCursorPlatformAvailability(CXCursor cursor,
6343 int *always_deprecated,
6344 CXString *deprecated_message,
6345 int *always_unavailable,
6346 CXString *unavailable_message,
6347 CXPlatformAvailability *availability,
6348 int availability_size) {
6349 if (always_deprecated)
6350 *always_deprecated = 0;
6351 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006352 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006353 if (always_unavailable)
6354 *always_unavailable = 0;
6355 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006356 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006357
Guy Benyei11169dd2012-12-18 14:30:41 +00006358 if (!clang_isDeclaration(cursor.kind))
6359 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006360
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006361 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006362 if (!D)
6363 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006364
6365 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6366 deprecated_message,
6367 always_unavailable,
6368 unavailable_message,
6369 availability,
6370 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006371}
6372
6373void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6374 clang_disposeString(availability->Platform);
6375 clang_disposeString(availability->Message);
6376}
6377
6378CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6379 if (clang_isDeclaration(cursor.kind))
6380 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6381
6382 return CXLanguage_Invalid;
6383}
6384
6385 /// \brief If the given cursor is the "templated" declaration
6386 /// descibing a class or function template, return the class or
6387 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006388static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006389 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006390 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006391
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006392 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006393 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6394 return FunTmpl;
6395
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006396 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006397 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6398 return ClassTmpl;
6399
6400 return D;
6401}
6402
6403CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6404 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006405 if (const Decl *D = getCursorDecl(cursor)) {
6406 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006407 if (!DC)
6408 return clang_getNullCursor();
6409
6410 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6411 getCursorTU(cursor));
6412 }
6413 }
6414
6415 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006416 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006417 return MakeCXCursor(D, getCursorTU(cursor));
6418 }
6419
6420 return clang_getNullCursor();
6421}
6422
6423CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6424 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006425 if (const Decl *D = getCursorDecl(cursor)) {
6426 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006427 if (!DC)
6428 return clang_getNullCursor();
6429
6430 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6431 getCursorTU(cursor));
6432 }
6433 }
6434
6435 // FIXME: Note that we can't easily compute the lexical context of a
6436 // statement or expression, so we return nothing.
6437 return clang_getNullCursor();
6438}
6439
6440CXFile clang_getIncludedFile(CXCursor cursor) {
6441 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006442 return nullptr;
6443
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006444 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006445 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006446}
6447
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006448unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6449 if (C.kind != CXCursor_ObjCPropertyDecl)
6450 return CXObjCPropertyAttr_noattr;
6451
6452 unsigned Result = CXObjCPropertyAttr_noattr;
6453 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6454 ObjCPropertyDecl::PropertyAttributeKind Attr =
6455 PD->getPropertyAttributesAsWritten();
6456
6457#define SET_CXOBJCPROP_ATTR(A) \
6458 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6459 Result |= CXObjCPropertyAttr_##A
6460 SET_CXOBJCPROP_ATTR(readonly);
6461 SET_CXOBJCPROP_ATTR(getter);
6462 SET_CXOBJCPROP_ATTR(assign);
6463 SET_CXOBJCPROP_ATTR(readwrite);
6464 SET_CXOBJCPROP_ATTR(retain);
6465 SET_CXOBJCPROP_ATTR(copy);
6466 SET_CXOBJCPROP_ATTR(nonatomic);
6467 SET_CXOBJCPROP_ATTR(setter);
6468 SET_CXOBJCPROP_ATTR(atomic);
6469 SET_CXOBJCPROP_ATTR(weak);
6470 SET_CXOBJCPROP_ATTR(strong);
6471 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6472#undef SET_CXOBJCPROP_ATTR
6473
6474 return Result;
6475}
6476
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006477unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6478 if (!clang_isDeclaration(C.kind))
6479 return CXObjCDeclQualifier_None;
6480
6481 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6482 const Decl *D = getCursorDecl(C);
6483 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6484 QT = MD->getObjCDeclQualifier();
6485 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6486 QT = PD->getObjCDeclQualifier();
6487 if (QT == Decl::OBJC_TQ_None)
6488 return CXObjCDeclQualifier_None;
6489
6490 unsigned Result = CXObjCDeclQualifier_None;
6491 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6492 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6493 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6494 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6495 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6496 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6497
6498 return Result;
6499}
6500
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006501unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6502 if (!clang_isDeclaration(C.kind))
6503 return 0;
6504
6505 const Decl *D = getCursorDecl(C);
6506 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6507 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6508 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6509 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6510
6511 return 0;
6512}
6513
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006514unsigned clang_Cursor_isVariadic(CXCursor C) {
6515 if (!clang_isDeclaration(C.kind))
6516 return 0;
6517
6518 const Decl *D = getCursorDecl(C);
6519 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6520 return FD->isVariadic();
6521 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6522 return MD->isVariadic();
6523
6524 return 0;
6525}
6526
Guy Benyei11169dd2012-12-18 14:30:41 +00006527CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6528 if (!clang_isDeclaration(C.kind))
6529 return clang_getNullRange();
6530
6531 const Decl *D = getCursorDecl(C);
6532 ASTContext &Context = getCursorContext(C);
6533 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6534 if (!RC)
6535 return clang_getNullRange();
6536
6537 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6538}
6539
6540CXString clang_Cursor_getRawCommentText(CXCursor C) {
6541 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006542 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006543
6544 const Decl *D = getCursorDecl(C);
6545 ASTContext &Context = getCursorContext(C);
6546 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6547 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6548 StringRef();
6549
6550 // Don't duplicate the string because RawText points directly into source
6551 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006552 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006553}
6554
6555CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6556 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006557 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006558
6559 const Decl *D = getCursorDecl(C);
6560 const ASTContext &Context = getCursorContext(C);
6561 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6562
6563 if (RC) {
6564 StringRef BriefText = RC->getBriefText(Context);
6565
6566 // Don't duplicate the string because RawComment ensures that this memory
6567 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006568 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006569 }
6570
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006571 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006572}
6573
Guy Benyei11169dd2012-12-18 14:30:41 +00006574CXModule clang_Cursor_getModule(CXCursor C) {
6575 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006576 if (const ImportDecl *ImportD =
6577 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006578 return ImportD->getImportedModule();
6579 }
6580
Craig Topper69186e72014-06-08 08:38:04 +00006581 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006582}
6583
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006584CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6585 if (isNotUsableTU(TU)) {
6586 LOG_BAD_TU(TU);
6587 return nullptr;
6588 }
6589 if (!File)
6590 return nullptr;
6591 FileEntry *FE = static_cast<FileEntry *>(File);
6592
6593 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6594 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6595 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6596
6597 if (Module *Mod = Header.getModule()) {
6598 if (Header.getRole() != ModuleMap::ExcludedHeader)
6599 return Mod;
6600 }
6601 return nullptr;
6602}
6603
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006604CXFile clang_Module_getASTFile(CXModule CXMod) {
6605 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006606 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006607 Module *Mod = static_cast<Module*>(CXMod);
6608 return const_cast<FileEntry *>(Mod->getASTFile());
6609}
6610
Guy Benyei11169dd2012-12-18 14:30:41 +00006611CXModule clang_Module_getParent(CXModule CXMod) {
6612 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006613 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006614 Module *Mod = static_cast<Module*>(CXMod);
6615 return Mod->Parent;
6616}
6617
6618CXString clang_Module_getName(CXModule CXMod) {
6619 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006620 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006621 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006622 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006623}
6624
6625CXString clang_Module_getFullName(CXModule CXMod) {
6626 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006627 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006628 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006629 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006630}
6631
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006632int clang_Module_isSystem(CXModule CXMod) {
6633 if (!CXMod)
6634 return 0;
6635 Module *Mod = static_cast<Module*>(CXMod);
6636 return Mod->IsSystem;
6637}
6638
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006639unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6640 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006641 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006642 LOG_BAD_TU(TU);
6643 return 0;
6644 }
6645 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006646 return 0;
6647 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006648 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6649 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6650 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006651}
6652
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006653CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6654 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006655 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006656 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006657 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006658 }
6659 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006660 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006661 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006662 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006663
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006664 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6665 if (Index < TopHeaders.size())
6666 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006667
Craig Topper69186e72014-06-08 08:38:04 +00006668 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006669}
6670
6671} // end: extern "C"
6672
6673//===----------------------------------------------------------------------===//
6674// C++ AST instrospection.
6675//===----------------------------------------------------------------------===//
6676
6677extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006678unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6679 if (!clang_isDeclaration(C.kind))
6680 return 0;
6681
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006682 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006683 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006684 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006685 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6686}
6687
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006688unsigned clang_CXXMethod_isConst(CXCursor C) {
6689 if (!clang_isDeclaration(C.kind))
6690 return 0;
6691
6692 const Decl *D = cxcursor::getCursorDecl(C);
6693 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006694 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006695 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6696}
6697
Guy Benyei11169dd2012-12-18 14:30:41 +00006698unsigned clang_CXXMethod_isStatic(CXCursor C) {
6699 if (!clang_isDeclaration(C.kind))
6700 return 0;
6701
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006702 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006703 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006704 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006705 return (Method && Method->isStatic()) ? 1 : 0;
6706}
6707
6708unsigned clang_CXXMethod_isVirtual(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->isVirtual()) ? 1 : 0;
6716}
6717} // end: extern "C"
6718
6719//===----------------------------------------------------------------------===//
6720// Attribute introspection.
6721//===----------------------------------------------------------------------===//
6722
6723extern "C" {
6724CXType clang_getIBOutletCollectionType(CXCursor C) {
6725 if (C.kind != CXCursor_IBOutletCollectionAttr)
6726 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6727
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006728 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006729 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6730
6731 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6732}
6733} // end: extern "C"
6734
6735//===----------------------------------------------------------------------===//
6736// Inspecting memory usage.
6737//===----------------------------------------------------------------------===//
6738
6739typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6740
6741static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6742 enum CXTUResourceUsageKind k,
6743 unsigned long amount) {
6744 CXTUResourceUsageEntry entry = { k, amount };
6745 entries.push_back(entry);
6746}
6747
6748extern "C" {
6749
6750const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6751 const char *str = "";
6752 switch (kind) {
6753 case CXTUResourceUsage_AST:
6754 str = "ASTContext: expressions, declarations, and types";
6755 break;
6756 case CXTUResourceUsage_Identifiers:
6757 str = "ASTContext: identifiers";
6758 break;
6759 case CXTUResourceUsage_Selectors:
6760 str = "ASTContext: selectors";
6761 break;
6762 case CXTUResourceUsage_GlobalCompletionResults:
6763 str = "Code completion: cached global results";
6764 break;
6765 case CXTUResourceUsage_SourceManagerContentCache:
6766 str = "SourceManager: content cache allocator";
6767 break;
6768 case CXTUResourceUsage_AST_SideTables:
6769 str = "ASTContext: side tables";
6770 break;
6771 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6772 str = "SourceManager: malloc'ed memory buffers";
6773 break;
6774 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6775 str = "SourceManager: mmap'ed memory buffers";
6776 break;
6777 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6778 str = "ExternalASTSource: malloc'ed memory buffers";
6779 break;
6780 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6781 str = "ExternalASTSource: mmap'ed memory buffers";
6782 break;
6783 case CXTUResourceUsage_Preprocessor:
6784 str = "Preprocessor: malloc'ed memory";
6785 break;
6786 case CXTUResourceUsage_PreprocessingRecord:
6787 str = "Preprocessor: PreprocessingRecord";
6788 break;
6789 case CXTUResourceUsage_SourceManager_DataStructures:
6790 str = "SourceManager: data structures and tables";
6791 break;
6792 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6793 str = "Preprocessor: header search tables";
6794 break;
6795 }
6796 return str;
6797}
6798
6799CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006800 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006801 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006802 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006803 return usage;
6804 }
6805
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006806 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006807 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006808 ASTContext &astContext = astUnit->getASTContext();
6809
6810 // How much memory is used by AST nodes and types?
6811 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6812 (unsigned long) astContext.getASTAllocatedMemory());
6813
6814 // How much memory is used by identifiers?
6815 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6816 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6817
6818 // How much memory is used for selectors?
6819 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6820 (unsigned long) astContext.Selectors.getTotalMemory());
6821
6822 // How much memory is used by ASTContext's side tables?
6823 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6824 (unsigned long) astContext.getSideTableAllocatedMemory());
6825
6826 // How much memory is used for caching global code completion results?
6827 unsigned long completionBytes = 0;
6828 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006829 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006830 completionBytes = completionAllocator->getTotalMemory();
6831 }
6832 createCXTUResourceUsageEntry(*entries,
6833 CXTUResourceUsage_GlobalCompletionResults,
6834 completionBytes);
6835
6836 // How much memory is being used by SourceManager's content cache?
6837 createCXTUResourceUsageEntry(*entries,
6838 CXTUResourceUsage_SourceManagerContentCache,
6839 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6840
6841 // How much memory is being used by the MemoryBuffer's in SourceManager?
6842 const SourceManager::MemoryBufferSizes &srcBufs =
6843 astUnit->getSourceManager().getMemoryBufferSizes();
6844
6845 createCXTUResourceUsageEntry(*entries,
6846 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6847 (unsigned long) srcBufs.malloc_bytes);
6848 createCXTUResourceUsageEntry(*entries,
6849 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6850 (unsigned long) srcBufs.mmap_bytes);
6851 createCXTUResourceUsageEntry(*entries,
6852 CXTUResourceUsage_SourceManager_DataStructures,
6853 (unsigned long) astContext.getSourceManager()
6854 .getDataStructureSizes());
6855
6856 // How much memory is being used by the ExternalASTSource?
6857 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6858 const ExternalASTSource::MemoryBufferSizes &sizes =
6859 esrc->getMemoryBufferSizes();
6860
6861 createCXTUResourceUsageEntry(*entries,
6862 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6863 (unsigned long) sizes.malloc_bytes);
6864 createCXTUResourceUsageEntry(*entries,
6865 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6866 (unsigned long) sizes.mmap_bytes);
6867 }
6868
6869 // How much memory is being used by the Preprocessor?
6870 Preprocessor &pp = astUnit->getPreprocessor();
6871 createCXTUResourceUsageEntry(*entries,
6872 CXTUResourceUsage_Preprocessor,
6873 pp.getTotalMemory());
6874
6875 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6876 createCXTUResourceUsageEntry(*entries,
6877 CXTUResourceUsage_PreprocessingRecord,
6878 pRec->getTotalMemory());
6879 }
6880
6881 createCXTUResourceUsageEntry(*entries,
6882 CXTUResourceUsage_Preprocessor_HeaderSearch,
6883 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006884
Guy Benyei11169dd2012-12-18 14:30:41 +00006885 CXTUResourceUsage usage = { (void*) entries.get(),
6886 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006887 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006888 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006889 return usage;
6890}
6891
6892void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6893 if (usage.data)
6894 delete (MemUsageEntries*) usage.data;
6895}
6896
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006897CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6898 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006899 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006900 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006901
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006902 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006903 LOG_BAD_TU(TU);
6904 return skipped;
6905 }
6906
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006907 if (!file)
6908 return skipped;
6909
6910 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6911 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6912 if (!ppRec)
6913 return skipped;
6914
6915 ASTContext &Ctx = astUnit->getASTContext();
6916 SourceManager &sm = Ctx.getSourceManager();
6917 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6918 FileID wantedFileID = sm.translateFile(fileEntry);
6919
6920 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6921 std::vector<SourceRange> wantedRanges;
6922 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6923 i != ei; ++i) {
6924 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6925 wantedRanges.push_back(*i);
6926 }
6927
6928 skipped->count = wantedRanges.size();
6929 skipped->ranges = new CXSourceRange[skipped->count];
6930 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6931 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6932
6933 return skipped;
6934}
6935
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006936void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6937 if (ranges) {
6938 delete[] ranges->ranges;
6939 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006940 }
6941}
6942
Guy Benyei11169dd2012-12-18 14:30:41 +00006943} // end extern "C"
6944
6945void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6946 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6947 for (unsigned I = 0; I != Usage.numEntries; ++I)
6948 fprintf(stderr, " %s: %lu\n",
6949 clang_getTUResourceUsageName(Usage.entries[I].kind),
6950 Usage.entries[I].amount);
6951
6952 clang_disposeCXTUResourceUsage(Usage);
6953}
6954
6955//===----------------------------------------------------------------------===//
6956// Misc. utility functions.
6957//===----------------------------------------------------------------------===//
6958
6959/// Default to using an 8 MB stack size on "safety" threads.
6960static unsigned SafetyStackThreadSize = 8 << 20;
6961
6962namespace clang {
6963
6964bool RunSafely(llvm::CrashRecoveryContext &CRC,
6965 void (*Fn)(void*), void *UserData,
6966 unsigned Size) {
6967 if (!Size)
6968 Size = GetSafetyThreadStackSize();
6969 if (Size)
6970 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6971 return CRC.RunSafely(Fn, UserData);
6972}
6973
6974unsigned GetSafetyThreadStackSize() {
6975 return SafetyStackThreadSize;
6976}
6977
6978void SetSafetyThreadStackSize(unsigned Value) {
6979 SafetyStackThreadSize = Value;
6980}
6981
6982}
6983
6984void clang::setThreadBackgroundPriority() {
6985 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6986 return;
6987
Alp Toker1a86ad22014-07-06 06:24:00 +00006988#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006989 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6990#endif
6991}
6992
6993void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6994 if (!Unit)
6995 return;
6996
6997 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6998 DEnd = Unit->stored_diag_end();
6999 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007000 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007001 CXString Msg = clang_formatDiagnostic(&Diag,
7002 clang_defaultDiagnosticDisplayOptions());
7003 fprintf(stderr, "%s\n", clang_getCString(Msg));
7004 clang_disposeString(Msg);
7005 }
7006#ifdef LLVM_ON_WIN32
7007 // On Windows, force a flush, since there may be multiple copies of
7008 // stderr and stdout in the file system, all with different buffers
7009 // but writing to the same device.
7010 fflush(stderr);
7011#endif
7012}
7013
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007014MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7015 SourceLocation MacroDefLoc,
7016 CXTranslationUnit TU){
7017 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007018 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007019 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007020 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007021
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007022 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007023 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007024 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007025 if (MD) {
7026 for (MacroDirective::DefInfo
7027 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7028 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7029 return Def.getMacroInfo();
7030 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007031 }
7032
Craig Topper69186e72014-06-08 08:38:04 +00007033 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007034}
7035
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007036const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7037 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007038 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007039 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007040 const IdentifierInfo *II = MacroDef->getName();
7041 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007042 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007043
7044 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7045}
7046
7047MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7048 const Token &Tok,
7049 CXTranslationUnit TU) {
7050 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007051 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007052 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007053 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007054
7055 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007056 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007057 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7058 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007059 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007060
7061 // Check that the token is inside the definition and not its argument list.
7062 SourceManager &SM = Unit->getSourceManager();
7063 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007064 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007065 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007066 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007067
7068 Preprocessor &PP = Unit->getPreprocessor();
7069 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7070 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007071 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007072
Alp Toker2d57cea2014-05-17 04:53:25 +00007073 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007074 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007075 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007076
7077 // Check that the identifier is not one of the macro arguments.
7078 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007079 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007080
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007081 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7082 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007083 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007084
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007085 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007086}
7087
7088MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7089 SourceLocation Loc,
7090 CXTranslationUnit TU) {
7091 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007092 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007093
7094 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007095 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007096 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007097 Preprocessor &PP = Unit->getPreprocessor();
7098 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007099 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007100 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7101 Token Tok;
7102 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007103 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007104
7105 return checkForMacroInMacroDefinition(MI, Tok, TU);
7106}
7107
Guy Benyei11169dd2012-12-18 14:30:41 +00007108extern "C" {
7109
7110CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007111 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007112}
7113
7114} // end: extern "C"
7115
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007116Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7117 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007118 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007119 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007120 if (Unit->isMainFileAST())
7121 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007122 return *this;
7123 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007124 } else {
7125 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007126 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007127 return *this;
7128}
7129
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007130Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7131 *this << FE->getName();
7132 return *this;
7133}
7134
7135Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7136 CXString cursorName = clang_getCursorDisplayName(cursor);
7137 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7138 clang_disposeString(cursorName);
7139 return *this;
7140}
7141
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007142Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7143 CXFile File;
7144 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007145 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007146 CXString FileName = clang_getFileName(File);
7147 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7148 clang_disposeString(FileName);
7149 return *this;
7150}
7151
7152Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7153 CXSourceLocation BLoc = clang_getRangeStart(range);
7154 CXSourceLocation ELoc = clang_getRangeEnd(range);
7155
7156 CXFile BFile;
7157 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007158 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007159
7160 CXFile EFile;
7161 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007162 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007163
7164 CXString BFileName = clang_getFileName(BFile);
7165 if (BFile == EFile) {
7166 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7167 BLine, BColumn, ELine, EColumn);
7168 } else {
7169 CXString EFileName = clang_getFileName(EFile);
7170 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7171 BLine, BColumn)
7172 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7173 ELine, EColumn);
7174 clang_disposeString(EFileName);
7175 }
7176 clang_disposeString(BFileName);
7177 return *this;
7178}
7179
7180Logger &cxindex::Logger::operator<<(CXString Str) {
7181 *this << clang_getCString(Str);
7182 return *this;
7183}
7184
7185Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7186 LogOS << Fmt;
7187 return *this;
7188}
7189
Chandler Carruth37ad2582014-06-27 15:14:39 +00007190static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7191
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007192cxindex::Logger::~Logger() {
7193 LogOS.flush();
7194
Chandler Carruth37ad2582014-06-27 15:14:39 +00007195 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007196
7197 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7198
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007199 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007200 OS << "[libclang:" << Name << ':';
7201
Alp Toker1a86ad22014-07-06 06:24:00 +00007202#ifdef USE_DARWIN_THREADS
7203 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007204 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7205 OS << tid << ':';
7206#endif
7207
7208 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7209 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7210 OS << Msg.str() << '\n';
7211
7212 if (Trace) {
7213 llvm::sys::PrintStackTrace(stderr);
7214 OS << "--------------------------------------------------\n";
7215 }
7216}