blob: 0e42a94b5439fbe19a12dc53b9d424fec758f106 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
243 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
244 Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
458
459 continue;
460 }
461
462 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
465
466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000572 if (MacroDefinition *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
667bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669 return Visit(TSInfo->getTypeLoc());
670
671 return false;
672}
673
674bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682 return VisitDeclContext(D);
683}
684
685bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686 ClassTemplateSpecializationDecl *D) {
687 bool ShouldVisitBody = false;
688 switch (D->getSpecializationKind()) {
689 case TSK_Undeclared:
690 case TSK_ImplicitInstantiation:
691 // Nothing to visit
692 return false;
693
694 case TSK_ExplicitInstantiationDeclaration:
695 case TSK_ExplicitInstantiationDefinition:
696 break;
697
698 case TSK_ExplicitSpecialization:
699 ShouldVisitBody = true;
700 break;
701 }
702
703 // Visit the template arguments used in the specialization.
704 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000706 if (TemplateSpecializationTypeLoc TSTLoc =
707 TL.getAs<TemplateSpecializationTypeLoc>()) {
708 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000710 return true;
711 }
712 }
713
714 if (ShouldVisitBody && VisitCXXRecordDecl(D))
715 return true;
716
717 return false;
718}
719
720bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721 ClassTemplatePartialSpecializationDecl *D) {
722 // FIXME: Visit the "outer" template parameter lists on the TagDecl
723 // before visiting these template parameters.
724 if (VisitTemplateParameters(D->getTemplateParameters()))
725 return true;
726
727 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000728 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732 return true;
733
734 return VisitCXXRecordDecl(D);
735}
736
737bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738 // Visit the default argument.
739 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741 if (Visit(DefArg->getTypeLoc()))
742 return true;
743
744 return false;
745}
746
747bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748 if (Expr *Init = D->getInitExpr())
749 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750 return false;
751}
752
753bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000754 unsigned NumParamList = DD->getNumTemplateParameterLists();
755 for (unsigned i = 0; i < NumParamList; i++) {
756 TemplateParameterList* Params = DD->getTemplateParameterList(i);
757 if (VisitTemplateParameters(Params))
758 return true;
759 }
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762 if (Visit(TSInfo->getTypeLoc()))
763 return true;
764
765 // Visit the nested-name-specifier, if present.
766 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
768 return true;
769
770 return false;
771}
772
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000773/// \brief Compare two base or member initializers based on their source order.
774static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775 CXXCtorInitializer *const *Y) {
776 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777}
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 unsigned NumParamList = ND->getNumTemplateParameterLists();
781 for (unsigned i = 0; i < NumParamList; i++) {
782 TemplateParameterList* Params = ND->getTemplateParameterList(i);
783 if (VisitTemplateParameters(Params))
784 return true;
785 }
786
Guy Benyei11169dd2012-12-18 14:30:41 +0000787 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788 // Visit the function declaration's syntactic components in the order
789 // written. This requires a bit of work.
790 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000791 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000792
793 // If we have a function declared directly (without the use of a typedef),
794 // visit just the return type. Otherwise, just visit the function's type
795 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000796 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000797 (!FTL && Visit(TL)))
798 return true;
799
800 // Visit the nested-name-specifier, if present.
801 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
803 return true;
804
805 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000806 if (!isa<CXXDestructorDecl>(ND))
807 if (VisitDeclarationNameInfo(ND->getNameInfo()))
808 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000809
810 // FIXME: Visit explicitly-specified template arguments!
811
812 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000813 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 return true;
815
Bill Wendling44426052012-12-20 19:22:21 +0000816 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 }
818
819 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821 // Find the initializers that were written in the source.
822 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 for (auto *I : Constructor->inits()) {
824 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 continue;
826
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 }
829
830 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000831 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832 &CompareCXXCtorInitializers);
833
Guy Benyei11169dd2012-12-18 14:30:41 +0000834 // Visit the initializers in source order
835 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836 CXXCtorInitializer *Init = WrittenInits[I];
837 if (Init->isAnyMemberInitializer()) {
838 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839 Init->getMemberLocation(), TU)))
840 return true;
841 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842 if (Visit(TInfo->getTypeLoc()))
843 return true;
844 }
845
846 // Visit the initializer value.
847 if (Expr *Initializer = Init->getInit())
848 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849 return true;
850 }
851 }
852
853 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854 return true;
855 }
856
857 return false;
858}
859
860bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861 if (VisitDeclaratorDecl(D))
862 return true;
863
864 if (Expr *BitWidth = D->getBitWidth())
865 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871 if (VisitDeclaratorDecl(D))
872 return true;
873
874 if (Expr *Init = D->getInit())
875 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876
877 return false;
878}
879
880bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881 if (VisitDeclaratorDecl(D))
882 return true;
883
884 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885 if (Expr *DefArg = D->getDefaultArgument())
886 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887
888 return false;
889}
890
891bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitFunctionDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901 // FIXME: Visit the "outer" template parameter lists on the TagDecl
902 // before visiting these template parameters.
903 if (VisitTemplateParameters(D->getTemplateParameters()))
904 return true;
905
906 return VisitCXXRecordDecl(D->getTemplatedDecl());
907}
908
909bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914 VisitTemplateArgumentLoc(D->getDefaultArgument()))
915 return true;
916
917 return false;
918}
919
920bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000921 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000922 if (Visit(TSInfo->getTypeLoc()))
923 return true;
924
Aaron Ballman43b68be2014-03-07 17:50:17 +0000925 for (const auto *P : ND->params()) {
926 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000927 return true;
928 }
929
930 if (ND->isThisDeclarationADefinition() &&
931 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
932 return true;
933
934 return false;
935}
936
937template <typename DeclIt>
938static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
939 SourceManager &SM, SourceLocation EndLoc,
940 SmallVectorImpl<Decl *> &Decls) {
941 DeclIt next = *DI_current;
942 while (++next != DE_current) {
943 Decl *D_next = *next;
944 if (!D_next)
945 break;
946 SourceLocation L = D_next->getLocStart();
947 if (!L.isValid())
948 break;
949 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
950 *DI_current = next;
951 Decls.push_back(D_next);
952 continue;
953 }
954 break;
955 }
956}
957
Guy Benyei11169dd2012-12-18 14:30:41 +0000958bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
959 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
960 // an @implementation can lexically contain Decls that are not properly
961 // nested in the AST. When we identify such cases, we need to retrofit
962 // this nesting here.
963 if (!DI_current && !FileDI_current)
964 return VisitDeclContext(D);
965
966 // Scan the Decls that immediately come after the container
967 // in the current DeclContext. If any fall within the
968 // container's lexical region, stash them into a vector
969 // for later processing.
970 SmallVector<Decl *, 24> DeclsInContainer;
971 SourceLocation EndLoc = D->getSourceRange().getEnd();
972 SourceManager &SM = AU->getSourceManager();
973 if (EndLoc.isValid()) {
974 if (DI_current) {
975 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
976 DeclsInContainer);
977 } else {
978 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
979 DeclsInContainer);
980 }
981 }
982
983 // The common case.
984 if (DeclsInContainer.empty())
985 return VisitDeclContext(D);
986
987 // Get all the Decls in the DeclContext, and sort them with the
988 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 for (auto *SubDecl : D->decls()) {
990 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
991 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000992 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000993 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000994 }
995
996 // Now sort the Decls so that they appear in lexical order.
997 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000998 [&SM](Decl *A, Decl *B) {
999 SourceLocation L_A = A->getLocStart();
1000 SourceLocation L_B = B->getLocStart();
1001 assert(L_A.isValid() && L_B.isValid());
1002 return SM.isBeforeInTranslationUnit(L_A, L_B);
1003 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001004
1005 // Now visit the decls.
1006 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1007 E = DeclsInContainer.end(); I != E; ++I) {
1008 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001009 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001010 if (!V.hasValue())
1011 continue;
1012 if (!V.getValue())
1013 return false;
1014 if (Visit(Cursor, true))
1015 return true;
1016 }
1017 return false;
1018}
1019
1020bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1021 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1022 TU)))
1023 return true;
1024
1025 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1026 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1027 E = ND->protocol_end(); I != E; ++I, ++PL)
1028 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1029 return true;
1030
1031 return VisitObjCContainerDecl(ND);
1032}
1033
1034bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1035 if (!PID->isThisDeclarationADefinition())
1036 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1037
1038 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1039 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1040 E = PID->protocol_end(); I != E; ++I, ++PL)
1041 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042 return true;
1043
1044 return VisitObjCContainerDecl(PID);
1045}
1046
1047bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1048 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1049 return true;
1050
1051 // FIXME: This implements a workaround with @property declarations also being
1052 // installed in the DeclContext for the @interface. Eventually this code
1053 // should be removed.
1054 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1055 if (!CDecl || !CDecl->IsClassExtension())
1056 return false;
1057
1058 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1059 if (!ID)
1060 return false;
1061
1062 IdentifierInfo *PropertyId = PD->getIdentifier();
1063 ObjCPropertyDecl *prevDecl =
1064 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1065
1066 if (!prevDecl)
1067 return false;
1068
1069 // Visit synthesized methods since they will be skipped when visiting
1070 // the @interface.
1071 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1072 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1073 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1074 return true;
1075
1076 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1077 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1078 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1079 return true;
1080
1081 return false;
1082}
1083
1084bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1085 if (!D->isThisDeclarationADefinition()) {
1086 // Forward declaration is treated like a reference.
1087 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1088 }
1089
1090 // Issue callbacks for super class.
1091 if (D->getSuperClass() &&
1092 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1093 D->getSuperClassLoc(),
1094 TU)))
1095 return true;
1096
1097 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1098 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1099 E = D->protocol_end(); I != E; ++I, ++PL)
1100 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1101 return true;
1102
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1107 return VisitObjCContainerDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1111 // 'ID' could be null when dealing with invalid code.
1112 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1113 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1114 return true;
1115
1116 return VisitObjCImplDecl(D);
1117}
1118
1119bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1120#if 0
1121 // Issue callbacks for super class.
1122 // FIXME: No source location information!
1123 if (D->getSuperClass() &&
1124 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125 D->getSuperClassLoc(),
1126 TU)))
1127 return true;
1128#endif
1129
1130 return VisitObjCImplDecl(D);
1131}
1132
1133bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1134 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1135 if (PD->isIvarNameSpecified())
1136 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1137
1138 return false;
1139}
1140
1141bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1142 return VisitDeclContext(D);
1143}
1144
1145bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1146 // Visit nested-name-specifier.
1147 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1148 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149 return true;
1150
1151 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1152 D->getTargetNameLoc(), TU));
1153}
1154
1155bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1156 // Visit nested-name-specifier.
1157 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1158 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1159 return true;
1160 }
1161
1162 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1163 return true;
1164
1165 return VisitDeclarationNameInfo(D->getNameInfo());
1166}
1167
1168bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1169 // Visit nested-name-specifier.
1170 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172 return true;
1173
1174 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1175 D->getIdentLocation(), TU));
1176}
1177
1178bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1179 // Visit nested-name-specifier.
1180 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1181 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1182 return true;
1183 }
1184
1185 return VisitDeclarationNameInfo(D->getNameInfo());
1186}
1187
1188bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1189 UnresolvedUsingTypenameDecl *D) {
1190 // Visit nested-name-specifier.
1191 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1192 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1193 return true;
1194
1195 return false;
1196}
1197
1198bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1199 switch (Name.getName().getNameKind()) {
1200 case clang::DeclarationName::Identifier:
1201 case clang::DeclarationName::CXXLiteralOperatorName:
1202 case clang::DeclarationName::CXXOperatorName:
1203 case clang::DeclarationName::CXXUsingDirective:
1204 return false;
1205
1206 case clang::DeclarationName::CXXConstructorName:
1207 case clang::DeclarationName::CXXDestructorName:
1208 case clang::DeclarationName::CXXConversionFunctionName:
1209 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1210 return Visit(TSInfo->getTypeLoc());
1211 return false;
1212
1213 case clang::DeclarationName::ObjCZeroArgSelector:
1214 case clang::DeclarationName::ObjCOneArgSelector:
1215 case clang::DeclarationName::ObjCMultiArgSelector:
1216 // FIXME: Per-identifier location info?
1217 return false;
1218 }
1219
1220 llvm_unreachable("Invalid DeclarationName::Kind!");
1221}
1222
1223bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1224 SourceRange Range) {
1225 // FIXME: This whole routine is a hack to work around the lack of proper
1226 // source information in nested-name-specifiers (PR5791). Since we do have
1227 // a beginning source location, we can visit the first component of the
1228 // nested-name-specifier, if it's a single-token component.
1229 if (!NNS)
1230 return false;
1231
1232 // Get the first component in the nested-name-specifier.
1233 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1234 NNS = Prefix;
1235
1236 switch (NNS->getKind()) {
1237 case NestedNameSpecifier::Namespace:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1239 TU));
1240
1241 case NestedNameSpecifier::NamespaceAlias:
1242 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1243 Range.getBegin(), TU));
1244
1245 case NestedNameSpecifier::TypeSpec: {
1246 // If the type has a form where we know that the beginning of the source
1247 // range matches up with a reference cursor. Visit the appropriate reference
1248 // cursor.
1249 const Type *T = NNS->getAsType();
1250 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1251 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1252 if (const TagType *Tag = dyn_cast<TagType>(T))
1253 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1254 if (const TemplateSpecializationType *TST
1255 = dyn_cast<TemplateSpecializationType>(T))
1256 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1257 break;
1258 }
1259
1260 case NestedNameSpecifier::TypeSpecWithTemplate:
1261 case NestedNameSpecifier::Global:
1262 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001263 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001264 break;
1265 }
1266
1267 return false;
1268}
1269
1270bool
1271CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1272 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1273 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1274 Qualifiers.push_back(Qualifier);
1275
1276 while (!Qualifiers.empty()) {
1277 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1278 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1279 switch (NNS->getKind()) {
1280 case NestedNameSpecifier::Namespace:
1281 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1282 Q.getLocalBeginLoc(),
1283 TU)))
1284 return true;
1285
1286 break;
1287
1288 case NestedNameSpecifier::NamespaceAlias:
1289 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1290 Q.getLocalBeginLoc(),
1291 TU)))
1292 return true;
1293
1294 break;
1295
1296 case NestedNameSpecifier::TypeSpec:
1297 case NestedNameSpecifier::TypeSpecWithTemplate:
1298 if (Visit(Q.getTypeLoc()))
1299 return true;
1300
1301 break;
1302
1303 case NestedNameSpecifier::Global:
1304 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001305 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001306 break;
1307 }
1308 }
1309
1310 return false;
1311}
1312
1313bool CursorVisitor::VisitTemplateParameters(
1314 const TemplateParameterList *Params) {
1315 if (!Params)
1316 return false;
1317
1318 for (TemplateParameterList::const_iterator P = Params->begin(),
1319 PEnd = Params->end();
1320 P != PEnd; ++P) {
1321 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1322 return true;
1323 }
1324
1325 return false;
1326}
1327
1328bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1329 switch (Name.getKind()) {
1330 case TemplateName::Template:
1331 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1332
1333 case TemplateName::OverloadedTemplate:
1334 // Visit the overloaded template set.
1335 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1336 return true;
1337
1338 return false;
1339
1340 case TemplateName::DependentTemplate:
1341 // FIXME: Visit nested-name-specifier.
1342 return false;
1343
1344 case TemplateName::QualifiedTemplate:
1345 // FIXME: Visit nested-name-specifier.
1346 return Visit(MakeCursorTemplateRef(
1347 Name.getAsQualifiedTemplateName()->getDecl(),
1348 Loc, TU));
1349
1350 case TemplateName::SubstTemplateTemplateParm:
1351 return Visit(MakeCursorTemplateRef(
1352 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1353 Loc, TU));
1354
1355 case TemplateName::SubstTemplateTemplateParmPack:
1356 return Visit(MakeCursorTemplateRef(
1357 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1358 Loc, TU));
1359 }
1360
1361 llvm_unreachable("Invalid TemplateName::Kind!");
1362}
1363
1364bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1365 switch (TAL.getArgument().getKind()) {
1366 case TemplateArgument::Null:
1367 case TemplateArgument::Integral:
1368 case TemplateArgument::Pack:
1369 return false;
1370
1371 case TemplateArgument::Type:
1372 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1373 return Visit(TSInfo->getTypeLoc());
1374 return false;
1375
1376 case TemplateArgument::Declaration:
1377 if (Expr *E = TAL.getSourceDeclExpression())
1378 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379 return false;
1380
1381 case TemplateArgument::NullPtr:
1382 if (Expr *E = TAL.getSourceNullPtrExpression())
1383 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1384 return false;
1385
1386 case TemplateArgument::Expression:
1387 if (Expr *E = TAL.getSourceExpression())
1388 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1389 return false;
1390
1391 case TemplateArgument::Template:
1392 case TemplateArgument::TemplateExpansion:
1393 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1394 return true;
1395
1396 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1397 TAL.getTemplateNameLoc());
1398 }
1399
1400 llvm_unreachable("Invalid TemplateArgument::Kind!");
1401}
1402
1403bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1404 return VisitDeclContext(D);
1405}
1406
1407bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1408 return Visit(TL.getUnqualifiedLoc());
1409}
1410
1411bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1412 ASTContext &Context = AU->getASTContext();
1413
1414 // Some builtin types (such as Objective-C's "id", "sel", and
1415 // "Class") have associated declarations. Create cursors for those.
1416 QualType VisitType;
1417 switch (TL.getTypePtr()->getKind()) {
1418
1419 case BuiltinType::Void:
1420 case BuiltinType::NullPtr:
1421 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001422 case BuiltinType::OCLImage1d:
1423 case BuiltinType::OCLImage1dArray:
1424 case BuiltinType::OCLImage1dBuffer:
1425 case BuiltinType::OCLImage2d:
1426 case BuiltinType::OCLImage2dArray:
1427 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001428 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001429 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001430#define BUILTIN_TYPE(Id, SingletonId)
1431#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1434#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1435#include "clang/AST/BuiltinTypes.def"
1436 break;
1437
1438 case BuiltinType::ObjCId:
1439 VisitType = Context.getObjCIdType();
1440 break;
1441
1442 case BuiltinType::ObjCClass:
1443 VisitType = Context.getObjCClassType();
1444 break;
1445
1446 case BuiltinType::ObjCSel:
1447 VisitType = Context.getObjCSelType();
1448 break;
1449 }
1450
1451 if (!VisitType.isNull()) {
1452 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1453 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1454 TU));
1455 }
1456
1457 return false;
1458}
1459
1460bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1461 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1465 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1466}
1467
1468bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1469 if (TL.isDefinition())
1470 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1471
1472 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1473}
1474
1475bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1476 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1477}
1478
1479bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1480 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1481 return true;
1482
1483 return false;
1484}
1485
1486bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1487 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1488 return true;
1489
1490 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1491 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1492 TU)))
1493 return true;
1494 }
1495
1496 return false;
1497}
1498
1499bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1500 return Visit(TL.getPointeeLoc());
1501}
1502
1503bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1504 return Visit(TL.getInnerLoc());
1505}
1506
1507bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1520 return Visit(TL.getPointeeLoc());
1521}
1522
1523bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1524 return Visit(TL.getPointeeLoc());
1525}
1526
1527bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1528 return Visit(TL.getModifiedLoc());
1529}
1530
1531bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1532 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001533 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001534 return true;
1535
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001536 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1537 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001538 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1539 return true;
1540
1541 return false;
1542}
1543
1544bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1545 if (Visit(TL.getElementLoc()))
1546 return true;
1547
1548 if (Expr *Size = TL.getSizeExpr())
1549 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1550
1551 return false;
1552}
1553
Reid Kleckner8a365022013-06-24 17:51:48 +00001554bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1555 return Visit(TL.getOriginalLoc());
1556}
1557
Reid Kleckner0503a872013-12-05 01:23:43 +00001558bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1559 return Visit(TL.getOriginalLoc());
1560}
1561
Guy Benyei11169dd2012-12-18 14:30:41 +00001562bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1563 TemplateSpecializationTypeLoc TL) {
1564 // Visit the template name.
1565 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1566 TL.getTemplateNameLoc()))
1567 return true;
1568
1569 // Visit the template arguments.
1570 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1571 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1572 return true;
1573
1574 return false;
1575}
1576
1577bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1578 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1579}
1580
1581bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1582 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1583 return Visit(TSInfo->getTypeLoc());
1584
1585 return false;
1586}
1587
1588bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1589 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1590 return Visit(TSInfo->getTypeLoc());
1591
1592 return false;
1593}
1594
1595bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1596 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1597 return true;
1598
1599 return false;
1600}
1601
1602bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1603 DependentTemplateSpecializationTypeLoc TL) {
1604 // Visit the nested-name-specifier, if there is one.
1605 if (TL.getQualifierLoc() &&
1606 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1607 return true;
1608
1609 // Visit the template arguments.
1610 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1611 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1612 return true;
1613
1614 return false;
1615}
1616
1617bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1618 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1619 return true;
1620
1621 return Visit(TL.getNamedTypeLoc());
1622}
1623
1624bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1625 return Visit(TL.getPatternLoc());
1626}
1627
1628bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1629 if (Expr *E = TL.getUnderlyingExpr())
1630 return Visit(MakeCXCursor(E, StmtParent, TU));
1631
1632 return false;
1633}
1634
1635bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1636 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1637}
1638
1639bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1640 return Visit(TL.getValueLoc());
1641}
1642
1643#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1644bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1645 return Visit##PARENT##Loc(TL); \
1646}
1647
1648DEFAULT_TYPELOC_IMPL(Complex, Type)
1649DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1652DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1653DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1654DEFAULT_TYPELOC_IMPL(Vector, Type)
1655DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1656DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1657DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1658DEFAULT_TYPELOC_IMPL(Record, TagType)
1659DEFAULT_TYPELOC_IMPL(Enum, TagType)
1660DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1661DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1662DEFAULT_TYPELOC_IMPL(Auto, Type)
1663
1664bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1665 // Visit the nested-name-specifier, if present.
1666 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1667 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1668 return true;
1669
1670 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001671 for (const auto &I : D->bases()) {
1672 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001673 return true;
1674 }
1675 }
1676
1677 return VisitTagDecl(D);
1678}
1679
1680bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001681 for (const auto *I : D->attrs())
1682 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001683 return true;
1684
1685 return false;
1686}
1687
1688//===----------------------------------------------------------------------===//
1689// Data-recursive visitor methods.
1690//===----------------------------------------------------------------------===//
1691
1692namespace {
1693#define DEF_JOB(NAME, DATA, KIND)\
1694class NAME : public VisitorJob {\
1695public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001696 NAME(const DATA *d, CXCursor parent) : \
1697 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001698 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001699 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001700};
1701
1702DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1703DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1704DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1705DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1706DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1707 ExplicitTemplateArgsVisitKind)
1708DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1709DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1710DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1711#undef DEF_JOB
1712
1713class DeclVisit : public VisitorJob {
1714public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001717 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001718 static bool classof(const VisitorJob *VJ) {
1719 return VJ->getKind() == DeclVisitKind;
1720 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001721 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001722 bool isFirst() const { return data[1] ? true : false; }
1723};
1724class TypeLocVisit : public VisitorJob {
1725public:
1726 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1727 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1728 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1729
1730 static bool classof(const VisitorJob *VJ) {
1731 return VJ->getKind() == TypeLocVisitKind;
1732 }
1733
1734 TypeLoc get() const {
1735 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001736 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001737 }
1738};
1739
1740class LabelRefVisit : public VisitorJob {
1741public:
1742 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1743 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1744 labelLoc.getPtrEncoding()) {}
1745
1746 static bool classof(const VisitorJob *VJ) {
1747 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1748 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001749 const LabelDecl *get() const {
1750 return static_cast<const LabelDecl *>(data[0]);
1751 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001752 SourceLocation getLoc() const {
1753 return SourceLocation::getFromPtrEncoding(data[1]); }
1754};
1755
1756class NestedNameSpecifierLocVisit : public VisitorJob {
1757public:
1758 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1759 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1760 Qualifier.getNestedNameSpecifier(),
1761 Qualifier.getOpaqueData()) { }
1762
1763 static bool classof(const VisitorJob *VJ) {
1764 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1765 }
1766
1767 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001768 return NestedNameSpecifierLoc(
1769 const_cast<NestedNameSpecifier *>(
1770 static_cast<const NestedNameSpecifier *>(data[0])),
1771 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001772 }
1773};
1774
1775class DeclarationNameInfoVisit : public VisitorJob {
1776public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001778 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001779 static bool classof(const VisitorJob *VJ) {
1780 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1781 }
1782 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001783 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001784 switch (S->getStmtClass()) {
1785 default:
1786 llvm_unreachable("Unhandled Stmt");
1787 case clang::Stmt::MSDependentExistsStmtClass:
1788 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1789 case Stmt::CXXDependentScopeMemberExprClass:
1790 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1791 case Stmt::DependentScopeDeclRefExprClass:
1792 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001793 case Stmt::OMPCriticalDirectiveClass:
1794 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 }
1796 }
1797};
1798class MemberRefVisit : public VisitorJob {
1799public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001801 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1802 L.getPtrEncoding()) {}
1803 static bool classof(const VisitorJob *VJ) {
1804 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1805 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001806 const FieldDecl *get() const {
1807 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001808 }
1809 SourceLocation getLoc() const {
1810 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1811 }
1812};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001814 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001815 VisitorWorkList &WL;
1816 CXCursor Parent;
1817public:
1818 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1819 : WL(wl), Parent(parent) {}
1820
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001821 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1822 void VisitBlockExpr(const BlockExpr *B);
1823 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1824 void VisitCompoundStmt(const CompoundStmt *S);
1825 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1826 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1827 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1828 void VisitCXXNewExpr(const CXXNewExpr *E);
1829 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1830 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1831 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1832 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1833 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1834 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1835 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1836 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001837 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001838 void VisitDeclRefExpr(const DeclRefExpr *D);
1839 void VisitDeclStmt(const DeclStmt *S);
1840 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1841 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1842 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1843 void VisitForStmt(const ForStmt *FS);
1844 void VisitGotoStmt(const GotoStmt *GS);
1845 void VisitIfStmt(const IfStmt *If);
1846 void VisitInitListExpr(const InitListExpr *IE);
1847 void VisitMemberExpr(const MemberExpr *M);
1848 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1849 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1850 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1851 void VisitOverloadExpr(const OverloadExpr *E);
1852 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1853 void VisitStmt(const Stmt *S);
1854 void VisitSwitchStmt(const SwitchStmt *S);
1855 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001856 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1857 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1858 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1859 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1860 void VisitVAArgExpr(const VAArgExpr *E);
1861 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1862 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1863 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1864 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001865 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001866 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001867 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001868 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001869 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001870 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001871 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001872 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001873 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001874 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001875 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001876 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001877 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001878 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001879 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001880 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001881 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001882 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001883 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001884 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001885 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001886 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001887 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888
Guy Benyei11169dd2012-12-18 14:30:41 +00001889private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001891 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1892 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1894 void AddStmt(const Stmt *S);
1895 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001896 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001898 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001899};
1900} // end anonyous namespace
1901
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 // 'S' should always be non-null, since it comes from the
1904 // statement we are visiting.
1905 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1906}
1907
1908void
1909EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1910 if (Qualifier)
1911 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1912}
1913
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001914void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001915 if (S)
1916 WL.push_back(StmtVisit(S, Parent));
1917}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001918void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001919 if (D)
1920 WL.push_back(DeclVisit(D, Parent, isFirst));
1921}
1922void EnqueueVisitor::
1923 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1924 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001925 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001926}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001927void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001928 if (D)
1929 WL.push_back(MemberRefVisit(D, L, Parent));
1930}
1931void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1932 if (TI)
1933 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1934 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001935void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001936 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001937 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001938 AddStmt(*Child);
1939 }
1940 if (size == WL.size())
1941 return;
1942 // Now reverse the entries we just added. This will match the DFS
1943 // ordering performed by the worklist.
1944 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1945 std::reverse(I, E);
1946}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947namespace {
1948class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1949 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001950 /// \brief Process clauses with list of variables.
1951 template <typename T>
1952 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001953public:
1954 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1955#define OPENMP_CLAUSE(Name, Class) \
1956 void Visit##Class(const Class *C);
1957#include "clang/Basic/OpenMPKinds.def"
1958};
1959
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001960void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1961 Visitor->AddStmt(C->getCondition());
1962}
1963
Alexey Bataev3778b602014-07-17 07:32:53 +00001964void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1965 Visitor->AddStmt(C->getCondition());
1966}
1967
Alexey Bataev568a8332014-03-06 06:15:19 +00001968void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1969 Visitor->AddStmt(C->getNumThreads());
1970}
1971
Alexey Bataev62c87d22014-03-21 04:51:18 +00001972void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1973 Visitor->AddStmt(C->getSafelen());
1974}
1975
Alexander Musman8bd31e62014-05-27 15:12:19 +00001976void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1977 Visitor->AddStmt(C->getNumForLoops());
1978}
1979
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001980void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001981
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001982void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1983
Alexey Bataev56dafe82014-06-20 07:16:17 +00001984void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1985 Visitor->AddStmt(C->getChunkSize());
1986}
1987
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001988void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1989
Alexey Bataev236070f2014-06-20 11:19:47 +00001990void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1991
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001992void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1993
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001994void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1995
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001996void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1997
Alexey Bataevdea47612014-07-23 07:46:59 +00001998void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1999
Alexey Bataev67a4f222014-07-23 10:25:33 +00002000void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2001
Alexey Bataev459dec02014-07-24 06:46:57 +00002002void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2003
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002004void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2005
Alexey Bataev756c1962013-09-24 03:17:45 +00002006template<typename T>
2007void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002008 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002009 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002010 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002011}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002012
2013void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002014 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002015 for (const auto *E : C->private_copies()) {
2016 Visitor->AddStmt(E);
2017 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002018}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002019void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2020 const OMPFirstprivateClause *C) {
2021 VisitOMPClauseList(C);
2022}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002023void OMPClauseEnqueue::VisitOMPLastprivateClause(
2024 const OMPLastprivateClause *C) {
2025 VisitOMPClauseList(C);
2026}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002027void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002028 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002029}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002030void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2031 VisitOMPClauseList(C);
2032}
Alexander Musman8dba6642014-04-22 13:09:42 +00002033void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2034 VisitOMPClauseList(C);
2035 Visitor->AddStmt(C->getStep());
2036}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002037void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2038 VisitOMPClauseList(C);
2039 Visitor->AddStmt(C->getAlignment());
2040}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002041void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2042 VisitOMPClauseList(C);
2043}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002044void
2045OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2046 VisitOMPClauseList(C);
2047}
Alexey Bataev6125da92014-07-21 11:26:11 +00002048void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2049 VisitOMPClauseList(C);
2050}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002051}
Alexey Bataev756c1962013-09-24 03:17:45 +00002052
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002053void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2054 unsigned size = WL.size();
2055 OMPClauseEnqueue Visitor(this);
2056 Visitor.Visit(S);
2057 if (size == WL.size())
2058 return;
2059 // Now reverse the entries we just added. This will match the DFS
2060 // ordering performed by the worklist.
2061 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2062 std::reverse(I, E);
2063}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002065 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2066}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002067void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 AddDecl(B->getBlockDecl());
2069}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002070void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002071 EnqueueChildren(E);
2072 AddTypeLoc(E->getTypeSourceInfo());
2073}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002074void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2075 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002076 E = S->body_rend(); I != E; ++I) {
2077 AddStmt(*I);
2078 }
2079}
2080void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 AddStmt(S->getSubStmt());
2083 AddDeclarationNameInfo(S);
2084 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2085 AddNestedNameSpecifierLoc(QualifierLoc);
2086}
2087
2088void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002089VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002090 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2091 AddDeclarationNameInfo(E);
2092 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2093 AddNestedNameSpecifierLoc(QualifierLoc);
2094 if (!E->isImplicitAccess())
2095 AddStmt(E->getBase());
2096}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 // Enqueue the initializer , if any.
2099 AddStmt(E->getInitializer());
2100 // Enqueue the array size, if any.
2101 AddStmt(E->getArraySize());
2102 // Enqueue the allocated type.
2103 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2104 // Enqueue the placement arguments.
2105 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2106 AddStmt(E->getPlacementArg(I-1));
2107}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002109 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2110 AddStmt(CE->getArg(I-1));
2111 AddStmt(CE->getCallee());
2112 AddStmt(CE->getArg(0));
2113}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002114void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2115 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 // Visit the name of the type being destroyed.
2117 AddTypeLoc(E->getDestroyedTypeInfo());
2118 // Visit the scope type that looks disturbingly like the nested-name-specifier
2119 // but isn't.
2120 AddTypeLoc(E->getScopeTypeInfo());
2121 // Visit the nested-name-specifier.
2122 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2123 AddNestedNameSpecifierLoc(QualifierLoc);
2124 // Visit base expression.
2125 AddStmt(E->getBase());
2126}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002127void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2128 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002129 AddTypeLoc(E->getTypeSourceInfo());
2130}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2132 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 EnqueueChildren(E);
2134 AddTypeLoc(E->getTypeSourceInfo());
2135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 EnqueueChildren(E);
2138 if (E->isTypeOperand())
2139 AddTypeLoc(E->getTypeOperandSourceInfo());
2140}
2141
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2143 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002144 EnqueueChildren(E);
2145 AddTypeLoc(E->getTypeSourceInfo());
2146}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 EnqueueChildren(E);
2149 if (E->isTypeOperand())
2150 AddTypeLoc(E->getTypeOperandSourceInfo());
2151}
2152
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 EnqueueChildren(S);
2155 AddDecl(S->getExceptionDecl());
2156}
2157
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002158void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
2159 AddDecl(S->getLoopVariable());
2160 AddStmt(S->getRangeInit());
2161}
2162
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002163void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 if (DR->hasExplicitTemplateArgs()) {
2165 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2166 }
2167 WL.push_back(DeclRefExprParts(DR, Parent));
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2170 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002171 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2172 AddDeclarationNameInfo(E);
2173 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 unsigned size = WL.size();
2177 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002178 for (const auto *D : S->decls()) {
2179 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 isFirst = false;
2181 }
2182 if (size == WL.size())
2183 return;
2184 // Now reverse the entries we just added. This will match the DFS
2185 // ordering performed by the worklist.
2186 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2187 std::reverse(I, E);
2188}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 D = E->designators_rbegin(), DEnd = E->designators_rend();
2193 D != DEnd; ++D) {
2194 if (D->isFieldDesignator()) {
2195 if (FieldDecl *Field = D->getField())
2196 AddMemberRef(Field, D->getFieldLoc());
2197 continue;
2198 }
2199 if (D->isArrayDesignator()) {
2200 AddStmt(E->getArrayIndex(*D));
2201 continue;
2202 }
2203 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2204 AddStmt(E->getArrayRangeEnd(*D));
2205 AddStmt(E->getArrayRangeStart(*D));
2206 }
2207}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 EnqueueChildren(E);
2210 AddTypeLoc(E->getTypeInfoAsWritten());
2211}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 AddStmt(FS->getBody());
2214 AddStmt(FS->getInc());
2215 AddStmt(FS->getCond());
2216 AddDecl(FS->getConditionVariable());
2217 AddStmt(FS->getInit());
2218}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 AddStmt(If->getElse());
2224 AddStmt(If->getThen());
2225 AddStmt(If->getCond());
2226 AddDecl(If->getConditionVariable());
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 // We care about the syntactic form of the initializer list, only.
2230 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2231 IE = Syntactic;
2232 EnqueueChildren(IE);
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 WL.push_back(MemberExprParts(M, Parent));
2236
2237 // If the base of the member access expression is an implicit 'this', don't
2238 // visit it.
2239 // FIXME: If we ever want to show these implicit accesses, this will be
2240 // unfortunate. However, clang_getCursor() relies on this behavior.
2241 if (!M->isImplicitAccess())
2242 AddStmt(M->getBase());
2243}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 AddTypeLoc(E->getEncodedTypeSourceInfo());
2246}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 EnqueueChildren(M);
2249 AddTypeLoc(M->getClassReceiverTypeInfo());
2250}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 // Visit the components of the offsetof expression.
2253 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2254 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2255 const OffsetOfNode &Node = E->getComponent(I-1);
2256 switch (Node.getKind()) {
2257 case OffsetOfNode::Array:
2258 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2259 break;
2260 case OffsetOfNode::Field:
2261 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2262 break;
2263 case OffsetOfNode::Identifier:
2264 case OffsetOfNode::Base:
2265 continue;
2266 }
2267 }
2268 // Visit the type into which we're computing the offset.
2269 AddTypeLoc(E->getTypeSourceInfo());
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2273 WL.push_back(OverloadExprParts(E, Parent));
2274}
2275void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 EnqueueChildren(E);
2278 if (E->isArgumentType())
2279 AddTypeLoc(E->getArgumentTypeInfo());
2280}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002281void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002282 EnqueueChildren(S);
2283}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 AddStmt(S->getBody());
2286 AddStmt(S->getCond());
2287 AddDecl(S->getConditionVariable());
2288}
2289
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 AddStmt(W->getBody());
2292 AddStmt(W->getCond());
2293 AddDecl(W->getConditionVariable());
2294}
2295
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002296void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002297 for (unsigned I = E->getNumArgs(); I > 0; --I)
2298 AddTypeLoc(E->getArg(I-1));
2299}
2300
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002301void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002302 AddTypeLoc(E->getQueriedTypeSourceInfo());
2303}
2304
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002305void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002306 EnqueueChildren(E);
2307}
2308
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 VisitOverloadExpr(U);
2311 if (!U->isImplicitAccess())
2312 AddStmt(U->getBase());
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 AddStmt(E->getSubExpr());
2316 AddTypeLoc(E->getWrittenTypeInfo());
2317}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002319 WL.push_back(SizeOfPackExprParts(E, Parent));
2320}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002321void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002322 // If the opaque value has a source expression, just transparently
2323 // visit that. This is useful for (e.g.) pseudo-object expressions.
2324 if (Expr *SourceExpr = E->getSourceExpr())
2325 return Visit(SourceExpr);
2326}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002327void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002328 AddStmt(E->getBody());
2329 WL.push_back(LambdaExprParts(E, Parent));
2330}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002331void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002332 // Treat the expression like its syntactic form.
2333 Visit(E->getSyntacticForm());
2334}
2335
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002336void EnqueueVisitor::VisitOMPExecutableDirective(
2337 const OMPExecutableDirective *D) {
2338 EnqueueChildren(D);
2339 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2340 E = D->clauses().end();
2341 I != E; ++I)
2342 EnqueueChildren(*I);
2343}
2344
Alexander Musman3aaab662014-08-19 11:27:13 +00002345void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2346 VisitOMPExecutableDirective(D);
2347}
2348
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002349void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2350 VisitOMPExecutableDirective(D);
2351}
2352
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002353void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002354 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002355}
2356
Alexey Bataevf29276e2014-06-18 04:14:57 +00002357void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002358 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002359}
2360
Alexander Musmanf82886e2014-09-18 05:12:34 +00002361void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2362 VisitOMPLoopDirective(D);
2363}
2364
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002365void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2366 VisitOMPExecutableDirective(D);
2367}
2368
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002369void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2370 VisitOMPExecutableDirective(D);
2371}
2372
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002373void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2374 VisitOMPExecutableDirective(D);
2375}
2376
Alexander Musman80c22892014-07-17 08:54:58 +00002377void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2378 VisitOMPExecutableDirective(D);
2379}
2380
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002381void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2382 VisitOMPExecutableDirective(D);
2383 AddDeclarationNameInfo(D);
2384}
2385
Alexey Bataev4acb8592014-07-07 13:01:15 +00002386void
2387EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002388 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002389}
2390
Alexander Musmane4e893b2014-09-23 09:33:00 +00002391void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2392 const OMPParallelForSimdDirective *D) {
2393 VisitOMPLoopDirective(D);
2394}
2395
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002396void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2397 const OMPParallelSectionsDirective *D) {
2398 VisitOMPExecutableDirective(D);
2399}
2400
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002401void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2402 VisitOMPExecutableDirective(D);
2403}
2404
Alexey Bataev68446b72014-07-18 07:47:19 +00002405void
2406EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2407 VisitOMPExecutableDirective(D);
2408}
2409
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002410void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2411 VisitOMPExecutableDirective(D);
2412}
2413
Alexey Bataev2df347a2014-07-18 10:17:07 +00002414void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2415 VisitOMPExecutableDirective(D);
2416}
2417
Alexey Bataev6125da92014-07-21 11:26:11 +00002418void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2419 VisitOMPExecutableDirective(D);
2420}
2421
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002422void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2423 VisitOMPExecutableDirective(D);
2424}
2425
Alexey Bataev0162e452014-07-22 10:10:35 +00002426void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2427 VisitOMPExecutableDirective(D);
2428}
2429
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002430void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2431 VisitOMPExecutableDirective(D);
2432}
2433
Alexey Bataev13314bf2014-10-09 04:18:56 +00002434void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2435 VisitOMPExecutableDirective(D);
2436}
2437
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2440}
2441
2442bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2443 if (RegionOfInterest.isValid()) {
2444 SourceRange Range = getRawCursorExtent(C);
2445 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2446 return false;
2447 }
2448 return true;
2449}
2450
2451bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2452 while (!WL.empty()) {
2453 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002454 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002455
2456 // Set the Parent field, then back to its old value once we're done.
2457 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2458
2459 switch (LI.getKind()) {
2460 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002461 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002462 if (!D)
2463 continue;
2464
2465 // For now, perform default visitation for Decls.
2466 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2467 cast<DeclVisit>(&LI)->isFirst())))
2468 return true;
2469
2470 continue;
2471 }
2472 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2473 const ASTTemplateArgumentListInfo *ArgList =
2474 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2475 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2476 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2477 Arg != ArgEnd; ++Arg) {
2478 if (VisitTemplateArgumentLoc(*Arg))
2479 return true;
2480 }
2481 continue;
2482 }
2483 case VisitorJob::TypeLocVisitKind: {
2484 // Perform default visitation for TypeLocs.
2485 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2486 return true;
2487 continue;
2488 }
2489 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002490 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002491 if (LabelStmt *stmt = LS->getStmt()) {
2492 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2493 TU))) {
2494 return true;
2495 }
2496 }
2497 continue;
2498 }
2499
2500 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2501 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2502 if (VisitNestedNameSpecifierLoc(V->get()))
2503 return true;
2504 continue;
2505 }
2506
2507 case VisitorJob::DeclarationNameInfoVisitKind: {
2508 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2509 ->get()))
2510 return true;
2511 continue;
2512 }
2513 case VisitorJob::MemberRefVisitKind: {
2514 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2515 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2516 return true;
2517 continue;
2518 }
2519 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002520 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002521 if (!S)
2522 continue;
2523
2524 // Update the current cursor.
2525 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2526 if (!IsInRegionOfInterest(Cursor))
2527 continue;
2528 switch (Visitor(Cursor, Parent, ClientData)) {
2529 case CXChildVisit_Break: return true;
2530 case CXChildVisit_Continue: break;
2531 case CXChildVisit_Recurse:
2532 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002533 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002534 EnqueueWorkList(WL, S);
2535 break;
2536 }
2537 continue;
2538 }
2539 case VisitorJob::MemberExprPartsKind: {
2540 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002541 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002542
2543 // Visit the nested-name-specifier
2544 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2545 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2546 return true;
2547
2548 // Visit the declaration name.
2549 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2550 return true;
2551
2552 // Visit the explicitly-specified template arguments, if any.
2553 if (M->hasExplicitTemplateArgs()) {
2554 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2555 *ArgEnd = Arg + M->getNumTemplateArgs();
2556 Arg != ArgEnd; ++Arg) {
2557 if (VisitTemplateArgumentLoc(*Arg))
2558 return true;
2559 }
2560 }
2561 continue;
2562 }
2563 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002564 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002565 // Visit nested-name-specifier, if present.
2566 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2567 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2568 return true;
2569 // Visit declaration name.
2570 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2571 return true;
2572 continue;
2573 }
2574 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002575 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002576 // Visit the nested-name-specifier.
2577 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2578 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2579 return true;
2580 // Visit the declaration name.
2581 if (VisitDeclarationNameInfo(O->getNameInfo()))
2582 return true;
2583 // Visit the overloaded declaration reference.
2584 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2585 return true;
2586 continue;
2587 }
2588 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002589 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002590 NamedDecl *Pack = E->getPack();
2591 if (isa<TemplateTypeParmDecl>(Pack)) {
2592 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2593 E->getPackLoc(), TU)))
2594 return true;
2595
2596 continue;
2597 }
2598
2599 if (isa<TemplateTemplateParmDecl>(Pack)) {
2600 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2601 E->getPackLoc(), TU)))
2602 return true;
2603
2604 continue;
2605 }
2606
2607 // Non-type template parameter packs and function parameter packs are
2608 // treated like DeclRefExpr cursors.
2609 continue;
2610 }
2611
2612 case VisitorJob::LambdaExprPartsKind: {
2613 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002614 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002615 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2616 CEnd = E->explicit_capture_end();
2617 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002618 // FIXME: Lambda init-captures.
2619 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002620 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002621
Guy Benyei11169dd2012-12-18 14:30:41 +00002622 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2623 C->getLocation(),
2624 TU)))
2625 return true;
2626 }
2627
2628 // Visit parameters and return type, if present.
2629 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2630 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2631 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2632 // Visit the whole type.
2633 if (Visit(TL))
2634 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002635 } else if (FunctionProtoTypeLoc Proto =
2636 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002637 if (E->hasExplicitParameters()) {
2638 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002639 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2640 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002641 return true;
2642 } else {
2643 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002644 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002645 return true;
2646 }
2647 }
2648 }
2649 break;
2650 }
2651
2652 case VisitorJob::PostChildrenVisitKind:
2653 if (PostChildrenVisitor(Parent, ClientData))
2654 return true;
2655 break;
2656 }
2657 }
2658 return false;
2659}
2660
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002661bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002662 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002663 if (!WorkListFreeList.empty()) {
2664 WL = WorkListFreeList.back();
2665 WL->clear();
2666 WorkListFreeList.pop_back();
2667 }
2668 else {
2669 WL = new VisitorWorkList();
2670 WorkListCache.push_back(WL);
2671 }
2672 EnqueueWorkList(*WL, S);
2673 bool result = RunVisitorWorkList(*WL);
2674 WorkListFreeList.push_back(WL);
2675 return result;
2676}
2677
2678namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002679typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002680RefNamePieces
2681buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2682 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2683 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002684 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2685 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2686 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2687
2688 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2689
2690 RefNamePieces Pieces;
2691
2692 if (WantQualifier && QLoc.isValid())
2693 Pieces.push_back(QLoc);
2694
2695 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2696 Pieces.push_back(NI.getLoc());
2697
2698 if (WantTemplateArgs && TemplateArgs)
2699 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2700 TemplateArgs->RAngleLoc));
2701
2702 if (Kind == DeclarationName::CXXOperatorName) {
2703 Pieces.push_back(SourceLocation::getFromRawEncoding(
2704 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2705 Pieces.push_back(SourceLocation::getFromRawEncoding(
2706 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2707 }
2708
2709 if (WantSinglePiece) {
2710 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2711 Pieces.clear();
2712 Pieces.push_back(R);
2713 }
2714
2715 return Pieces;
2716}
2717}
2718
2719//===----------------------------------------------------------------------===//
2720// Misc. API hooks.
2721//===----------------------------------------------------------------------===//
2722
Chad Rosier05c71aa2013-03-27 18:28:23 +00002723static void fatal_error_handler(void *user_data, const std::string& reason,
2724 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002725 // Write the result out to stderr avoiding errs() because raw_ostreams can
2726 // call report_fatal_error.
2727 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2728 ::abort();
2729}
2730
Chandler Carruth66660742014-06-27 16:37:27 +00002731namespace {
2732struct RegisterFatalErrorHandler {
2733 RegisterFatalErrorHandler() {
2734 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2735 }
2736};
2737}
2738
2739static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2740
Guy Benyei11169dd2012-12-18 14:30:41 +00002741extern "C" {
2742CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2743 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002744 // We use crash recovery to make some of our APIs more reliable, implicitly
2745 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002746 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2747 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002748
Chandler Carruth66660742014-06-27 16:37:27 +00002749 // Look through the managed static to trigger construction of the managed
2750 // static which registers our fatal error handler. This ensures it is only
2751 // registered once.
2752 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002753
2754 CIndexer *CIdxr = new CIndexer();
2755 if (excludeDeclarationsFromPCH)
2756 CIdxr->setOnlyLocalDecls();
2757 if (displayDiagnostics)
2758 CIdxr->setDisplayDiagnostics();
2759
2760 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2761 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2762 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2763 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2764 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2765 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2766
2767 return CIdxr;
2768}
2769
2770void clang_disposeIndex(CXIndex CIdx) {
2771 if (CIdx)
2772 delete static_cast<CIndexer *>(CIdx);
2773}
2774
2775void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2776 if (CIdx)
2777 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2778}
2779
2780unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2781 if (CIdx)
2782 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2783 return 0;
2784}
2785
2786void clang_toggleCrashRecovery(unsigned isEnabled) {
2787 if (isEnabled)
2788 llvm::CrashRecoveryContext::Enable();
2789 else
2790 llvm::CrashRecoveryContext::Disable();
2791}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002792
Guy Benyei11169dd2012-12-18 14:30:41 +00002793CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2794 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002795 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002796 enum CXErrorCode Result =
2797 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002798 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002799 assert((TU && Result == CXError_Success) ||
2800 (!TU && Result != CXError_Success));
2801 return TU;
2802}
2803
2804enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2805 const char *ast_filename,
2806 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002807 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002808 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002809
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002810 if (!CIdx || !ast_filename || !out_TU)
2811 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002812
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002813 LOG_FUNC_SECTION {
2814 *Log << ast_filename;
2815 }
2816
Guy Benyei11169dd2012-12-18 14:30:41 +00002817 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2818 FileSystemOptions FileSystemOpts;
2819
Justin Bognerd512c1e2014-10-15 00:33:06 +00002820 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2821 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002822 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2823 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2824 /*CaptureDiagnostics=*/true,
2825 /*AllowPCHWithCompilerErrors=*/true,
2826 /*UserFilesAreVolatile=*/true);
2827 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002828 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002829}
2830
2831unsigned clang_defaultEditingTranslationUnitOptions() {
2832 return CXTranslationUnit_PrecompiledPreamble |
2833 CXTranslationUnit_CacheCompletionResults;
2834}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002835
Guy Benyei11169dd2012-12-18 14:30:41 +00002836CXTranslationUnit
2837clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2838 const char *source_filename,
2839 int num_command_line_args,
2840 const char * const *command_line_args,
2841 unsigned num_unsaved_files,
2842 struct CXUnsavedFile *unsaved_files) {
2843 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2844 return clang_parseTranslationUnit(CIdx, source_filename,
2845 command_line_args, num_command_line_args,
2846 unsaved_files, num_unsaved_files,
2847 Options);
2848}
2849
2850struct ParseTranslationUnitInfo {
2851 CXIndex CIdx;
2852 const char *source_filename;
2853 const char *const *command_line_args;
2854 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002855 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002857 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002858 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002859};
2860static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002861 const ParseTranslationUnitInfo *PTUI =
2862 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002863 CXIndex CIdx = PTUI->CIdx;
2864 const char *source_filename = PTUI->source_filename;
2865 const char * const *command_line_args = PTUI->command_line_args;
2866 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002867 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002868 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002869
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002870 // Set up the initial return values.
2871 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002872 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002873
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002874 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002875 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002876 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002877 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002878 }
2879
Guy Benyei11169dd2012-12-18 14:30:41 +00002880 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2881
2882 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2883 setThreadBackgroundPriority();
2884
2885 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2886 // FIXME: Add a flag for modules.
2887 TranslationUnitKind TUKind
2888 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002889 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002890 = options & CXTranslationUnit_CacheCompletionResults;
2891 bool IncludeBriefCommentsInCodeCompletion
2892 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2893 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2894 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2895
2896 // Configure the diagnostics.
2897 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002898 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002899
2900 // Recover resources if we crash before exiting this function.
2901 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2902 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002903 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002904
Ahmed Charlesb8984322014-03-07 20:03:18 +00002905 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2906 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002907
2908 // Recover resources if we crash before exiting this function.
2909 llvm::CrashRecoveryContextCleanupRegistrar<
2910 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2911
Alp Toker9d85b182014-07-07 01:23:14 +00002912 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002913 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002914 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002915 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002916 }
2917
Ahmed Charlesb8984322014-03-07 20:03:18 +00002918 std::unique_ptr<std::vector<const char *>> Args(
2919 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002920
2921 // Recover resources if we crash before exiting this method.
2922 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2923 ArgsCleanup(Args.get());
2924
2925 // Since the Clang C library is primarily used by batch tools dealing with
2926 // (often very broken) source code, where spell-checking can have a
2927 // significant negative impact on performance (particularly when
2928 // precompiled headers are involved), we disable it by default.
2929 // Only do this if we haven't found a spell-checking-related argument.
2930 bool FoundSpellCheckingArgument = false;
2931 for (int I = 0; I != num_command_line_args; ++I) {
2932 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2933 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2934 FoundSpellCheckingArgument = true;
2935 break;
2936 }
2937 }
2938 if (!FoundSpellCheckingArgument)
2939 Args->push_back("-fno-spell-checking");
2940
2941 Args->insert(Args->end(), command_line_args,
2942 command_line_args + num_command_line_args);
2943
2944 // The 'source_filename' argument is optional. If the caller does not
2945 // specify it then it is assumed that the source file is specified
2946 // in the actual argument list.
2947 // Put the source file after command_line_args otherwise if '-x' flag is
2948 // present it will be unused.
2949 if (source_filename)
2950 Args->push_back(source_filename);
2951
2952 // Do we need the detailed preprocessing record?
2953 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2954 Args->push_back("-Xclang");
2955 Args->push_back("-detailed-preprocessing-record");
2956 }
2957
2958 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002959 std::unique_ptr<ASTUnit> ErrUnit;
2960 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002961 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002962 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2963 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2964 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2965 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2966 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2967 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002968
2969 if (NumErrors != Diags->getClient()->getNumErrors()) {
2970 // Make sure to check that 'Unit' is non-NULL.
2971 if (CXXIdx->getDisplayDiagnostics())
2972 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2973 }
2974
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002975 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2976 PTUI->result = CXError_ASTReadError;
2977 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002978 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002979 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2980 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002981}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002982
2983CXTranslationUnit
2984clang_parseTranslationUnit(CXIndex CIdx,
2985 const char *source_filename,
2986 const char *const *command_line_args,
2987 int num_command_line_args,
2988 struct CXUnsavedFile *unsaved_files,
2989 unsigned num_unsaved_files,
2990 unsigned options) {
2991 CXTranslationUnit TU;
2992 enum CXErrorCode Result = clang_parseTranslationUnit2(
2993 CIdx, source_filename, command_line_args, num_command_line_args,
2994 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002995 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002996 assert((TU && Result == CXError_Success) ||
2997 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998 return TU;
2999}
3000
3001enum CXErrorCode clang_parseTranslationUnit2(
3002 CXIndex CIdx,
3003 const char *source_filename,
3004 const char *const *command_line_args,
3005 int num_command_line_args,
3006 struct CXUnsavedFile *unsaved_files,
3007 unsigned num_unsaved_files,
3008 unsigned options,
3009 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003010 LOG_FUNC_SECTION {
3011 *Log << source_filename << ": ";
3012 for (int i = 0; i != num_command_line_args; ++i)
3013 *Log << command_line_args[i] << " ";
3014 }
3015
Alp Toker9d85b182014-07-07 01:23:14 +00003016 if (num_unsaved_files && !unsaved_files)
3017 return CXError_InvalidArguments;
3018
Alp Toker5c532982014-07-07 22:42:03 +00003019 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003020 ParseTranslationUnitInfo PTUI = {
3021 CIdx,
3022 source_filename,
3023 command_line_args,
3024 num_command_line_args,
3025 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3026 options,
3027 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00003028 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003029 llvm::CrashRecoveryContext CRC;
3030
3031 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3032 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3033 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3034 fprintf(stderr, " 'command_line_args' : [");
3035 for (int i = 0; i != num_command_line_args; ++i) {
3036 if (i)
3037 fprintf(stderr, ", ");
3038 fprintf(stderr, "'%s'", command_line_args[i]);
3039 }
3040 fprintf(stderr, "],\n");
3041 fprintf(stderr, " 'unsaved_files' : [");
3042 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3043 if (i)
3044 fprintf(stderr, ", ");
3045 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3046 unsaved_files[i].Length);
3047 }
3048 fprintf(stderr, "],\n");
3049 fprintf(stderr, " 'options' : %d,\n", options);
3050 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003051
3052 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003053 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003054 if (CXTranslationUnit *TU = PTUI.out_TU)
3055 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003056 }
Alp Toker5c532982014-07-07 22:42:03 +00003057
3058 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003059}
3060
3061unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3062 return CXSaveTranslationUnit_None;
3063}
3064
3065namespace {
3066
3067struct SaveTranslationUnitInfo {
3068 CXTranslationUnit TU;
3069 const char *FileName;
3070 unsigned options;
3071 CXSaveError result;
3072};
3073
3074}
3075
3076static void clang_saveTranslationUnit_Impl(void *UserData) {
3077 SaveTranslationUnitInfo *STUI =
3078 static_cast<SaveTranslationUnitInfo*>(UserData);
3079
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003080 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003081 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3082 setThreadBackgroundPriority();
3083
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003084 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003085 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3086}
3087
3088int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3089 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003090 LOG_FUNC_SECTION {
3091 *Log << TU << ' ' << FileName;
3092 }
3093
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003094 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003095 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003096 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003097 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003098
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003099 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003100 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3101 if (!CXXUnit->hasSema())
3102 return CXSaveError_InvalidTU;
3103
3104 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3105
3106 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3107 getenv("LIBCLANG_NOTHREADS")) {
3108 clang_saveTranslationUnit_Impl(&STUI);
3109
3110 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3111 PrintLibclangResourceUsage(TU);
3112
3113 return STUI.result;
3114 }
3115
3116 // We have an AST that has invalid nodes due to compiler errors.
3117 // Use a crash recovery thread for protection.
3118
3119 llvm::CrashRecoveryContext CRC;
3120
3121 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3122 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3123 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3124 fprintf(stderr, " 'options' : %d,\n", options);
3125 fprintf(stderr, "}\n");
3126
3127 return CXSaveError_Unknown;
3128
3129 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3130 PrintLibclangResourceUsage(TU);
3131 }
3132
3133 return STUI.result;
3134}
3135
3136void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3137 if (CTUnit) {
3138 // If the translation unit has been marked as unsafe to free, just discard
3139 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003140 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3141 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003142 return;
3143
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003144 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003145 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003146 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3147 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003148 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 delete CTUnit;
3150 }
3151}
3152
3153unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3154 return CXReparse_None;
3155}
3156
3157struct ReparseTranslationUnitInfo {
3158 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003159 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003160 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003161 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003162};
3163
3164static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003165 const ReparseTranslationUnitInfo *RTUI =
3166 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003168 unsigned options = RTUI->options;
3169 (void) options;
3170
3171 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003172 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003173 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003174 RTUI->result = CXError_InvalidArguments;
3175 return;
3176 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003177
3178 // Reset the associated diagnostics.
3179 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003180 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003181
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003182 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3184 setThreadBackgroundPriority();
3185
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003186 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003188
3189 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3190 new std::vector<ASTUnit::RemappedFile>());
3191
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 // Recover resources if we crash before exiting this function.
3193 llvm::CrashRecoveryContextCleanupRegistrar<
3194 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003195
3196 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003197 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003198 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003199 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003201
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003202 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003203 RTUI->result = CXError_Success;
3204 else if (isASTReadError(CXXUnit))
3205 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003206}
3207
3208int clang_reparseTranslationUnit(CXTranslationUnit TU,
3209 unsigned num_unsaved_files,
3210 struct CXUnsavedFile *unsaved_files,
3211 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003212 LOG_FUNC_SECTION {
3213 *Log << TU;
3214 }
3215
Alp Toker9d85b182014-07-07 01:23:14 +00003216 if (num_unsaved_files && !unsaved_files)
3217 return CXError_InvalidArguments;
3218
Alp Toker5c532982014-07-07 22:42:03 +00003219 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003220 ReparseTranslationUnitInfo RTUI = {
3221 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003222 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003223
3224 if (getenv("LIBCLANG_NOTHREADS")) {
3225 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003226 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 }
3228
3229 llvm::CrashRecoveryContext CRC;
3230
3231 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3232 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003233 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003234 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003235 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3236 PrintLibclangResourceUsage(TU);
3237
Alp Toker5c532982014-07-07 22:42:03 +00003238 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003239}
3240
3241
3242CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003243 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003244 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003245 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003246 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003247
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003248 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003249 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003250}
3251
3252CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003253 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003254 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003255 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003256 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003257
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003258 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3260}
3261
3262} // end: extern "C"
3263
3264//===----------------------------------------------------------------------===//
3265// CXFile Operations.
3266//===----------------------------------------------------------------------===//
3267
3268extern "C" {
3269CXString clang_getFileName(CXFile SFile) {
3270 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003271 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003272
3273 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003274 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003275}
3276
3277time_t clang_getFileTime(CXFile SFile) {
3278 if (!SFile)
3279 return 0;
3280
3281 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3282 return FEnt->getModificationTime();
3283}
3284
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003285CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003286 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003287 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003288 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003289 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003290
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003291 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003292
3293 FileManager &FMgr = CXXUnit->getFileManager();
3294 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3295}
3296
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003297unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3298 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003299 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003300 LOG_BAD_TU(TU);
3301 return 0;
3302 }
3303
3304 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 return 0;
3306
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003307 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 FileEntry *FEnt = static_cast<FileEntry *>(file);
3309 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3310 .isFileMultipleIncludeGuarded(FEnt);
3311}
3312
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003313int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3314 if (!file || !outID)
3315 return 1;
3316
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003317 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003318 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3319 outID->data[0] = ID.getDevice();
3320 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003321 outID->data[2] = FEnt->getModificationTime();
3322 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003323}
3324
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003325int clang_File_isEqual(CXFile file1, CXFile file2) {
3326 if (file1 == file2)
3327 return true;
3328
3329 if (!file1 || !file2)
3330 return false;
3331
3332 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3333 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3334 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3335}
3336
Guy Benyei11169dd2012-12-18 14:30:41 +00003337} // end: extern "C"
3338
3339//===----------------------------------------------------------------------===//
3340// CXCursor Operations.
3341//===----------------------------------------------------------------------===//
3342
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003343static const Decl *getDeclFromExpr(const Stmt *E) {
3344 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 return getDeclFromExpr(CE->getSubExpr());
3346
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003347 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003349 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003351 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003353 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 if (PRE->isExplicitProperty())
3355 return PRE->getExplicitProperty();
3356 // It could be messaging both getter and setter as in:
3357 // ++myobj.myprop;
3358 // in which case prefer to associate the setter since it is less obvious
3359 // from inspecting the source that the setter is going to get called.
3360 if (PRE->isMessagingSetter())
3361 return PRE->getImplicitPropertySetter();
3362 return PRE->getImplicitPropertyGetter();
3363 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003364 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003366 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 if (Expr *Src = OVE->getSourceExpr())
3368 return getDeclFromExpr(Src);
3369
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003370 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003372 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 if (!CE->isElidable())
3374 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003375 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 return OME->getMethodDecl();
3377
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003378 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003380 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3382 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003383 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3385 isa<ParmVarDecl>(SizeOfPack->getPack()))
3386 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003387
3388 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003389}
3390
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003391static SourceLocation getLocationFromExpr(const Expr *E) {
3392 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 return getLocationFromExpr(CE->getSubExpr());
3394
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003395 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003397 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003398 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003399 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003401 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003402 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003403 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003405 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003406 return PropRef->getLocation();
3407
3408 return E->getLocStart();
3409}
3410
3411extern "C" {
3412
3413unsigned clang_visitChildren(CXCursor parent,
3414 CXCursorVisitor visitor,
3415 CXClientData client_data) {
3416 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3417 /*VisitPreprocessorLast=*/false);
3418 return CursorVis.VisitChildren(parent);
3419}
3420
3421#ifndef __has_feature
3422#define __has_feature(x) 0
3423#endif
3424#if __has_feature(blocks)
3425typedef enum CXChildVisitResult
3426 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3427
3428static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3429 CXClientData client_data) {
3430 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3431 return block(cursor, parent);
3432}
3433#else
3434// If we are compiled with a compiler that doesn't have native blocks support,
3435// define and call the block manually, so the
3436typedef struct _CXChildVisitResult
3437{
3438 void *isa;
3439 int flags;
3440 int reserved;
3441 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3442 CXCursor);
3443} *CXCursorVisitorBlock;
3444
3445static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3446 CXClientData client_data) {
3447 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3448 return block->invoke(block, cursor, parent);
3449}
3450#endif
3451
3452
3453unsigned clang_visitChildrenWithBlock(CXCursor parent,
3454 CXCursorVisitorBlock block) {
3455 return clang_visitChildren(parent, visitWithBlock, block);
3456}
3457
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003458static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003460 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003461
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003462 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003464 if (const ObjCPropertyImplDecl *PropImpl =
3465 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003467 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003468
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003469 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003471 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003472
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003473 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 }
3475
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003476 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003477 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003478
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003479 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3481 // and returns different names. NamedDecl returns the class name and
3482 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003483 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003484
3485 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003486 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003487
3488 SmallString<1024> S;
3489 llvm::raw_svector_ostream os(S);
3490 ND->printName(os);
3491
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003492 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003493}
3494
3495CXString clang_getCursorSpelling(CXCursor C) {
3496 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003497 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003498
3499 if (clang_isReference(C.kind)) {
3500 switch (C.kind) {
3501 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003502 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003503 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 }
3505 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003506 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003507 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 }
3509 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003510 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003512 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003513 }
3514 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003515 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003516 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 }
3518 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003519 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 assert(Type && "Missing type decl");
3521
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003522 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 getAsString());
3524 }
3525 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003526 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 assert(Template && "Missing template decl");
3528
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003529 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 }
3531
3532 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003533 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 assert(NS && "Missing namespace decl");
3535
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003536 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 }
3538
3539 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003540 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 assert(Field && "Missing member decl");
3542
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003543 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 }
3545
3546 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003547 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 assert(Label && "Missing label");
3549
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003550 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 }
3552
3553 case CXCursor_OverloadedDeclRef: {
3554 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003555 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3556 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003557 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003558 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003560 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003561 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 OverloadedTemplateStorage *Ovl
3563 = Storage.get<OverloadedTemplateStorage*>();
3564 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003565 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003566 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 }
3568
3569 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003570 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 assert(Var && "Missing variable decl");
3572
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003573 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003574 }
3575
3576 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003577 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 }
3579 }
3580
3581 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003582 const Expr *E = getCursorExpr(C);
3583
3584 if (C.kind == CXCursor_ObjCStringLiteral ||
3585 C.kind == CXCursor_StringLiteral) {
3586 const StringLiteral *SLit;
3587 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3588 SLit = OSL->getString();
3589 } else {
3590 SLit = cast<StringLiteral>(E);
3591 }
3592 SmallString<256> Buf;
3593 llvm::raw_svector_ostream OS(Buf);
3594 SLit->outputString(OS);
3595 return cxstring::createDup(OS.str());
3596 }
3597
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003598 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 if (D)
3600 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003601 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 }
3603
3604 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003605 const Stmt *S = getCursorStmt(C);
3606 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003607 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003608
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003609 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 }
3611
3612 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003613 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 ->getNameStart());
3615
3616 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003617 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 ->getNameStart());
3619
3620 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003621 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003622
3623 if (clang_isDeclaration(C.kind))
3624 return getDeclSpelling(getCursorDecl(C));
3625
3626 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003627 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003628 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 }
3630
3631 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003632 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003633 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 }
3635
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003636 if (C.kind == CXCursor_PackedAttr) {
3637 return cxstring::createRef("packed");
3638 }
3639
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003640 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003641}
3642
3643CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3644 unsigned pieceIndex,
3645 unsigned options) {
3646 if (clang_Cursor_isNull(C))
3647 return clang_getNullRange();
3648
3649 ASTContext &Ctx = getCursorContext(C);
3650
3651 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003652 const Stmt *S = getCursorStmt(C);
3653 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 if (pieceIndex > 0)
3655 return clang_getNullRange();
3656 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3657 }
3658
3659 return clang_getNullRange();
3660 }
3661
3662 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003663 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3665 if (pieceIndex >= ME->getNumSelectorLocs())
3666 return clang_getNullRange();
3667 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3668 }
3669 }
3670
3671 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3672 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003673 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3675 if (pieceIndex >= MD->getNumSelectorLocs())
3676 return clang_getNullRange();
3677 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3678 }
3679 }
3680
3681 if (C.kind == CXCursor_ObjCCategoryDecl ||
3682 C.kind == CXCursor_ObjCCategoryImplDecl) {
3683 if (pieceIndex > 0)
3684 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003685 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3687 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003688 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3690 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3691 }
3692
3693 if (C.kind == CXCursor_ModuleImportDecl) {
3694 if (pieceIndex > 0)
3695 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003696 if (const ImportDecl *ImportD =
3697 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3699 if (!Locs.empty())
3700 return cxloc::translateSourceRange(Ctx,
3701 SourceRange(Locs.front(), Locs.back()));
3702 }
3703 return clang_getNullRange();
3704 }
3705
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003706 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3707 C.kind == CXCursor_ConversionFunction) {
3708 if (pieceIndex > 0)
3709 return clang_getNullRange();
3710 if (const FunctionDecl *FD =
3711 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3712 DeclarationNameInfo FunctionName = FD->getNameInfo();
3713 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3714 }
3715 return clang_getNullRange();
3716 }
3717
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 // FIXME: A CXCursor_InclusionDirective should give the location of the
3719 // filename, but we don't keep track of this.
3720
3721 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3722 // but we don't keep track of this.
3723
3724 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3725 // but we don't keep track of this.
3726
3727 // Default handling, give the location of the cursor.
3728
3729 if (pieceIndex > 0)
3730 return clang_getNullRange();
3731
3732 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3733 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3734 return cxloc::translateSourceRange(Ctx, Loc);
3735}
3736
Eli Bendersky44a206f2014-07-31 18:04:56 +00003737CXString clang_Cursor_getMangling(CXCursor C) {
3738 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3739 return cxstring::createEmpty();
3740
Eli Bendersky44a206f2014-07-31 18:04:56 +00003741 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003742 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003743 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3744 return cxstring::createEmpty();
3745
Eli Bendersky79759592014-08-01 15:01:10 +00003746 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003747 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003748 ASTContext &Ctx = ND->getASTContext();
3749 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003750
Eli Bendersky79759592014-08-01 15:01:10 +00003751 std::string FrontendBuf;
3752 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3753 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003754
Eli Bendersky79759592014-08-01 15:01:10 +00003755 // Now apply backend mangling.
3756 std::unique_ptr<llvm::DataLayout> DL(
3757 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3758 llvm::Mangler BackendMangler(DL.get());
3759
3760 std::string FinalBuf;
3761 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3762 BackendMangler.getNameWithPrefix(FinalBufOS,
3763 llvm::Twine(FrontendBufOS.str()));
3764
3765 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003766}
3767
Guy Benyei11169dd2012-12-18 14:30:41 +00003768CXString clang_getCursorDisplayName(CXCursor C) {
3769 if (!clang_isDeclaration(C.kind))
3770 return clang_getCursorSpelling(C);
3771
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003772 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003774 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003775
3776 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003777 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 D = FunTmpl->getTemplatedDecl();
3779
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003780 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 SmallString<64> Str;
3782 llvm::raw_svector_ostream OS(Str);
3783 OS << *Function;
3784 if (Function->getPrimaryTemplate())
3785 OS << "<>";
3786 OS << "(";
3787 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3788 if (I)
3789 OS << ", ";
3790 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3791 }
3792
3793 if (Function->isVariadic()) {
3794 if (Function->getNumParams())
3795 OS << ", ";
3796 OS << "...";
3797 }
3798 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003799 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 }
3801
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003802 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 SmallString<64> Str;
3804 llvm::raw_svector_ostream OS(Str);
3805 OS << *ClassTemplate;
3806 OS << "<";
3807 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3808 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3809 if (I)
3810 OS << ", ";
3811
3812 NamedDecl *Param = Params->getParam(I);
3813 if (Param->getIdentifier()) {
3814 OS << Param->getIdentifier()->getName();
3815 continue;
3816 }
3817
3818 // There is no parameter name, which makes this tricky. Try to come up
3819 // with something useful that isn't too long.
3820 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3821 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3822 else if (NonTypeTemplateParmDecl *NTTP
3823 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3824 OS << NTTP->getType().getAsString(Policy);
3825 else
3826 OS << "template<...> class";
3827 }
3828
3829 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003830 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 }
3832
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003833 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3835 // If the type was explicitly written, use that.
3836 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003837 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003838
Benjamin Kramer9170e912013-02-22 15:46:01 +00003839 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 llvm::raw_svector_ostream OS(Str);
3841 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003842 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 ClassSpec->getTemplateArgs().data(),
3844 ClassSpec->getTemplateArgs().size(),
3845 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003846 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 }
3848
3849 return clang_getCursorSpelling(C);
3850}
3851
3852CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3853 switch (Kind) {
3854 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003949 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003982 case CXCursor_ObjCSelfExpr:
3983 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004039 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004069 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004072 case CXCursor_SEHLeaveStmt:
4073 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004077 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004078 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004079 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004083 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004085 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004102 case CXCursor_PackedAttr:
4103 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004104 case CXCursor_PureAttr:
4105 return cxstring::createRef("attribute(pure)");
4106 case CXCursor_ConstAttr:
4107 return cxstring::createRef("attribute(const)");
4108 case CXCursor_NoDuplicateAttr:
4109 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004110 case CXCursor_CUDAConstantAttr:
4111 return cxstring::createRef("attribute(constant)");
4112 case CXCursor_CUDADeviceAttr:
4113 return cxstring::createRef("attribute(device)");
4114 case CXCursor_CUDAGlobalAttr:
4115 return cxstring::createRef("attribute(global)");
4116 case CXCursor_CUDAHostAttr:
4117 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004118 case CXCursor_CUDASharedAttr:
4119 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004135 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004137 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004139 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004141 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004142 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004143 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004145 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004146 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004147 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004149 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004151 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004152 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004153 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004154 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004155 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004156 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004157 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004159 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004161 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004163 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004164 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004167 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004168 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004169 return cxstring::createRef("OMPParallelDirective");
4170 case CXCursor_OMPSimdDirective:
4171 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004172 case CXCursor_OMPForDirective:
4173 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004174 case CXCursor_OMPForSimdDirective:
4175 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004176 case CXCursor_OMPSectionsDirective:
4177 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004178 case CXCursor_OMPSectionDirective:
4179 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004180 case CXCursor_OMPSingleDirective:
4181 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004182 case CXCursor_OMPMasterDirective:
4183 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004184 case CXCursor_OMPCriticalDirective:
4185 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004186 case CXCursor_OMPParallelForDirective:
4187 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004188 case CXCursor_OMPParallelForSimdDirective:
4189 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004190 case CXCursor_OMPParallelSectionsDirective:
4191 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004192 case CXCursor_OMPTaskDirective:
4193 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004194 case CXCursor_OMPTaskyieldDirective:
4195 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004196 case CXCursor_OMPBarrierDirective:
4197 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004198 case CXCursor_OMPTaskwaitDirective:
4199 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004200 case CXCursor_OMPFlushDirective:
4201 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004202 case CXCursor_OMPOrderedDirective:
4203 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004204 case CXCursor_OMPAtomicDirective:
4205 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004206 case CXCursor_OMPTargetDirective:
4207 return cxstring::createRef("OMPTargetDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004208 case CXCursor_OMPTeamsDirective:
4209 return cxstring::createRef("OMPTeamsDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 }
4211
4212 llvm_unreachable("Unhandled CXCursorKind");
4213}
4214
4215struct GetCursorData {
4216 SourceLocation TokenBeginLoc;
4217 bool PointsAtMacroArgExpansion;
4218 bool VisitedObjCPropertyImplDecl;
4219 SourceLocation VisitedDeclaratorDeclStartLoc;
4220 CXCursor &BestCursor;
4221
4222 GetCursorData(SourceManager &SM,
4223 SourceLocation tokenBegin, CXCursor &outputCursor)
4224 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4225 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4226 VisitedObjCPropertyImplDecl = false;
4227 }
4228};
4229
4230static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4231 CXCursor parent,
4232 CXClientData client_data) {
4233 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4234 CXCursor *BestCursor = &Data->BestCursor;
4235
4236 // If we point inside a macro argument we should provide info of what the
4237 // token is so use the actual cursor, don't replace it with a macro expansion
4238 // cursor.
4239 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4240 return CXChildVisit_Recurse;
4241
4242 if (clang_isDeclaration(cursor.kind)) {
4243 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004244 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4246 if (MD->isImplicit())
4247 return CXChildVisit_Break;
4248
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004249 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4251 // Check that when we have multiple @class references in the same line,
4252 // that later ones do not override the previous ones.
4253 // If we have:
4254 // @class Foo, Bar;
4255 // source ranges for both start at '@', so 'Bar' will end up overriding
4256 // 'Foo' even though the cursor location was at 'Foo'.
4257 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4258 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004259 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4261 if (PrevID != ID &&
4262 !PrevID->isThisDeclarationADefinition() &&
4263 !ID->isThisDeclarationADefinition())
4264 return CXChildVisit_Break;
4265 }
4266
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004267 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4269 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4270 // Check that when we have multiple declarators in the same line,
4271 // that later ones do not override the previous ones.
4272 // If we have:
4273 // int Foo, Bar;
4274 // source ranges for both start at 'int', so 'Bar' will end up overriding
4275 // 'Foo' even though the cursor location was at 'Foo'.
4276 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4277 return CXChildVisit_Break;
4278 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4279
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004280 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4282 (void)PropImp;
4283 // Check that when we have multiple @synthesize in the same line,
4284 // that later ones do not override the previous ones.
4285 // If we have:
4286 // @synthesize Foo, Bar;
4287 // source ranges for both start at '@', so 'Bar' will end up overriding
4288 // 'Foo' even though the cursor location was at 'Foo'.
4289 if (Data->VisitedObjCPropertyImplDecl)
4290 return CXChildVisit_Break;
4291 Data->VisitedObjCPropertyImplDecl = true;
4292 }
4293 }
4294
4295 if (clang_isExpression(cursor.kind) &&
4296 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004297 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 // Avoid having the cursor of an expression replace the declaration cursor
4299 // when the expression source range overlaps the declaration range.
4300 // This can happen for C++ constructor expressions whose range generally
4301 // include the variable declaration, e.g.:
4302 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4303 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4304 D->getLocation() == Data->TokenBeginLoc)
4305 return CXChildVisit_Break;
4306 }
4307 }
4308
4309 // If our current best cursor is the construction of a temporary object,
4310 // don't replace that cursor with a type reference, because we want
4311 // clang_getCursor() to point at the constructor.
4312 if (clang_isExpression(BestCursor->kind) &&
4313 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4314 cursor.kind == CXCursor_TypeRef) {
4315 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4316 // as having the actual point on the type reference.
4317 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4318 return CXChildVisit_Recurse;
4319 }
4320
4321 *BestCursor = cursor;
4322 return CXChildVisit_Recurse;
4323}
4324
4325CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004326 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004327 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004328 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004329 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004330
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004331 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4333
4334 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4335 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4336
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004337 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004338 CXFile SearchFile;
4339 unsigned SearchLine, SearchColumn;
4340 CXFile ResultFile;
4341 unsigned ResultLine, ResultColumn;
4342 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4343 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4344 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004345
4346 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4347 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004348 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004349 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004350 SearchFileName = clang_getFileName(SearchFile);
4351 ResultFileName = clang_getFileName(ResultFile);
4352 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4353 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004354 *Log << llvm::format("(%s:%d:%d) = %s",
4355 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4356 clang_getCString(KindSpelling))
4357 << llvm::format("(%s:%d:%d):%s%s",
4358 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4359 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004360 clang_disposeString(SearchFileName);
4361 clang_disposeString(ResultFileName);
4362 clang_disposeString(KindSpelling);
4363 clang_disposeString(USR);
4364
4365 CXCursor Definition = clang_getCursorDefinition(Result);
4366 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4367 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4368 CXString DefinitionKindSpelling
4369 = clang_getCursorKindSpelling(Definition.kind);
4370 CXFile DefinitionFile;
4371 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004372 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004373 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004374 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004375 *Log << llvm::format(" -> %s(%s:%d:%d)",
4376 clang_getCString(DefinitionKindSpelling),
4377 clang_getCString(DefinitionFileName),
4378 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004379 clang_disposeString(DefinitionFileName);
4380 clang_disposeString(DefinitionKindSpelling);
4381 }
4382 }
4383
4384 return Result;
4385}
4386
4387CXCursor clang_getNullCursor(void) {
4388 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4389}
4390
4391unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004392 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4393 // can't set consistently. For example, when visiting a DeclStmt we will set
4394 // it but we don't set it on the result of clang_getCursorDefinition for
4395 // a reference of the same declaration.
4396 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4397 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4398 // to provide that kind of info.
4399 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004400 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004401 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004402 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004403
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 return X == Y;
4405}
4406
4407unsigned clang_hashCursor(CXCursor C) {
4408 unsigned Index = 0;
4409 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4410 Index = 1;
4411
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004412 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 std::make_pair(C.kind, C.data[Index]));
4414}
4415
4416unsigned clang_isInvalid(enum CXCursorKind K) {
4417 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4418}
4419
4420unsigned clang_isDeclaration(enum CXCursorKind K) {
4421 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4422 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4423}
4424
4425unsigned clang_isReference(enum CXCursorKind K) {
4426 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4427}
4428
4429unsigned clang_isExpression(enum CXCursorKind K) {
4430 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4431}
4432
4433unsigned clang_isStatement(enum CXCursorKind K) {
4434 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4435}
4436
4437unsigned clang_isAttribute(enum CXCursorKind K) {
4438 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4439}
4440
4441unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4442 return K == CXCursor_TranslationUnit;
4443}
4444
4445unsigned clang_isPreprocessing(enum CXCursorKind K) {
4446 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4447}
4448
4449unsigned clang_isUnexposed(enum CXCursorKind K) {
4450 switch (K) {
4451 case CXCursor_UnexposedDecl:
4452 case CXCursor_UnexposedExpr:
4453 case CXCursor_UnexposedStmt:
4454 case CXCursor_UnexposedAttr:
4455 return true;
4456 default:
4457 return false;
4458 }
4459}
4460
4461CXCursorKind clang_getCursorKind(CXCursor C) {
4462 return C.kind;
4463}
4464
4465CXSourceLocation clang_getCursorLocation(CXCursor C) {
4466 if (clang_isReference(C.kind)) {
4467 switch (C.kind) {
4468 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004469 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 = getCursorObjCSuperClassRef(C);
4471 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4472 }
4473
4474 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004475 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 = getCursorObjCProtocolRef(C);
4477 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4478 }
4479
4480 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004481 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 = getCursorObjCClassRef(C);
4483 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4484 }
4485
4486 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004487 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4489 }
4490
4491 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004492 std::pair<const TemplateDecl *, SourceLocation> P =
4493 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4495 }
4496
4497 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004498 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4500 }
4501
4502 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004503 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4505 }
4506
4507 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004508 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4510 }
4511
4512 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004513 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 if (!BaseSpec)
4515 return clang_getNullLocation();
4516
4517 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4518 return cxloc::translateSourceLocation(getCursorContext(C),
4519 TSInfo->getTypeLoc().getBeginLoc());
4520
4521 return cxloc::translateSourceLocation(getCursorContext(C),
4522 BaseSpec->getLocStart());
4523 }
4524
4525 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004526 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4528 }
4529
4530 case CXCursor_OverloadedDeclRef:
4531 return cxloc::translateSourceLocation(getCursorContext(C),
4532 getCursorOverloadedDeclRef(C).second);
4533
4534 default:
4535 // FIXME: Need a way to enumerate all non-reference cases.
4536 llvm_unreachable("Missed a reference kind");
4537 }
4538 }
4539
4540 if (clang_isExpression(C.kind))
4541 return cxloc::translateSourceLocation(getCursorContext(C),
4542 getLocationFromExpr(getCursorExpr(C)));
4543
4544 if (clang_isStatement(C.kind))
4545 return cxloc::translateSourceLocation(getCursorContext(C),
4546 getCursorStmt(C)->getLocStart());
4547
4548 if (C.kind == CXCursor_PreprocessingDirective) {
4549 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4550 return cxloc::translateSourceLocation(getCursorContext(C), L);
4551 }
4552
4553 if (C.kind == CXCursor_MacroExpansion) {
4554 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004555 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 return cxloc::translateSourceLocation(getCursorContext(C), L);
4557 }
4558
4559 if (C.kind == CXCursor_MacroDefinition) {
4560 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4561 return cxloc::translateSourceLocation(getCursorContext(C), L);
4562 }
4563
4564 if (C.kind == CXCursor_InclusionDirective) {
4565 SourceLocation L
4566 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4567 return cxloc::translateSourceLocation(getCursorContext(C), L);
4568 }
4569
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004570 if (clang_isAttribute(C.kind)) {
4571 SourceLocation L
4572 = cxcursor::getCursorAttr(C)->getLocation();
4573 return cxloc::translateSourceLocation(getCursorContext(C), L);
4574 }
4575
Guy Benyei11169dd2012-12-18 14:30:41 +00004576 if (!clang_isDeclaration(C.kind))
4577 return clang_getNullLocation();
4578
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004579 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 if (!D)
4581 return clang_getNullLocation();
4582
4583 SourceLocation Loc = D->getLocation();
4584 // FIXME: Multiple variables declared in a single declaration
4585 // currently lack the information needed to correctly determine their
4586 // ranges when accounting for the type-specifier. We use context
4587 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4588 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004589 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 if (!cxcursor::isFirstInDeclGroup(C))
4591 Loc = VD->getLocation();
4592 }
4593
4594 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004595 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004596 Loc = MD->getSelectorStartLoc();
4597
4598 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4599}
4600
4601} // end extern "C"
4602
4603CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4604 assert(TU);
4605
4606 // Guard against an invalid SourceLocation, or we may assert in one
4607 // of the following calls.
4608 if (SLoc.isInvalid())
4609 return clang_getNullCursor();
4610
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004611 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004612
4613 // Translate the given source location to make it point at the beginning of
4614 // the token under the cursor.
4615 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4616 CXXUnit->getASTContext().getLangOpts());
4617
4618 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4619 if (SLoc.isValid()) {
4620 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4621 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4622 /*VisitPreprocessorLast=*/true,
4623 /*VisitIncludedEntities=*/false,
4624 SourceLocation(SLoc));
4625 CursorVis.visitFileRegion();
4626 }
4627
4628 return Result;
4629}
4630
4631static SourceRange getRawCursorExtent(CXCursor C) {
4632 if (clang_isReference(C.kind)) {
4633 switch (C.kind) {
4634 case CXCursor_ObjCSuperClassRef:
4635 return getCursorObjCSuperClassRef(C).second;
4636
4637 case CXCursor_ObjCProtocolRef:
4638 return getCursorObjCProtocolRef(C).second;
4639
4640 case CXCursor_ObjCClassRef:
4641 return getCursorObjCClassRef(C).second;
4642
4643 case CXCursor_TypeRef:
4644 return getCursorTypeRef(C).second;
4645
4646 case CXCursor_TemplateRef:
4647 return getCursorTemplateRef(C).second;
4648
4649 case CXCursor_NamespaceRef:
4650 return getCursorNamespaceRef(C).second;
4651
4652 case CXCursor_MemberRef:
4653 return getCursorMemberRef(C).second;
4654
4655 case CXCursor_CXXBaseSpecifier:
4656 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4657
4658 case CXCursor_LabelRef:
4659 return getCursorLabelRef(C).second;
4660
4661 case CXCursor_OverloadedDeclRef:
4662 return getCursorOverloadedDeclRef(C).second;
4663
4664 case CXCursor_VariableRef:
4665 return getCursorVariableRef(C).second;
4666
4667 default:
4668 // FIXME: Need a way to enumerate all non-reference cases.
4669 llvm_unreachable("Missed a reference kind");
4670 }
4671 }
4672
4673 if (clang_isExpression(C.kind))
4674 return getCursorExpr(C)->getSourceRange();
4675
4676 if (clang_isStatement(C.kind))
4677 return getCursorStmt(C)->getSourceRange();
4678
4679 if (clang_isAttribute(C.kind))
4680 return getCursorAttr(C)->getRange();
4681
4682 if (C.kind == CXCursor_PreprocessingDirective)
4683 return cxcursor::getCursorPreprocessingDirective(C);
4684
4685 if (C.kind == CXCursor_MacroExpansion) {
4686 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004687 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 return TU->mapRangeFromPreamble(Range);
4689 }
4690
4691 if (C.kind == CXCursor_MacroDefinition) {
4692 ASTUnit *TU = getCursorASTUnit(C);
4693 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4694 return TU->mapRangeFromPreamble(Range);
4695 }
4696
4697 if (C.kind == CXCursor_InclusionDirective) {
4698 ASTUnit *TU = getCursorASTUnit(C);
4699 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4700 return TU->mapRangeFromPreamble(Range);
4701 }
4702
4703 if (C.kind == CXCursor_TranslationUnit) {
4704 ASTUnit *TU = getCursorASTUnit(C);
4705 FileID MainID = TU->getSourceManager().getMainFileID();
4706 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4707 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4708 return SourceRange(Start, End);
4709 }
4710
4711 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004712 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 if (!D)
4714 return SourceRange();
4715
4716 SourceRange R = D->getSourceRange();
4717 // FIXME: Multiple variables declared in a single declaration
4718 // currently lack the information needed to correctly determine their
4719 // ranges when accounting for the type-specifier. We use context
4720 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4721 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004722 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 if (!cxcursor::isFirstInDeclGroup(C))
4724 R.setBegin(VD->getLocation());
4725 }
4726 return R;
4727 }
4728 return SourceRange();
4729}
4730
4731/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4732/// the decl-specifier-seq for declarations.
4733static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4734 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004735 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 if (!D)
4737 return SourceRange();
4738
4739 SourceRange R = D->getSourceRange();
4740
4741 // Adjust the start of the location for declarations preceded by
4742 // declaration specifiers.
4743 SourceLocation StartLoc;
4744 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4745 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4746 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004747 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4749 StartLoc = TI->getTypeLoc().getLocStart();
4750 }
4751
4752 if (StartLoc.isValid() && R.getBegin().isValid() &&
4753 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4754 R.setBegin(StartLoc);
4755
4756 // FIXME: Multiple variables declared in a single declaration
4757 // currently lack the information needed to correctly determine their
4758 // ranges when accounting for the type-specifier. We use context
4759 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4760 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004761 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004762 if (!cxcursor::isFirstInDeclGroup(C))
4763 R.setBegin(VD->getLocation());
4764 }
4765
4766 return R;
4767 }
4768
4769 return getRawCursorExtent(C);
4770}
4771
4772extern "C" {
4773
4774CXSourceRange clang_getCursorExtent(CXCursor C) {
4775 SourceRange R = getRawCursorExtent(C);
4776 if (R.isInvalid())
4777 return clang_getNullRange();
4778
4779 return cxloc::translateSourceRange(getCursorContext(C), R);
4780}
4781
4782CXCursor clang_getCursorReferenced(CXCursor C) {
4783 if (clang_isInvalid(C.kind))
4784 return clang_getNullCursor();
4785
4786 CXTranslationUnit tu = getCursorTU(C);
4787 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004788 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 if (!D)
4790 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004791 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004792 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004793 if (const ObjCPropertyImplDecl *PropImpl =
4794 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004795 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4796 return MakeCXCursor(Property, tu);
4797
4798 return C;
4799 }
4800
4801 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004802 const Expr *E = getCursorExpr(C);
4803 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004804 if (D) {
4805 CXCursor declCursor = MakeCXCursor(D, tu);
4806 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4807 declCursor);
4808 return declCursor;
4809 }
4810
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004811 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004812 return MakeCursorOverloadedDeclRef(Ovl, tu);
4813
4814 return clang_getNullCursor();
4815 }
4816
4817 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004818 const Stmt *S = getCursorStmt(C);
4819 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004820 if (LabelDecl *label = Goto->getLabel())
4821 if (LabelStmt *labelS = label->getStmt())
4822 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4823
4824 return clang_getNullCursor();
4825 }
4826
4827 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004828 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004829 return MakeMacroDefinitionCursor(Def, tu);
4830 }
4831
4832 if (!clang_isReference(C.kind))
4833 return clang_getNullCursor();
4834
4835 switch (C.kind) {
4836 case CXCursor_ObjCSuperClassRef:
4837 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4838
4839 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004840 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4841 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004842 return MakeCXCursor(Def, tu);
4843
4844 return MakeCXCursor(Prot, tu);
4845 }
4846
4847 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004848 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4849 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004850 return MakeCXCursor(Def, tu);
4851
4852 return MakeCXCursor(Class, tu);
4853 }
4854
4855 case CXCursor_TypeRef:
4856 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4857
4858 case CXCursor_TemplateRef:
4859 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4860
4861 case CXCursor_NamespaceRef:
4862 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4863
4864 case CXCursor_MemberRef:
4865 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4866
4867 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004868 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4870 tu ));
4871 }
4872
4873 case CXCursor_LabelRef:
4874 // FIXME: We end up faking the "parent" declaration here because we
4875 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004876 return MakeCXCursor(getCursorLabelRef(C).first,
4877 cxtu::getASTUnit(tu)->getASTContext()
4878 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004879 tu);
4880
4881 case CXCursor_OverloadedDeclRef:
4882 return C;
4883
4884 case CXCursor_VariableRef:
4885 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4886
4887 default:
4888 // We would prefer to enumerate all non-reference cursor kinds here.
4889 llvm_unreachable("Unhandled reference cursor kind");
4890 }
4891}
4892
4893CXCursor clang_getCursorDefinition(CXCursor C) {
4894 if (clang_isInvalid(C.kind))
4895 return clang_getNullCursor();
4896
4897 CXTranslationUnit TU = getCursorTU(C);
4898
4899 bool WasReference = false;
4900 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4901 C = clang_getCursorReferenced(C);
4902 WasReference = true;
4903 }
4904
4905 if (C.kind == CXCursor_MacroExpansion)
4906 return clang_getCursorReferenced(C);
4907
4908 if (!clang_isDeclaration(C.kind))
4909 return clang_getNullCursor();
4910
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004911 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004912 if (!D)
4913 return clang_getNullCursor();
4914
4915 switch (D->getKind()) {
4916 // Declaration kinds that don't really separate the notions of
4917 // declaration and definition.
4918 case Decl::Namespace:
4919 case Decl::Typedef:
4920 case Decl::TypeAlias:
4921 case Decl::TypeAliasTemplate:
4922 case Decl::TemplateTypeParm:
4923 case Decl::EnumConstant:
4924 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004925 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004926 case Decl::IndirectField:
4927 case Decl::ObjCIvar:
4928 case Decl::ObjCAtDefsField:
4929 case Decl::ImplicitParam:
4930 case Decl::ParmVar:
4931 case Decl::NonTypeTemplateParm:
4932 case Decl::TemplateTemplateParm:
4933 case Decl::ObjCCategoryImpl:
4934 case Decl::ObjCImplementation:
4935 case Decl::AccessSpec:
4936 case Decl::LinkageSpec:
4937 case Decl::ObjCPropertyImpl:
4938 case Decl::FileScopeAsm:
4939 case Decl::StaticAssert:
4940 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004941 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004942 case Decl::Label: // FIXME: Is this right??
4943 case Decl::ClassScopeFunctionSpecialization:
4944 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004945 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004946 return C;
4947
4948 // Declaration kinds that don't make any sense here, but are
4949 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004950 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004951 case Decl::TranslationUnit:
4952 break;
4953
4954 // Declaration kinds for which the definition is not resolvable.
4955 case Decl::UnresolvedUsingTypename:
4956 case Decl::UnresolvedUsingValue:
4957 break;
4958
4959 case Decl::UsingDirective:
4960 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4961 TU);
4962
4963 case Decl::NamespaceAlias:
4964 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4965
4966 case Decl::Enum:
4967 case Decl::Record:
4968 case Decl::CXXRecord:
4969 case Decl::ClassTemplateSpecialization:
4970 case Decl::ClassTemplatePartialSpecialization:
4971 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4972 return MakeCXCursor(Def, TU);
4973 return clang_getNullCursor();
4974
4975 case Decl::Function:
4976 case Decl::CXXMethod:
4977 case Decl::CXXConstructor:
4978 case Decl::CXXDestructor:
4979 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004980 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004981 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004982 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 return clang_getNullCursor();
4984 }
4985
Larisse Voufo39a1e502013-08-06 01:03:05 +00004986 case Decl::Var:
4987 case Decl::VarTemplateSpecialization:
4988 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004989 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004990 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 return MakeCXCursor(Def, TU);
4992 return clang_getNullCursor();
4993 }
4994
4995 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004996 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004997 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4998 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4999 return clang_getNullCursor();
5000 }
5001
5002 case Decl::ClassTemplate: {
5003 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5004 ->getDefinition())
5005 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5006 TU);
5007 return clang_getNullCursor();
5008 }
5009
Larisse Voufo39a1e502013-08-06 01:03:05 +00005010 case Decl::VarTemplate: {
5011 if (VarDecl *Def =
5012 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5013 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5014 return clang_getNullCursor();
5015 }
5016
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 case Decl::Using:
5018 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5019 D->getLocation(), TU);
5020
5021 case Decl::UsingShadow:
5022 return clang_getCursorDefinition(
5023 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5024 TU));
5025
5026 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005027 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 if (Method->isThisDeclarationADefinition())
5029 return C;
5030
5031 // Dig out the method definition in the associated
5032 // @implementation, if we have it.
5033 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005034 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005035 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5036 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5037 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5038 Method->isInstanceMethod()))
5039 if (Def->isThisDeclarationADefinition())
5040 return MakeCXCursor(Def, TU);
5041
5042 return clang_getNullCursor();
5043 }
5044
5045 case Decl::ObjCCategory:
5046 if (ObjCCategoryImplDecl *Impl
5047 = cast<ObjCCategoryDecl>(D)->getImplementation())
5048 return MakeCXCursor(Impl, TU);
5049 return clang_getNullCursor();
5050
5051 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005052 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 return MakeCXCursor(Def, TU);
5054 return clang_getNullCursor();
5055
5056 case Decl::ObjCInterface: {
5057 // There are two notions of a "definition" for an Objective-C
5058 // class: the interface and its implementation. When we resolved a
5059 // reference to an Objective-C class, produce the @interface as
5060 // the definition; when we were provided with the interface,
5061 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005062 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005063 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005064 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005065 return MakeCXCursor(Def, TU);
5066 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5067 return MakeCXCursor(Impl, TU);
5068 return clang_getNullCursor();
5069 }
5070
5071 case Decl::ObjCProperty:
5072 // FIXME: We don't really know where to find the
5073 // ObjCPropertyImplDecls that implement this property.
5074 return clang_getNullCursor();
5075
5076 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005077 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005078 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005079 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005080 return MakeCXCursor(Def, TU);
5081
5082 return clang_getNullCursor();
5083
5084 case Decl::Friend:
5085 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5086 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5087 return clang_getNullCursor();
5088
5089 case Decl::FriendTemplate:
5090 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5091 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5092 return clang_getNullCursor();
5093 }
5094
5095 return clang_getNullCursor();
5096}
5097
5098unsigned clang_isCursorDefinition(CXCursor C) {
5099 if (!clang_isDeclaration(C.kind))
5100 return 0;
5101
5102 return clang_getCursorDefinition(C) == C;
5103}
5104
5105CXCursor clang_getCanonicalCursor(CXCursor C) {
5106 if (!clang_isDeclaration(C.kind))
5107 return C;
5108
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005109 if (const Decl *D = getCursorDecl(C)) {
5110 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005111 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5112 return MakeCXCursor(CatD, getCursorTU(C));
5113
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005114 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5115 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 return MakeCXCursor(IFD, getCursorTU(C));
5117
5118 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5119 }
5120
5121 return C;
5122}
5123
5124int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5125 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5126}
5127
5128unsigned clang_getNumOverloadedDecls(CXCursor C) {
5129 if (C.kind != CXCursor_OverloadedDeclRef)
5130 return 0;
5131
5132 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005133 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 return E->getNumDecls();
5135
5136 if (OverloadedTemplateStorage *S
5137 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5138 return S->size();
5139
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005140 const Decl *D = Storage.get<const Decl *>();
5141 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 return Using->shadow_size();
5143
5144 return 0;
5145}
5146
5147CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5148 if (cursor.kind != CXCursor_OverloadedDeclRef)
5149 return clang_getNullCursor();
5150
5151 if (index >= clang_getNumOverloadedDecls(cursor))
5152 return clang_getNullCursor();
5153
5154 CXTranslationUnit TU = getCursorTU(cursor);
5155 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005156 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005157 return MakeCXCursor(E->decls_begin()[index], TU);
5158
5159 if (OverloadedTemplateStorage *S
5160 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5161 return MakeCXCursor(S->begin()[index], TU);
5162
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005163 const Decl *D = Storage.get<const Decl *>();
5164 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005165 // FIXME: This is, unfortunately, linear time.
5166 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5167 std::advance(Pos, index);
5168 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5169 }
5170
5171 return clang_getNullCursor();
5172}
5173
5174void clang_getDefinitionSpellingAndExtent(CXCursor C,
5175 const char **startBuf,
5176 const char **endBuf,
5177 unsigned *startLine,
5178 unsigned *startColumn,
5179 unsigned *endLine,
5180 unsigned *endColumn) {
5181 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005182 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005183 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5184
5185 SourceManager &SM = FD->getASTContext().getSourceManager();
5186 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5187 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5188 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5189 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5190 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5191 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5192}
5193
5194
5195CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5196 unsigned PieceIndex) {
5197 RefNamePieces Pieces;
5198
5199 switch (C.kind) {
5200 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005201 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5203 E->getQualifierLoc().getSourceRange());
5204 break;
5205
5206 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005207 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5209 E->getQualifierLoc().getSourceRange(),
5210 E->getOptionalExplicitTemplateArgs());
5211 break;
5212
5213 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005214 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005216 const Expr *Callee = OCE->getCallee();
5217 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 Callee = ICE->getSubExpr();
5219
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005220 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5222 DRE->getQualifierLoc().getSourceRange());
5223 }
5224 break;
5225
5226 default:
5227 break;
5228 }
5229
5230 if (Pieces.empty()) {
5231 if (PieceIndex == 0)
5232 return clang_getCursorExtent(C);
5233 } else if (PieceIndex < Pieces.size()) {
5234 SourceRange R = Pieces[PieceIndex];
5235 if (R.isValid())
5236 return cxloc::translateSourceRange(getCursorContext(C), R);
5237 }
5238
5239 return clang_getNullRange();
5240}
5241
5242void clang_enableStackTraces(void) {
5243 llvm::sys::PrintStackTraceOnErrorSignal();
5244}
5245
5246void clang_executeOnThread(void (*fn)(void*), void *user_data,
5247 unsigned stack_size) {
5248 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5249}
5250
5251} // end: extern "C"
5252
5253//===----------------------------------------------------------------------===//
5254// Token-based Operations.
5255//===----------------------------------------------------------------------===//
5256
5257/* CXToken layout:
5258 * int_data[0]: a CXTokenKind
5259 * int_data[1]: starting token location
5260 * int_data[2]: token length
5261 * int_data[3]: reserved
5262 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5263 * otherwise unused.
5264 */
5265extern "C" {
5266
5267CXTokenKind clang_getTokenKind(CXToken CXTok) {
5268 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5269}
5270
5271CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5272 switch (clang_getTokenKind(CXTok)) {
5273 case CXToken_Identifier:
5274 case CXToken_Keyword:
5275 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005276 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 ->getNameStart());
5278
5279 case CXToken_Literal: {
5280 // We have stashed the starting pointer in the ptr_data field. Use it.
5281 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005282 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005283 }
5284
5285 case CXToken_Punctuation:
5286 case CXToken_Comment:
5287 break;
5288 }
5289
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005290 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005291 LOG_BAD_TU(TU);
5292 return cxstring::createEmpty();
5293 }
5294
Guy Benyei11169dd2012-12-18 14:30:41 +00005295 // We have to find the starting buffer pointer the hard way, by
5296 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005297 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005299 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005300
5301 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5302 std::pair<FileID, unsigned> LocInfo
5303 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5304 bool Invalid = false;
5305 StringRef Buffer
5306 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5307 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005308 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005309
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005310 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005311}
5312
5313CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005314 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005315 LOG_BAD_TU(TU);
5316 return clang_getNullLocation();
5317 }
5318
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005319 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 if (!CXXUnit)
5321 return clang_getNullLocation();
5322
5323 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5324 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5325}
5326
5327CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005328 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005329 LOG_BAD_TU(TU);
5330 return clang_getNullRange();
5331 }
5332
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005333 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 if (!CXXUnit)
5335 return clang_getNullRange();
5336
5337 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5338 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5339}
5340
5341static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5342 SmallVectorImpl<CXToken> &CXTokens) {
5343 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5344 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005345 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005347 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005348
5349 // Cannot tokenize across files.
5350 if (BeginLocInfo.first != EndLocInfo.first)
5351 return;
5352
5353 // Create a lexer
5354 bool Invalid = false;
5355 StringRef Buffer
5356 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5357 if (Invalid)
5358 return;
5359
5360 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5361 CXXUnit->getASTContext().getLangOpts(),
5362 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5363 Lex.SetCommentRetentionState(true);
5364
5365 // Lex tokens until we hit the end of the range.
5366 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5367 Token Tok;
5368 bool previousWasAt = false;
5369 do {
5370 // Lex the next token
5371 Lex.LexFromRawLexer(Tok);
5372 if (Tok.is(tok::eof))
5373 break;
5374
5375 // Initialize the CXToken.
5376 CXToken CXTok;
5377
5378 // - Common fields
5379 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5380 CXTok.int_data[2] = Tok.getLength();
5381 CXTok.int_data[3] = 0;
5382
5383 // - Kind-specific fields
5384 if (Tok.isLiteral()) {
5385 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005386 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005387 } else if (Tok.is(tok::raw_identifier)) {
5388 // Lookup the identifier to determine whether we have a keyword.
5389 IdentifierInfo *II
5390 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5391
5392 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5393 CXTok.int_data[0] = CXToken_Keyword;
5394 }
5395 else {
5396 CXTok.int_data[0] = Tok.is(tok::identifier)
5397 ? CXToken_Identifier
5398 : CXToken_Keyword;
5399 }
5400 CXTok.ptr_data = II;
5401 } else if (Tok.is(tok::comment)) {
5402 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005403 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005404 } else {
5405 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005406 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005407 }
5408 CXTokens.push_back(CXTok);
5409 previousWasAt = Tok.is(tok::at);
5410 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5411}
5412
5413void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5414 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005415 LOG_FUNC_SECTION {
5416 *Log << TU << ' ' << Range;
5417 }
5418
Guy Benyei11169dd2012-12-18 14:30:41 +00005419 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005420 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005421 if (NumTokens)
5422 *NumTokens = 0;
5423
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005424 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005425 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005426 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005427 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005428
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005429 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005430 if (!CXXUnit || !Tokens || !NumTokens)
5431 return;
5432
5433 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5434
5435 SourceRange R = cxloc::translateCXSourceRange(Range);
5436 if (R.isInvalid())
5437 return;
5438
5439 SmallVector<CXToken, 32> CXTokens;
5440 getTokens(CXXUnit, R, CXTokens);
5441
5442 if (CXTokens.empty())
5443 return;
5444
5445 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5446 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5447 *NumTokens = CXTokens.size();
5448}
5449
5450void clang_disposeTokens(CXTranslationUnit TU,
5451 CXToken *Tokens, unsigned NumTokens) {
5452 free(Tokens);
5453}
5454
5455} // end: extern "C"
5456
5457//===----------------------------------------------------------------------===//
5458// Token annotation APIs.
5459//===----------------------------------------------------------------------===//
5460
Guy Benyei11169dd2012-12-18 14:30:41 +00005461static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5462 CXCursor parent,
5463 CXClientData client_data);
5464static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5465 CXClientData client_data);
5466
5467namespace {
5468class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 CXToken *Tokens;
5470 CXCursor *Cursors;
5471 unsigned NumTokens;
5472 unsigned TokIdx;
5473 unsigned PreprocessingTokIdx;
5474 CursorVisitor AnnotateVis;
5475 SourceManager &SrcMgr;
5476 bool HasContextSensitiveKeywords;
5477
5478 struct PostChildrenInfo {
5479 CXCursor Cursor;
5480 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005481 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 unsigned BeforeChildrenTokenIdx;
5483 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005484 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005485
5486 CXToken &getTok(unsigned Idx) {
5487 assert(Idx < NumTokens);
5488 return Tokens[Idx];
5489 }
5490 const CXToken &getTok(unsigned Idx) const {
5491 assert(Idx < NumTokens);
5492 return Tokens[Idx];
5493 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005494 bool MoreTokens() const { return TokIdx < NumTokens; }
5495 unsigned NextToken() const { return TokIdx; }
5496 void AdvanceToken() { ++TokIdx; }
5497 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005498 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005499 }
5500 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005501 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005502 }
5503 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005504 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005505 }
5506
5507 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005508 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005509 SourceRange);
5510
5511public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005512 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005513 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005514 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005516 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 AnnotateTokensVisitor, this,
5518 /*VisitPreprocessorLast=*/true,
5519 /*VisitIncludedEntities=*/false,
5520 RegionOfInterest,
5521 /*VisitDeclsOnly=*/false,
5522 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005523 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005524 HasContextSensitiveKeywords(false) { }
5525
5526 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5527 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5528 bool postVisitChildren(CXCursor cursor);
5529 void AnnotateTokens();
5530
5531 /// \brief Determine whether the annotator saw any cursors that have
5532 /// context-sensitive keywords.
5533 bool hasContextSensitiveKeywords() const {
5534 return HasContextSensitiveKeywords;
5535 }
5536
5537 ~AnnotateTokensWorker() {
5538 assert(PostChildrenInfos.empty());
5539 }
5540};
5541}
5542
5543void AnnotateTokensWorker::AnnotateTokens() {
5544 // Walk the AST within the region of interest, annotating tokens
5545 // along the way.
5546 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005547}
Guy Benyei11169dd2012-12-18 14:30:41 +00005548
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005549static inline void updateCursorAnnotation(CXCursor &Cursor,
5550 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005551 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005552 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005553 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005554}
5555
5556/// \brief It annotates and advances tokens with a cursor until the comparison
5557//// between the cursor location and the source range is the same as
5558/// \arg compResult.
5559///
5560/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5561/// Pass RangeOverlap to annotate tokens inside a range.
5562void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5563 RangeComparisonResult compResult,
5564 SourceRange range) {
5565 while (MoreTokens()) {
5566 const unsigned I = NextToken();
5567 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005568 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5569 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005570
5571 SourceLocation TokLoc = GetTokenLoc(I);
5572 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005573 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005574 AdvanceToken();
5575 continue;
5576 }
5577 break;
5578 }
5579}
5580
5581/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005582/// \returns true if it advanced beyond all macro tokens, false otherwise.
5583bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 CXCursor updateC,
5585 RangeComparisonResult compResult,
5586 SourceRange range) {
5587 assert(MoreTokens());
5588 assert(isFunctionMacroToken(NextToken()) &&
5589 "Should be called only for macro arg tokens");
5590
5591 // This works differently than annotateAndAdvanceTokens; because expanded
5592 // macro arguments can have arbitrary translation-unit source order, we do not
5593 // advance the token index one by one until a token fails the range test.
5594 // We only advance once past all of the macro arg tokens if all of them
5595 // pass the range test. If one of them fails we keep the token index pointing
5596 // at the start of the macro arg tokens so that the failing token will be
5597 // annotated by a subsequent annotation try.
5598
5599 bool atLeastOneCompFail = false;
5600
5601 unsigned I = NextToken();
5602 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5603 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5604 if (TokLoc.isFileID())
5605 continue; // not macro arg token, it's parens or comma.
5606 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5607 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5608 Cursors[I] = updateC;
5609 } else
5610 atLeastOneCompFail = true;
5611 }
5612
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005613 if (atLeastOneCompFail)
5614 return false;
5615
5616 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5617 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005618}
5619
5620enum CXChildVisitResult
5621AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005622 SourceRange cursorRange = getRawCursorExtent(cursor);
5623 if (cursorRange.isInvalid())
5624 return CXChildVisit_Recurse;
5625
5626 if (!HasContextSensitiveKeywords) {
5627 // Objective-C properties can have context-sensitive keywords.
5628 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005629 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5631 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5632 }
5633 // Objective-C methods can have context-sensitive keywords.
5634 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5635 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005636 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5638 if (Method->getObjCDeclQualifier())
5639 HasContextSensitiveKeywords = true;
5640 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005641 for (const auto *P : Method->params()) {
5642 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 HasContextSensitiveKeywords = true;
5644 break;
5645 }
5646 }
5647 }
5648 }
5649 }
5650 // C++ methods can have context-sensitive keywords.
5651 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005652 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5654 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5655 HasContextSensitiveKeywords = true;
5656 }
5657 }
5658 // C++ classes can have context-sensitive keywords.
5659 else if (cursor.kind == CXCursor_StructDecl ||
5660 cursor.kind == CXCursor_ClassDecl ||
5661 cursor.kind == CXCursor_ClassTemplate ||
5662 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005663 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005664 if (D->hasAttr<FinalAttr>())
5665 HasContextSensitiveKeywords = true;
5666 }
5667 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005668
5669 // Don't override a property annotation with its getter/setter method.
5670 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5671 parent.kind == CXCursor_ObjCPropertyDecl)
5672 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005673
5674 if (clang_isPreprocessing(cursor.kind)) {
5675 // Items in the preprocessing record are kept separate from items in
5676 // declarations, so we keep a separate token index.
5677 unsigned SavedTokIdx = TokIdx;
5678 TokIdx = PreprocessingTokIdx;
5679
5680 // Skip tokens up until we catch up to the beginning of the preprocessing
5681 // entry.
5682 while (MoreTokens()) {
5683 const unsigned I = NextToken();
5684 SourceLocation TokLoc = GetTokenLoc(I);
5685 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5686 case RangeBefore:
5687 AdvanceToken();
5688 continue;
5689 case RangeAfter:
5690 case RangeOverlap:
5691 break;
5692 }
5693 break;
5694 }
5695
5696 // Look at all of the tokens within this range.
5697 while (MoreTokens()) {
5698 const unsigned I = NextToken();
5699 SourceLocation TokLoc = GetTokenLoc(I);
5700 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5701 case RangeBefore:
5702 llvm_unreachable("Infeasible");
5703 case RangeAfter:
5704 break;
5705 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005706 // For macro expansions, just note where the beginning of the macro
5707 // expansion occurs.
5708 if (cursor.kind == CXCursor_MacroExpansion) {
5709 if (TokLoc == cursorRange.getBegin())
5710 Cursors[I] = cursor;
5711 AdvanceToken();
5712 break;
5713 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005714 // We may have already annotated macro names inside macro definitions.
5715 if (Cursors[I].kind != CXCursor_MacroExpansion)
5716 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005717 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005718 continue;
5719 }
5720 break;
5721 }
5722
5723 // Save the preprocessing token index; restore the non-preprocessing
5724 // token index.
5725 PreprocessingTokIdx = TokIdx;
5726 TokIdx = SavedTokIdx;
5727 return CXChildVisit_Recurse;
5728 }
5729
5730 if (cursorRange.isInvalid())
5731 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005732
5733 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005735 const enum CXCursorKind K = clang_getCursorKind(parent);
5736 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005737 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5738 // Attributes are annotated out-of-order, skip tokens until we reach it.
5739 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005740 ? clang_getNullCursor() : parent;
5741
5742 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5743
5744 // Avoid having the cursor of an expression "overwrite" the annotation of the
5745 // variable declaration that it belongs to.
5746 // This can happen for C++ constructor expressions whose range generally
5747 // include the variable declaration, e.g.:
5748 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005749 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005750 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005751 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 const unsigned I = NextToken();
5753 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5754 E->getLocStart() == D->getLocation() &&
5755 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005756 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005757 AdvanceToken();
5758 }
5759 }
5760 }
5761
5762 // Before recursing into the children keep some state that we are going
5763 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5764 // extra work after the child nodes are visited.
5765 // Note that we don't call VisitChildren here to avoid traversing statements
5766 // code-recursively which can blow the stack.
5767
5768 PostChildrenInfo Info;
5769 Info.Cursor = cursor;
5770 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005771 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005772 Info.BeforeChildrenTokenIdx = NextToken();
5773 PostChildrenInfos.push_back(Info);
5774
5775 return CXChildVisit_Recurse;
5776}
5777
5778bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5779 if (PostChildrenInfos.empty())
5780 return false;
5781 const PostChildrenInfo &Info = PostChildrenInfos.back();
5782 if (!clang_equalCursors(Info.Cursor, cursor))
5783 return false;
5784
5785 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5786 const unsigned AfterChildren = NextToken();
5787 SourceRange cursorRange = Info.CursorRange;
5788
5789 // Scan the tokens that are at the end of the cursor, but are not captured
5790 // but the child cursors.
5791 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5792
5793 // Scan the tokens that are at the beginning of the cursor, but are not
5794 // capture by the child cursors.
5795 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5796 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5797 break;
5798
5799 Cursors[I] = cursor;
5800 }
5801
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005802 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5803 // encountered the attribute cursor.
5804 if (clang_isAttribute(cursor.kind))
5805 TokIdx = Info.BeforeReachingCursorIdx;
5806
Guy Benyei11169dd2012-12-18 14:30:41 +00005807 PostChildrenInfos.pop_back();
5808 return false;
5809}
5810
5811static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5812 CXCursor parent,
5813 CXClientData client_data) {
5814 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5815}
5816
5817static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5818 CXClientData client_data) {
5819 return static_cast<AnnotateTokensWorker*>(client_data)->
5820 postVisitChildren(cursor);
5821}
5822
5823namespace {
5824
5825/// \brief Uses the macro expansions in the preprocessing record to find
5826/// and mark tokens that are macro arguments. This info is used by the
5827/// AnnotateTokensWorker.
5828class MarkMacroArgTokensVisitor {
5829 SourceManager &SM;
5830 CXToken *Tokens;
5831 unsigned NumTokens;
5832 unsigned CurIdx;
5833
5834public:
5835 MarkMacroArgTokensVisitor(SourceManager &SM,
5836 CXToken *tokens, unsigned numTokens)
5837 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5838
5839 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5840 if (cursor.kind != CXCursor_MacroExpansion)
5841 return CXChildVisit_Continue;
5842
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005843 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005844 if (macroRange.getBegin() == macroRange.getEnd())
5845 return CXChildVisit_Continue; // it's not a function macro.
5846
5847 for (; CurIdx < NumTokens; ++CurIdx) {
5848 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5849 macroRange.getBegin()))
5850 break;
5851 }
5852
5853 if (CurIdx == NumTokens)
5854 return CXChildVisit_Break;
5855
5856 for (; CurIdx < NumTokens; ++CurIdx) {
5857 SourceLocation tokLoc = getTokenLoc(CurIdx);
5858 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5859 break;
5860
5861 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5862 }
5863
5864 if (CurIdx == NumTokens)
5865 return CXChildVisit_Break;
5866
5867 return CXChildVisit_Continue;
5868 }
5869
5870private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005871 CXToken &getTok(unsigned Idx) {
5872 assert(Idx < NumTokens);
5873 return Tokens[Idx];
5874 }
5875 const CXToken &getTok(unsigned Idx) const {
5876 assert(Idx < NumTokens);
5877 return Tokens[Idx];
5878 }
5879
Guy Benyei11169dd2012-12-18 14:30:41 +00005880 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005881 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005882 }
5883
5884 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5885 // The third field is reserved and currently not used. Use it here
5886 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005887 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005888 }
5889};
5890
5891} // end anonymous namespace
5892
5893static CXChildVisitResult
5894MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5895 CXClientData client_data) {
5896 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5897 parent);
5898}
5899
5900namespace {
5901 struct clang_annotateTokens_Data {
5902 CXTranslationUnit TU;
5903 ASTUnit *CXXUnit;
5904 CXToken *Tokens;
5905 unsigned NumTokens;
5906 CXCursor *Cursors;
5907 };
5908}
5909
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005910/// \brief Used by \c annotatePreprocessorTokens.
5911/// \returns true if lexing was finished, false otherwise.
5912static bool lexNext(Lexer &Lex, Token &Tok,
5913 unsigned &NextIdx, unsigned NumTokens) {
5914 if (NextIdx >= NumTokens)
5915 return true;
5916
5917 ++NextIdx;
5918 Lex.LexFromRawLexer(Tok);
5919 if (Tok.is(tok::eof))
5920 return true;
5921
5922 return false;
5923}
5924
Guy Benyei11169dd2012-12-18 14:30:41 +00005925static void annotatePreprocessorTokens(CXTranslationUnit TU,
5926 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005927 CXCursor *Cursors,
5928 CXToken *Tokens,
5929 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005930 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005931
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005932 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005933 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5934 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005935 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005936 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005937 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005938
5939 if (BeginLocInfo.first != EndLocInfo.first)
5940 return;
5941
5942 StringRef Buffer;
5943 bool Invalid = false;
5944 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5945 if (Buffer.empty() || Invalid)
5946 return;
5947
5948 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5949 CXXUnit->getASTContext().getLangOpts(),
5950 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5951 Buffer.end());
5952 Lex.SetCommentRetentionState(true);
5953
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005954 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005955 // Lex tokens in raw mode until we hit the end of the range, to avoid
5956 // entering #includes or expanding macros.
5957 while (true) {
5958 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005959 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5960 break;
5961 unsigned TokIdx = NextIdx-1;
5962 assert(Tok.getLocation() ==
5963 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005964
5965 reprocess:
5966 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005967 // We have found a preprocessing directive. Annotate the tokens
5968 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005969 //
5970 // FIXME: Some simple tests here could identify macro definitions and
5971 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005972
5973 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005974 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5975 break;
5976
Craig Topper69186e72014-06-08 08:38:04 +00005977 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005978 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005979 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5980 break;
5981
5982 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005983 IdentifierInfo &II =
5984 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005985 SourceLocation MappedTokLoc =
5986 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5987 MI = getMacroInfo(II, MappedTokLoc, TU);
5988 }
5989 }
5990
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005991 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005992 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005993 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5994 finished = true;
5995 break;
5996 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005997 // If we are in a macro definition, check if the token was ever a
5998 // macro name and annotate it if that's the case.
5999 if (MI) {
6000 SourceLocation SaveLoc = Tok.getLocation();
6001 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6002 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
6003 Tok.setLocation(SaveLoc);
6004 if (MacroDef)
6005 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6006 Tok.getLocation(), TU);
6007 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006008 } while (!Tok.isAtStartOfLine());
6009
6010 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6011 assert(TokIdx <= LastIdx);
6012 SourceLocation EndLoc =
6013 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6014 CXCursor Cursor =
6015 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6016
6017 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006018 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006019
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006020 if (finished)
6021 break;
6022 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006023 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006024 }
6025}
6026
6027// This gets run a separate thread to avoid stack blowout.
6028static void clang_annotateTokensImpl(void *UserData) {
6029 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6030 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6031 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6032 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6033 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6034
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006035 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006036 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6037 setThreadBackgroundPriority();
6038
6039 // Determine the region of interest, which contains all of the tokens.
6040 SourceRange RegionOfInterest;
6041 RegionOfInterest.setBegin(
6042 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6043 RegionOfInterest.setEnd(
6044 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6045 Tokens[NumTokens-1])));
6046
Guy Benyei11169dd2012-12-18 14:30:41 +00006047 // Relex the tokens within the source range to look for preprocessing
6048 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006049 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006050
6051 // If begin location points inside a macro argument, set it to the expansion
6052 // location so we can have the full context when annotating semantically.
6053 {
6054 SourceManager &SM = CXXUnit->getSourceManager();
6055 SourceLocation Loc =
6056 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6057 if (Loc.isMacroID())
6058 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6059 }
6060
Guy Benyei11169dd2012-12-18 14:30:41 +00006061 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6062 // Search and mark tokens that are macro argument expansions.
6063 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6064 Tokens, NumTokens);
6065 CursorVisitor MacroArgMarker(TU,
6066 MarkMacroArgTokensVisitorDelegate, &Visitor,
6067 /*VisitPreprocessorLast=*/true,
6068 /*VisitIncludedEntities=*/false,
6069 RegionOfInterest);
6070 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6071 }
6072
6073 // Annotate all of the source locations in the region of interest that map to
6074 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006075 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006076
6077 // FIXME: We use a ridiculous stack size here because the data-recursion
6078 // algorithm uses a large stack frame than the non-data recursive version,
6079 // and AnnotationTokensWorker currently transforms the data-recursion
6080 // algorithm back into a traditional recursion by explicitly calling
6081 // VisitChildren(). We will need to remove this explicit recursive call.
6082 W.AnnotateTokens();
6083
6084 // If we ran into any entities that involve context-sensitive keywords,
6085 // take another pass through the tokens to mark them as such.
6086 if (W.hasContextSensitiveKeywords()) {
6087 for (unsigned I = 0; I != NumTokens; ++I) {
6088 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6089 continue;
6090
6091 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6092 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006093 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006094 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6095 if (Property->getPropertyAttributesAsWritten() != 0 &&
6096 llvm::StringSwitch<bool>(II->getName())
6097 .Case("readonly", true)
6098 .Case("assign", true)
6099 .Case("unsafe_unretained", true)
6100 .Case("readwrite", true)
6101 .Case("retain", true)
6102 .Case("copy", true)
6103 .Case("nonatomic", true)
6104 .Case("atomic", true)
6105 .Case("getter", true)
6106 .Case("setter", true)
6107 .Case("strong", true)
6108 .Case("weak", true)
6109 .Default(false))
6110 Tokens[I].int_data[0] = CXToken_Keyword;
6111 }
6112 continue;
6113 }
6114
6115 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6116 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6117 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6118 if (llvm::StringSwitch<bool>(II->getName())
6119 .Case("in", true)
6120 .Case("out", true)
6121 .Case("inout", true)
6122 .Case("oneway", true)
6123 .Case("bycopy", true)
6124 .Case("byref", true)
6125 .Default(false))
6126 Tokens[I].int_data[0] = CXToken_Keyword;
6127 continue;
6128 }
6129
6130 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6131 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6132 Tokens[I].int_data[0] = CXToken_Keyword;
6133 continue;
6134 }
6135 }
6136 }
6137}
6138
6139extern "C" {
6140
6141void clang_annotateTokens(CXTranslationUnit TU,
6142 CXToken *Tokens, unsigned NumTokens,
6143 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006144 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006145 LOG_BAD_TU(TU);
6146 return;
6147 }
6148 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006149 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006150 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006151 }
6152
6153 LOG_FUNC_SECTION {
6154 *Log << TU << ' ';
6155 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6156 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6157 *Log << clang_getRange(bloc, eloc);
6158 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006159
6160 // Any token we don't specifically annotate will have a NULL cursor.
6161 CXCursor C = clang_getNullCursor();
6162 for (unsigned I = 0; I != NumTokens; ++I)
6163 Cursors[I] = C;
6164
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006165 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006166 if (!CXXUnit)
6167 return;
6168
6169 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6170
6171 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6172 llvm::CrashRecoveryContext CRC;
6173 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6174 GetSafetyThreadStackSize() * 2)) {
6175 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6176 }
6177}
6178
6179} // end: extern "C"
6180
6181//===----------------------------------------------------------------------===//
6182// Operations for querying linkage of a cursor.
6183//===----------------------------------------------------------------------===//
6184
6185extern "C" {
6186CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6187 if (!clang_isDeclaration(cursor.kind))
6188 return CXLinkage_Invalid;
6189
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006190 const Decl *D = cxcursor::getCursorDecl(cursor);
6191 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006192 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006193 case NoLinkage:
6194 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006195 case InternalLinkage: return CXLinkage_Internal;
6196 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6197 case ExternalLinkage: return CXLinkage_External;
6198 };
6199
6200 return CXLinkage_Invalid;
6201}
6202} // end: extern "C"
6203
6204//===----------------------------------------------------------------------===//
6205// Operations for querying language of a cursor.
6206//===----------------------------------------------------------------------===//
6207
6208static CXLanguageKind getDeclLanguage(const Decl *D) {
6209 if (!D)
6210 return CXLanguage_C;
6211
6212 switch (D->getKind()) {
6213 default:
6214 break;
6215 case Decl::ImplicitParam:
6216 case Decl::ObjCAtDefsField:
6217 case Decl::ObjCCategory:
6218 case Decl::ObjCCategoryImpl:
6219 case Decl::ObjCCompatibleAlias:
6220 case Decl::ObjCImplementation:
6221 case Decl::ObjCInterface:
6222 case Decl::ObjCIvar:
6223 case Decl::ObjCMethod:
6224 case Decl::ObjCProperty:
6225 case Decl::ObjCPropertyImpl:
6226 case Decl::ObjCProtocol:
6227 return CXLanguage_ObjC;
6228 case Decl::CXXConstructor:
6229 case Decl::CXXConversion:
6230 case Decl::CXXDestructor:
6231 case Decl::CXXMethod:
6232 case Decl::CXXRecord:
6233 case Decl::ClassTemplate:
6234 case Decl::ClassTemplatePartialSpecialization:
6235 case Decl::ClassTemplateSpecialization:
6236 case Decl::Friend:
6237 case Decl::FriendTemplate:
6238 case Decl::FunctionTemplate:
6239 case Decl::LinkageSpec:
6240 case Decl::Namespace:
6241 case Decl::NamespaceAlias:
6242 case Decl::NonTypeTemplateParm:
6243 case Decl::StaticAssert:
6244 case Decl::TemplateTemplateParm:
6245 case Decl::TemplateTypeParm:
6246 case Decl::UnresolvedUsingTypename:
6247 case Decl::UnresolvedUsingValue:
6248 case Decl::Using:
6249 case Decl::UsingDirective:
6250 case Decl::UsingShadow:
6251 return CXLanguage_CPlusPlus;
6252 }
6253
6254 return CXLanguage_C;
6255}
6256
6257extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006258
6259static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6260 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6261 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006262
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006263 switch (D->getAvailability()) {
6264 case AR_Available:
6265 case AR_NotYetIntroduced:
6266 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006267 return getCursorAvailabilityForDecl(
6268 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006269 return CXAvailability_Available;
6270
6271 case AR_Deprecated:
6272 return CXAvailability_Deprecated;
6273
6274 case AR_Unavailable:
6275 return CXAvailability_NotAvailable;
6276 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006277
6278 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006279}
6280
Guy Benyei11169dd2012-12-18 14:30:41 +00006281enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6282 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006283 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6284 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006285
6286 return CXAvailability_Available;
6287}
6288
6289static CXVersion convertVersion(VersionTuple In) {
6290 CXVersion Out = { -1, -1, -1 };
6291 if (In.empty())
6292 return Out;
6293
6294 Out.Major = In.getMajor();
6295
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006296 Optional<unsigned> Minor = In.getMinor();
6297 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006298 Out.Minor = *Minor;
6299 else
6300 return Out;
6301
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006302 Optional<unsigned> Subminor = In.getSubminor();
6303 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006304 Out.Subminor = *Subminor;
6305
6306 return Out;
6307}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006308
6309static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6310 int *always_deprecated,
6311 CXString *deprecated_message,
6312 int *always_unavailable,
6313 CXString *unavailable_message,
6314 CXPlatformAvailability *availability,
6315 int availability_size) {
6316 bool HadAvailAttr = false;
6317 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006318 for (auto A : D->attrs()) {
6319 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006320 HadAvailAttr = true;
6321 if (always_deprecated)
6322 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006323 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006324 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006325 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006326 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006327 continue;
6328 }
6329
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006330 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006331 HadAvailAttr = true;
6332 if (always_unavailable)
6333 *always_unavailable = 1;
6334 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006335 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006336 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6337 }
6338 continue;
6339 }
6340
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006341 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006342 HadAvailAttr = true;
6343 if (N < availability_size) {
6344 availability[N].Platform
6345 = cxstring::createDup(Avail->getPlatform()->getName());
6346 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6347 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6348 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6349 availability[N].Unavailable = Avail->getUnavailable();
6350 availability[N].Message = cxstring::createDup(Avail->getMessage());
6351 }
6352 ++N;
6353 }
6354 }
6355
6356 if (!HadAvailAttr)
6357 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6358 return getCursorPlatformAvailabilityForDecl(
6359 cast<Decl>(EnumConst->getDeclContext()),
6360 always_deprecated,
6361 deprecated_message,
6362 always_unavailable,
6363 unavailable_message,
6364 availability,
6365 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006366
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006367 return N;
6368}
6369
Guy Benyei11169dd2012-12-18 14:30:41 +00006370int clang_getCursorPlatformAvailability(CXCursor cursor,
6371 int *always_deprecated,
6372 CXString *deprecated_message,
6373 int *always_unavailable,
6374 CXString *unavailable_message,
6375 CXPlatformAvailability *availability,
6376 int availability_size) {
6377 if (always_deprecated)
6378 *always_deprecated = 0;
6379 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006380 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006381 if (always_unavailable)
6382 *always_unavailable = 0;
6383 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006384 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006385
Guy Benyei11169dd2012-12-18 14:30:41 +00006386 if (!clang_isDeclaration(cursor.kind))
6387 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006388
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006389 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006390 if (!D)
6391 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006392
6393 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6394 deprecated_message,
6395 always_unavailable,
6396 unavailable_message,
6397 availability,
6398 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006399}
6400
6401void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6402 clang_disposeString(availability->Platform);
6403 clang_disposeString(availability->Message);
6404}
6405
6406CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6407 if (clang_isDeclaration(cursor.kind))
6408 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6409
6410 return CXLanguage_Invalid;
6411}
6412
6413 /// \brief If the given cursor is the "templated" declaration
6414 /// descibing a class or function template, return the class or
6415 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006416static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006417 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006418 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006419
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006420 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6422 return FunTmpl;
6423
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006424 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006425 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6426 return ClassTmpl;
6427
6428 return D;
6429}
6430
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006431
6432enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6433 StorageClass sc = SC_None;
6434 const Decl *D = getCursorDecl(C);
6435 if (D) {
6436 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6437 sc = FD->getStorageClass();
6438 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6439 sc = VD->getStorageClass();
6440 } else {
6441 return CX_SC_Invalid;
6442 }
6443 } else {
6444 return CX_SC_Invalid;
6445 }
6446 switch (sc) {
6447 case SC_None:
6448 return CX_SC_None;
6449 case SC_Extern:
6450 return CX_SC_Extern;
6451 case SC_Static:
6452 return CX_SC_Static;
6453 case SC_PrivateExtern:
6454 return CX_SC_PrivateExtern;
6455 case SC_OpenCLWorkGroupLocal:
6456 return CX_SC_OpenCLWorkGroupLocal;
6457 case SC_Auto:
6458 return CX_SC_Auto;
6459 case SC_Register:
6460 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006461 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006462 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006463}
6464
Guy Benyei11169dd2012-12-18 14:30:41 +00006465CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6466 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006467 if (const Decl *D = getCursorDecl(cursor)) {
6468 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006469 if (!DC)
6470 return clang_getNullCursor();
6471
6472 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6473 getCursorTU(cursor));
6474 }
6475 }
6476
6477 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006478 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006479 return MakeCXCursor(D, getCursorTU(cursor));
6480 }
6481
6482 return clang_getNullCursor();
6483}
6484
6485CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6486 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006487 if (const Decl *D = getCursorDecl(cursor)) {
6488 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006489 if (!DC)
6490 return clang_getNullCursor();
6491
6492 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6493 getCursorTU(cursor));
6494 }
6495 }
6496
6497 // FIXME: Note that we can't easily compute the lexical context of a
6498 // statement or expression, so we return nothing.
6499 return clang_getNullCursor();
6500}
6501
6502CXFile clang_getIncludedFile(CXCursor cursor) {
6503 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006504 return nullptr;
6505
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006506 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006507 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006508}
6509
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006510unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6511 if (C.kind != CXCursor_ObjCPropertyDecl)
6512 return CXObjCPropertyAttr_noattr;
6513
6514 unsigned Result = CXObjCPropertyAttr_noattr;
6515 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6516 ObjCPropertyDecl::PropertyAttributeKind Attr =
6517 PD->getPropertyAttributesAsWritten();
6518
6519#define SET_CXOBJCPROP_ATTR(A) \
6520 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6521 Result |= CXObjCPropertyAttr_##A
6522 SET_CXOBJCPROP_ATTR(readonly);
6523 SET_CXOBJCPROP_ATTR(getter);
6524 SET_CXOBJCPROP_ATTR(assign);
6525 SET_CXOBJCPROP_ATTR(readwrite);
6526 SET_CXOBJCPROP_ATTR(retain);
6527 SET_CXOBJCPROP_ATTR(copy);
6528 SET_CXOBJCPROP_ATTR(nonatomic);
6529 SET_CXOBJCPROP_ATTR(setter);
6530 SET_CXOBJCPROP_ATTR(atomic);
6531 SET_CXOBJCPROP_ATTR(weak);
6532 SET_CXOBJCPROP_ATTR(strong);
6533 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6534#undef SET_CXOBJCPROP_ATTR
6535
6536 return Result;
6537}
6538
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006539unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6540 if (!clang_isDeclaration(C.kind))
6541 return CXObjCDeclQualifier_None;
6542
6543 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6544 const Decl *D = getCursorDecl(C);
6545 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6546 QT = MD->getObjCDeclQualifier();
6547 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6548 QT = PD->getObjCDeclQualifier();
6549 if (QT == Decl::OBJC_TQ_None)
6550 return CXObjCDeclQualifier_None;
6551
6552 unsigned Result = CXObjCDeclQualifier_None;
6553 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6554 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6555 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6556 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6557 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6558 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6559
6560 return Result;
6561}
6562
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006563unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6564 if (!clang_isDeclaration(C.kind))
6565 return 0;
6566
6567 const Decl *D = getCursorDecl(C);
6568 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6569 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6570 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6571 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6572
6573 return 0;
6574}
6575
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006576unsigned clang_Cursor_isVariadic(CXCursor C) {
6577 if (!clang_isDeclaration(C.kind))
6578 return 0;
6579
6580 const Decl *D = getCursorDecl(C);
6581 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6582 return FD->isVariadic();
6583 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6584 return MD->isVariadic();
6585
6586 return 0;
6587}
6588
Guy Benyei11169dd2012-12-18 14:30:41 +00006589CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6590 if (!clang_isDeclaration(C.kind))
6591 return clang_getNullRange();
6592
6593 const Decl *D = getCursorDecl(C);
6594 ASTContext &Context = getCursorContext(C);
6595 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6596 if (!RC)
6597 return clang_getNullRange();
6598
6599 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6600}
6601
6602CXString clang_Cursor_getRawCommentText(CXCursor C) {
6603 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006604 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006605
6606 const Decl *D = getCursorDecl(C);
6607 ASTContext &Context = getCursorContext(C);
6608 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6609 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6610 StringRef();
6611
6612 // Don't duplicate the string because RawText points directly into source
6613 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006614 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006615}
6616
6617CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6618 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006619 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006620
6621 const Decl *D = getCursorDecl(C);
6622 const ASTContext &Context = getCursorContext(C);
6623 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6624
6625 if (RC) {
6626 StringRef BriefText = RC->getBriefText(Context);
6627
6628 // Don't duplicate the string because RawComment ensures that this memory
6629 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006630 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006631 }
6632
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006633 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006634}
6635
Guy Benyei11169dd2012-12-18 14:30:41 +00006636CXModule clang_Cursor_getModule(CXCursor C) {
6637 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006638 if (const ImportDecl *ImportD =
6639 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006640 return ImportD->getImportedModule();
6641 }
6642
Craig Topper69186e72014-06-08 08:38:04 +00006643 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006644}
6645
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006646CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6647 if (isNotUsableTU(TU)) {
6648 LOG_BAD_TU(TU);
6649 return nullptr;
6650 }
6651 if (!File)
6652 return nullptr;
6653 FileEntry *FE = static_cast<FileEntry *>(File);
6654
6655 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6656 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6657 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6658
Richard Smithfeb54b62014-10-23 02:01:19 +00006659 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006660}
6661
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006662CXFile clang_Module_getASTFile(CXModule CXMod) {
6663 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006664 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006665 Module *Mod = static_cast<Module*>(CXMod);
6666 return const_cast<FileEntry *>(Mod->getASTFile());
6667}
6668
Guy Benyei11169dd2012-12-18 14:30:41 +00006669CXModule clang_Module_getParent(CXModule CXMod) {
6670 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006671 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006672 Module *Mod = static_cast<Module*>(CXMod);
6673 return Mod->Parent;
6674}
6675
6676CXString clang_Module_getName(CXModule CXMod) {
6677 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006678 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006679 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006680 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006681}
6682
6683CXString clang_Module_getFullName(CXModule CXMod) {
6684 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006685 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006686 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006687 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006688}
6689
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006690int clang_Module_isSystem(CXModule CXMod) {
6691 if (!CXMod)
6692 return 0;
6693 Module *Mod = static_cast<Module*>(CXMod);
6694 return Mod->IsSystem;
6695}
6696
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006697unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6698 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006699 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006700 LOG_BAD_TU(TU);
6701 return 0;
6702 }
6703 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006704 return 0;
6705 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006706 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6707 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6708 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006709}
6710
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006711CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6712 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006713 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006714 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006715 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006716 }
6717 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006718 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006719 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006720 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006721
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006722 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6723 if (Index < TopHeaders.size())
6724 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006725
Craig Topper69186e72014-06-08 08:38:04 +00006726 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006727}
6728
6729} // end: extern "C"
6730
6731//===----------------------------------------------------------------------===//
6732// C++ AST instrospection.
6733//===----------------------------------------------------------------------===//
6734
6735extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006736unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6737 if (!clang_isDeclaration(C.kind))
6738 return 0;
6739
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006740 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006741 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006742 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006743 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6744}
6745
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006746unsigned clang_CXXMethod_isConst(CXCursor C) {
6747 if (!clang_isDeclaration(C.kind))
6748 return 0;
6749
6750 const Decl *D = cxcursor::getCursorDecl(C);
6751 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006752 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006753 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6754}
6755
Guy Benyei11169dd2012-12-18 14:30:41 +00006756unsigned clang_CXXMethod_isStatic(CXCursor C) {
6757 if (!clang_isDeclaration(C.kind))
6758 return 0;
6759
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006760 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006761 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006762 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006763 return (Method && Method->isStatic()) ? 1 : 0;
6764}
6765
6766unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6767 if (!clang_isDeclaration(C.kind))
6768 return 0;
6769
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006770 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006771 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006772 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006773 return (Method && Method->isVirtual()) ? 1 : 0;
6774}
6775} // end: extern "C"
6776
6777//===----------------------------------------------------------------------===//
6778// Attribute introspection.
6779//===----------------------------------------------------------------------===//
6780
6781extern "C" {
6782CXType clang_getIBOutletCollectionType(CXCursor C) {
6783 if (C.kind != CXCursor_IBOutletCollectionAttr)
6784 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6785
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006786 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006787 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6788
6789 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6790}
6791} // end: extern "C"
6792
6793//===----------------------------------------------------------------------===//
6794// Inspecting memory usage.
6795//===----------------------------------------------------------------------===//
6796
6797typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6798
6799static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6800 enum CXTUResourceUsageKind k,
6801 unsigned long amount) {
6802 CXTUResourceUsageEntry entry = { k, amount };
6803 entries.push_back(entry);
6804}
6805
6806extern "C" {
6807
6808const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6809 const char *str = "";
6810 switch (kind) {
6811 case CXTUResourceUsage_AST:
6812 str = "ASTContext: expressions, declarations, and types";
6813 break;
6814 case CXTUResourceUsage_Identifiers:
6815 str = "ASTContext: identifiers";
6816 break;
6817 case CXTUResourceUsage_Selectors:
6818 str = "ASTContext: selectors";
6819 break;
6820 case CXTUResourceUsage_GlobalCompletionResults:
6821 str = "Code completion: cached global results";
6822 break;
6823 case CXTUResourceUsage_SourceManagerContentCache:
6824 str = "SourceManager: content cache allocator";
6825 break;
6826 case CXTUResourceUsage_AST_SideTables:
6827 str = "ASTContext: side tables";
6828 break;
6829 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6830 str = "SourceManager: malloc'ed memory buffers";
6831 break;
6832 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6833 str = "SourceManager: mmap'ed memory buffers";
6834 break;
6835 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6836 str = "ExternalASTSource: malloc'ed memory buffers";
6837 break;
6838 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6839 str = "ExternalASTSource: mmap'ed memory buffers";
6840 break;
6841 case CXTUResourceUsage_Preprocessor:
6842 str = "Preprocessor: malloc'ed memory";
6843 break;
6844 case CXTUResourceUsage_PreprocessingRecord:
6845 str = "Preprocessor: PreprocessingRecord";
6846 break;
6847 case CXTUResourceUsage_SourceManager_DataStructures:
6848 str = "SourceManager: data structures and tables";
6849 break;
6850 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6851 str = "Preprocessor: header search tables";
6852 break;
6853 }
6854 return str;
6855}
6856
6857CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006858 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006859 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006860 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006861 return usage;
6862 }
6863
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006864 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006865 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006866 ASTContext &astContext = astUnit->getASTContext();
6867
6868 // How much memory is used by AST nodes and types?
6869 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6870 (unsigned long) astContext.getASTAllocatedMemory());
6871
6872 // How much memory is used by identifiers?
6873 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6874 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6875
6876 // How much memory is used for selectors?
6877 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6878 (unsigned long) astContext.Selectors.getTotalMemory());
6879
6880 // How much memory is used by ASTContext's side tables?
6881 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6882 (unsigned long) astContext.getSideTableAllocatedMemory());
6883
6884 // How much memory is used for caching global code completion results?
6885 unsigned long completionBytes = 0;
6886 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006887 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006888 completionBytes = completionAllocator->getTotalMemory();
6889 }
6890 createCXTUResourceUsageEntry(*entries,
6891 CXTUResourceUsage_GlobalCompletionResults,
6892 completionBytes);
6893
6894 // How much memory is being used by SourceManager's content cache?
6895 createCXTUResourceUsageEntry(*entries,
6896 CXTUResourceUsage_SourceManagerContentCache,
6897 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6898
6899 // How much memory is being used by the MemoryBuffer's in SourceManager?
6900 const SourceManager::MemoryBufferSizes &srcBufs =
6901 astUnit->getSourceManager().getMemoryBufferSizes();
6902
6903 createCXTUResourceUsageEntry(*entries,
6904 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6905 (unsigned long) srcBufs.malloc_bytes);
6906 createCXTUResourceUsageEntry(*entries,
6907 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6908 (unsigned long) srcBufs.mmap_bytes);
6909 createCXTUResourceUsageEntry(*entries,
6910 CXTUResourceUsage_SourceManager_DataStructures,
6911 (unsigned long) astContext.getSourceManager()
6912 .getDataStructureSizes());
6913
6914 // How much memory is being used by the ExternalASTSource?
6915 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6916 const ExternalASTSource::MemoryBufferSizes &sizes =
6917 esrc->getMemoryBufferSizes();
6918
6919 createCXTUResourceUsageEntry(*entries,
6920 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6921 (unsigned long) sizes.malloc_bytes);
6922 createCXTUResourceUsageEntry(*entries,
6923 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6924 (unsigned long) sizes.mmap_bytes);
6925 }
6926
6927 // How much memory is being used by the Preprocessor?
6928 Preprocessor &pp = astUnit->getPreprocessor();
6929 createCXTUResourceUsageEntry(*entries,
6930 CXTUResourceUsage_Preprocessor,
6931 pp.getTotalMemory());
6932
6933 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6934 createCXTUResourceUsageEntry(*entries,
6935 CXTUResourceUsage_PreprocessingRecord,
6936 pRec->getTotalMemory());
6937 }
6938
6939 createCXTUResourceUsageEntry(*entries,
6940 CXTUResourceUsage_Preprocessor_HeaderSearch,
6941 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006942
Guy Benyei11169dd2012-12-18 14:30:41 +00006943 CXTUResourceUsage usage = { (void*) entries.get(),
6944 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006945 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006946 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006947 return usage;
6948}
6949
6950void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6951 if (usage.data)
6952 delete (MemUsageEntries*) usage.data;
6953}
6954
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006955CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6956 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006957 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006958 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006959
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006960 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006961 LOG_BAD_TU(TU);
6962 return skipped;
6963 }
6964
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006965 if (!file)
6966 return skipped;
6967
6968 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6969 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6970 if (!ppRec)
6971 return skipped;
6972
6973 ASTContext &Ctx = astUnit->getASTContext();
6974 SourceManager &sm = Ctx.getSourceManager();
6975 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6976 FileID wantedFileID = sm.translateFile(fileEntry);
6977
6978 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6979 std::vector<SourceRange> wantedRanges;
6980 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6981 i != ei; ++i) {
6982 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6983 wantedRanges.push_back(*i);
6984 }
6985
6986 skipped->count = wantedRanges.size();
6987 skipped->ranges = new CXSourceRange[skipped->count];
6988 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6989 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6990
6991 return skipped;
6992}
6993
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006994void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6995 if (ranges) {
6996 delete[] ranges->ranges;
6997 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006998 }
6999}
7000
Guy Benyei11169dd2012-12-18 14:30:41 +00007001} // end extern "C"
7002
7003void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7004 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7005 for (unsigned I = 0; I != Usage.numEntries; ++I)
7006 fprintf(stderr, " %s: %lu\n",
7007 clang_getTUResourceUsageName(Usage.entries[I].kind),
7008 Usage.entries[I].amount);
7009
7010 clang_disposeCXTUResourceUsage(Usage);
7011}
7012
7013//===----------------------------------------------------------------------===//
7014// Misc. utility functions.
7015//===----------------------------------------------------------------------===//
7016
7017/// Default to using an 8 MB stack size on "safety" threads.
7018static unsigned SafetyStackThreadSize = 8 << 20;
7019
7020namespace clang {
7021
7022bool RunSafely(llvm::CrashRecoveryContext &CRC,
7023 void (*Fn)(void*), void *UserData,
7024 unsigned Size) {
7025 if (!Size)
7026 Size = GetSafetyThreadStackSize();
7027 if (Size)
7028 return CRC.RunSafelyOnThread(Fn, UserData, Size);
7029 return CRC.RunSafely(Fn, UserData);
7030}
7031
7032unsigned GetSafetyThreadStackSize() {
7033 return SafetyStackThreadSize;
7034}
7035
7036void SetSafetyThreadStackSize(unsigned Value) {
7037 SafetyStackThreadSize = Value;
7038}
7039
7040}
7041
7042void clang::setThreadBackgroundPriority() {
7043 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7044 return;
7045
Alp Toker1a86ad22014-07-06 06:24:00 +00007046#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007047 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7048#endif
7049}
7050
7051void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7052 if (!Unit)
7053 return;
7054
7055 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7056 DEnd = Unit->stored_diag_end();
7057 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007058 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007059 CXString Msg = clang_formatDiagnostic(&Diag,
7060 clang_defaultDiagnosticDisplayOptions());
7061 fprintf(stderr, "%s\n", clang_getCString(Msg));
7062 clang_disposeString(Msg);
7063 }
7064#ifdef LLVM_ON_WIN32
7065 // On Windows, force a flush, since there may be multiple copies of
7066 // stderr and stdout in the file system, all with different buffers
7067 // but writing to the same device.
7068 fflush(stderr);
7069#endif
7070}
7071
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007072MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7073 SourceLocation MacroDefLoc,
7074 CXTranslationUnit TU){
7075 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007076 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007077 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007078 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007079
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007080 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007081 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007082 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007083 if (MD) {
7084 for (MacroDirective::DefInfo
7085 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7086 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7087 return Def.getMacroInfo();
7088 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007089 }
7090
Craig Topper69186e72014-06-08 08:38:04 +00007091 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007092}
7093
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007094const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7095 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007096 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007097 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007098 const IdentifierInfo *II = MacroDef->getName();
7099 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007100 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007101
7102 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7103}
7104
7105MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7106 const Token &Tok,
7107 CXTranslationUnit TU) {
7108 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007109 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007110 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007111 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007112
7113 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007114 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007115 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7116 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007117 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007118
7119 // Check that the token is inside the definition and not its argument list.
7120 SourceManager &SM = Unit->getSourceManager();
7121 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007122 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007123 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007124 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007125
7126 Preprocessor &PP = Unit->getPreprocessor();
7127 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7128 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007129 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007130
Alp Toker2d57cea2014-05-17 04:53:25 +00007131 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007132 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007133 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007134
7135 // Check that the identifier is not one of the macro arguments.
7136 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007137 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007138
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007139 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7140 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007141 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007142
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007143 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007144}
7145
7146MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7147 SourceLocation Loc,
7148 CXTranslationUnit TU) {
7149 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007150 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007151
7152 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007153 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007154 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007155 Preprocessor &PP = Unit->getPreprocessor();
7156 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007157 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007158 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7159 Token Tok;
7160 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007161 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007162
7163 return checkForMacroInMacroDefinition(MI, Tok, TU);
7164}
7165
Guy Benyei11169dd2012-12-18 14:30:41 +00007166extern "C" {
7167
7168CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007169 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007170}
7171
7172} // end: extern "C"
7173
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007174Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7175 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007176 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007177 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007178 if (Unit->isMainFileAST())
7179 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007180 return *this;
7181 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007182 } else {
7183 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007184 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007185 return *this;
7186}
7187
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007188Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7189 *this << FE->getName();
7190 return *this;
7191}
7192
7193Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7194 CXString cursorName = clang_getCursorDisplayName(cursor);
7195 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7196 clang_disposeString(cursorName);
7197 return *this;
7198}
7199
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007200Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7201 CXFile File;
7202 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007203 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007204 CXString FileName = clang_getFileName(File);
7205 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7206 clang_disposeString(FileName);
7207 return *this;
7208}
7209
7210Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7211 CXSourceLocation BLoc = clang_getRangeStart(range);
7212 CXSourceLocation ELoc = clang_getRangeEnd(range);
7213
7214 CXFile BFile;
7215 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007216 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007217
7218 CXFile EFile;
7219 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007220 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007221
7222 CXString BFileName = clang_getFileName(BFile);
7223 if (BFile == EFile) {
7224 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7225 BLine, BColumn, ELine, EColumn);
7226 } else {
7227 CXString EFileName = clang_getFileName(EFile);
7228 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7229 BLine, BColumn)
7230 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7231 ELine, EColumn);
7232 clang_disposeString(EFileName);
7233 }
7234 clang_disposeString(BFileName);
7235 return *this;
7236}
7237
7238Logger &cxindex::Logger::operator<<(CXString Str) {
7239 *this << clang_getCString(Str);
7240 return *this;
7241}
7242
7243Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7244 LogOS << Fmt;
7245 return *this;
7246}
7247
Chandler Carruth37ad2582014-06-27 15:14:39 +00007248static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7249
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007250cxindex::Logger::~Logger() {
7251 LogOS.flush();
7252
Chandler Carruth37ad2582014-06-27 15:14:39 +00007253 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007254
7255 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7256
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007257 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007258 OS << "[libclang:" << Name << ':';
7259
Alp Toker1a86ad22014-07-06 06:24:00 +00007260#ifdef USE_DARWIN_THREADS
7261 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007262 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7263 OS << tid << ':';
7264#endif
7265
7266 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7267 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7268 OS << Msg.str() << '\n';
7269
7270 if (Trace) {
7271 llvm::sys::PrintStackTrace(stderr);
7272 OS << "--------------------------------------------------\n";
7273 }
7274}