blob: 6aa14b66e664640c41fa2ec819086f165fe73b06 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
243 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
244 Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
458
459 continue;
460 }
461
462 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
465
466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000572 if (MacroDefinition *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
667bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669 return Visit(TSInfo->getTypeLoc());
670
671 return false;
672}
673
674bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682 return VisitDeclContext(D);
683}
684
685bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686 ClassTemplateSpecializationDecl *D) {
687 bool ShouldVisitBody = false;
688 switch (D->getSpecializationKind()) {
689 case TSK_Undeclared:
690 case TSK_ImplicitInstantiation:
691 // Nothing to visit
692 return false;
693
694 case TSK_ExplicitInstantiationDeclaration:
695 case TSK_ExplicitInstantiationDefinition:
696 break;
697
698 case TSK_ExplicitSpecialization:
699 ShouldVisitBody = true;
700 break;
701 }
702
703 // Visit the template arguments used in the specialization.
704 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000706 if (TemplateSpecializationTypeLoc TSTLoc =
707 TL.getAs<TemplateSpecializationTypeLoc>()) {
708 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000710 return true;
711 }
712 }
713
714 if (ShouldVisitBody && VisitCXXRecordDecl(D))
715 return true;
716
717 return false;
718}
719
720bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721 ClassTemplatePartialSpecializationDecl *D) {
722 // FIXME: Visit the "outer" template parameter lists on the TagDecl
723 // before visiting these template parameters.
724 if (VisitTemplateParameters(D->getTemplateParameters()))
725 return true;
726
727 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000728 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732 return true;
733
734 return VisitCXXRecordDecl(D);
735}
736
737bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738 // Visit the default argument.
739 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741 if (Visit(DefArg->getTypeLoc()))
742 return true;
743
744 return false;
745}
746
747bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748 if (Expr *Init = D->getInitExpr())
749 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750 return false;
751}
752
753bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000754 unsigned NumParamList = DD->getNumTemplateParameterLists();
755 for (unsigned i = 0; i < NumParamList; i++) {
756 TemplateParameterList* Params = DD->getTemplateParameterList(i);
757 if (VisitTemplateParameters(Params))
758 return true;
759 }
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762 if (Visit(TSInfo->getTypeLoc()))
763 return true;
764
765 // Visit the nested-name-specifier, if present.
766 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
768 return true;
769
770 return false;
771}
772
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000773/// \brief Compare two base or member initializers based on their source order.
774static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775 CXXCtorInitializer *const *Y) {
776 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777}
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 unsigned NumParamList = ND->getNumTemplateParameterLists();
781 for (unsigned i = 0; i < NumParamList; i++) {
782 TemplateParameterList* Params = ND->getTemplateParameterList(i);
783 if (VisitTemplateParameters(Params))
784 return true;
785 }
786
Guy Benyei11169dd2012-12-18 14:30:41 +0000787 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788 // Visit the function declaration's syntactic components in the order
789 // written. This requires a bit of work.
790 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000791 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000792
793 // If we have a function declared directly (without the use of a typedef),
794 // visit just the return type. Otherwise, just visit the function's type
795 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000796 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000797 (!FTL && Visit(TL)))
798 return true;
799
800 // Visit the nested-name-specifier, if present.
801 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
803 return true;
804
805 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000806 if (!isa<CXXDestructorDecl>(ND))
807 if (VisitDeclarationNameInfo(ND->getNameInfo()))
808 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000809
810 // FIXME: Visit explicitly-specified template arguments!
811
812 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000813 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 return true;
815
Bill Wendling44426052012-12-20 19:22:21 +0000816 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 }
818
819 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821 // Find the initializers that were written in the source.
822 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 for (auto *I : Constructor->inits()) {
824 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 continue;
826
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 }
829
830 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000831 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832 &CompareCXXCtorInitializers);
833
Guy Benyei11169dd2012-12-18 14:30:41 +0000834 // Visit the initializers in source order
835 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836 CXXCtorInitializer *Init = WrittenInits[I];
837 if (Init->isAnyMemberInitializer()) {
838 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839 Init->getMemberLocation(), TU)))
840 return true;
841 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842 if (Visit(TInfo->getTypeLoc()))
843 return true;
844 }
845
846 // Visit the initializer value.
847 if (Expr *Initializer = Init->getInit())
848 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849 return true;
850 }
851 }
852
853 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854 return true;
855 }
856
857 return false;
858}
859
860bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861 if (VisitDeclaratorDecl(D))
862 return true;
863
864 if (Expr *BitWidth = D->getBitWidth())
865 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871 if (VisitDeclaratorDecl(D))
872 return true;
873
874 if (Expr *Init = D->getInit())
875 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876
877 return false;
878}
879
880bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881 if (VisitDeclaratorDecl(D))
882 return true;
883
884 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885 if (Expr *DefArg = D->getDefaultArgument())
886 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887
888 return false;
889}
890
891bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitFunctionDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901 // FIXME: Visit the "outer" template parameter lists on the TagDecl
902 // before visiting these template parameters.
903 if (VisitTemplateParameters(D->getTemplateParameters()))
904 return true;
905
906 return VisitCXXRecordDecl(D->getTemplatedDecl());
907}
908
909bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914 VisitTemplateArgumentLoc(D->getDefaultArgument()))
915 return true;
916
917 return false;
918}
919
920bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000921 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000922 if (Visit(TSInfo->getTypeLoc()))
923 return true;
924
Aaron Ballman43b68be2014-03-07 17:50:17 +0000925 for (const auto *P : ND->params()) {
926 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000927 return true;
928 }
929
930 if (ND->isThisDeclarationADefinition() &&
931 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
932 return true;
933
934 return false;
935}
936
937template <typename DeclIt>
938static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
939 SourceManager &SM, SourceLocation EndLoc,
940 SmallVectorImpl<Decl *> &Decls) {
941 DeclIt next = *DI_current;
942 while (++next != DE_current) {
943 Decl *D_next = *next;
944 if (!D_next)
945 break;
946 SourceLocation L = D_next->getLocStart();
947 if (!L.isValid())
948 break;
949 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
950 *DI_current = next;
951 Decls.push_back(D_next);
952 continue;
953 }
954 break;
955 }
956}
957
Guy Benyei11169dd2012-12-18 14:30:41 +0000958bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
959 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
960 // an @implementation can lexically contain Decls that are not properly
961 // nested in the AST. When we identify such cases, we need to retrofit
962 // this nesting here.
963 if (!DI_current && !FileDI_current)
964 return VisitDeclContext(D);
965
966 // Scan the Decls that immediately come after the container
967 // in the current DeclContext. If any fall within the
968 // container's lexical region, stash them into a vector
969 // for later processing.
970 SmallVector<Decl *, 24> DeclsInContainer;
971 SourceLocation EndLoc = D->getSourceRange().getEnd();
972 SourceManager &SM = AU->getSourceManager();
973 if (EndLoc.isValid()) {
974 if (DI_current) {
975 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
976 DeclsInContainer);
977 } else {
978 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
979 DeclsInContainer);
980 }
981 }
982
983 // The common case.
984 if (DeclsInContainer.empty())
985 return VisitDeclContext(D);
986
987 // Get all the Decls in the DeclContext, and sort them with the
988 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 for (auto *SubDecl : D->decls()) {
990 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
991 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000992 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000993 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000994 }
995
996 // Now sort the Decls so that they appear in lexical order.
997 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000998 [&SM](Decl *A, Decl *B) {
999 SourceLocation L_A = A->getLocStart();
1000 SourceLocation L_B = B->getLocStart();
1001 assert(L_A.isValid() && L_B.isValid());
1002 return SM.isBeforeInTranslationUnit(L_A, L_B);
1003 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001004
1005 // Now visit the decls.
1006 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1007 E = DeclsInContainer.end(); I != E; ++I) {
1008 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001009 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001010 if (!V.hasValue())
1011 continue;
1012 if (!V.getValue())
1013 return false;
1014 if (Visit(Cursor, true))
1015 return true;
1016 }
1017 return false;
1018}
1019
1020bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1021 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1022 TU)))
1023 return true;
1024
1025 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1026 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1027 E = ND->protocol_end(); I != E; ++I, ++PL)
1028 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1029 return true;
1030
1031 return VisitObjCContainerDecl(ND);
1032}
1033
1034bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1035 if (!PID->isThisDeclarationADefinition())
1036 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1037
1038 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1039 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1040 E = PID->protocol_end(); I != E; ++I, ++PL)
1041 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042 return true;
1043
1044 return VisitObjCContainerDecl(PID);
1045}
1046
1047bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1048 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1049 return true;
1050
1051 // FIXME: This implements a workaround with @property declarations also being
1052 // installed in the DeclContext for the @interface. Eventually this code
1053 // should be removed.
1054 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1055 if (!CDecl || !CDecl->IsClassExtension())
1056 return false;
1057
1058 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1059 if (!ID)
1060 return false;
1061
1062 IdentifierInfo *PropertyId = PD->getIdentifier();
1063 ObjCPropertyDecl *prevDecl =
1064 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1065
1066 if (!prevDecl)
1067 return false;
1068
1069 // Visit synthesized methods since they will be skipped when visiting
1070 // the @interface.
1071 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1072 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1073 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1074 return true;
1075
1076 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1077 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1078 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1079 return true;
1080
1081 return false;
1082}
1083
1084bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1085 if (!D->isThisDeclarationADefinition()) {
1086 // Forward declaration is treated like a reference.
1087 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1088 }
1089
1090 // Issue callbacks for super class.
1091 if (D->getSuperClass() &&
1092 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1093 D->getSuperClassLoc(),
1094 TU)))
1095 return true;
1096
1097 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1098 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1099 E = D->protocol_end(); I != E; ++I, ++PL)
1100 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1101 return true;
1102
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1107 return VisitObjCContainerDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1111 // 'ID' could be null when dealing with invalid code.
1112 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1113 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1114 return true;
1115
1116 return VisitObjCImplDecl(D);
1117}
1118
1119bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1120#if 0
1121 // Issue callbacks for super class.
1122 // FIXME: No source location information!
1123 if (D->getSuperClass() &&
1124 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125 D->getSuperClassLoc(),
1126 TU)))
1127 return true;
1128#endif
1129
1130 return VisitObjCImplDecl(D);
1131}
1132
1133bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1134 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1135 if (PD->isIvarNameSpecified())
1136 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1137
1138 return false;
1139}
1140
1141bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1142 return VisitDeclContext(D);
1143}
1144
1145bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1146 // Visit nested-name-specifier.
1147 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1148 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149 return true;
1150
1151 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1152 D->getTargetNameLoc(), TU));
1153}
1154
1155bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1156 // Visit nested-name-specifier.
1157 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1158 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1159 return true;
1160 }
1161
1162 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1163 return true;
1164
1165 return VisitDeclarationNameInfo(D->getNameInfo());
1166}
1167
1168bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1169 // Visit nested-name-specifier.
1170 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172 return true;
1173
1174 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1175 D->getIdentLocation(), TU));
1176}
1177
1178bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1179 // Visit nested-name-specifier.
1180 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1181 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1182 return true;
1183 }
1184
1185 return VisitDeclarationNameInfo(D->getNameInfo());
1186}
1187
1188bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1189 UnresolvedUsingTypenameDecl *D) {
1190 // Visit nested-name-specifier.
1191 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1192 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1193 return true;
1194
1195 return false;
1196}
1197
1198bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1199 switch (Name.getName().getNameKind()) {
1200 case clang::DeclarationName::Identifier:
1201 case clang::DeclarationName::CXXLiteralOperatorName:
1202 case clang::DeclarationName::CXXOperatorName:
1203 case clang::DeclarationName::CXXUsingDirective:
1204 return false;
1205
1206 case clang::DeclarationName::CXXConstructorName:
1207 case clang::DeclarationName::CXXDestructorName:
1208 case clang::DeclarationName::CXXConversionFunctionName:
1209 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1210 return Visit(TSInfo->getTypeLoc());
1211 return false;
1212
1213 case clang::DeclarationName::ObjCZeroArgSelector:
1214 case clang::DeclarationName::ObjCOneArgSelector:
1215 case clang::DeclarationName::ObjCMultiArgSelector:
1216 // FIXME: Per-identifier location info?
1217 return false;
1218 }
1219
1220 llvm_unreachable("Invalid DeclarationName::Kind!");
1221}
1222
1223bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1224 SourceRange Range) {
1225 // FIXME: This whole routine is a hack to work around the lack of proper
1226 // source information in nested-name-specifiers (PR5791). Since we do have
1227 // a beginning source location, we can visit the first component of the
1228 // nested-name-specifier, if it's a single-token component.
1229 if (!NNS)
1230 return false;
1231
1232 // Get the first component in the nested-name-specifier.
1233 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1234 NNS = Prefix;
1235
1236 switch (NNS->getKind()) {
1237 case NestedNameSpecifier::Namespace:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1239 TU));
1240
1241 case NestedNameSpecifier::NamespaceAlias:
1242 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1243 Range.getBegin(), TU));
1244
1245 case NestedNameSpecifier::TypeSpec: {
1246 // If the type has a form where we know that the beginning of the source
1247 // range matches up with a reference cursor. Visit the appropriate reference
1248 // cursor.
1249 const Type *T = NNS->getAsType();
1250 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1251 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1252 if (const TagType *Tag = dyn_cast<TagType>(T))
1253 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1254 if (const TemplateSpecializationType *TST
1255 = dyn_cast<TemplateSpecializationType>(T))
1256 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1257 break;
1258 }
1259
1260 case NestedNameSpecifier::TypeSpecWithTemplate:
1261 case NestedNameSpecifier::Global:
1262 case NestedNameSpecifier::Identifier:
1263 break;
1264 }
1265
1266 return false;
1267}
1268
1269bool
1270CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1271 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1272 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1273 Qualifiers.push_back(Qualifier);
1274
1275 while (!Qualifiers.empty()) {
1276 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1277 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1278 switch (NNS->getKind()) {
1279 case NestedNameSpecifier::Namespace:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::NamespaceAlias:
1288 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1289 Q.getLocalBeginLoc(),
1290 TU)))
1291 return true;
1292
1293 break;
1294
1295 case NestedNameSpecifier::TypeSpec:
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 if (Visit(Q.getTypeLoc()))
1298 return true;
1299
1300 break;
1301
1302 case NestedNameSpecifier::Global:
1303 case NestedNameSpecifier::Identifier:
1304 break;
1305 }
1306 }
1307
1308 return false;
1309}
1310
1311bool CursorVisitor::VisitTemplateParameters(
1312 const TemplateParameterList *Params) {
1313 if (!Params)
1314 return false;
1315
1316 for (TemplateParameterList::const_iterator P = Params->begin(),
1317 PEnd = Params->end();
1318 P != PEnd; ++P) {
1319 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1320 return true;
1321 }
1322
1323 return false;
1324}
1325
1326bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1327 switch (Name.getKind()) {
1328 case TemplateName::Template:
1329 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1330
1331 case TemplateName::OverloadedTemplate:
1332 // Visit the overloaded template set.
1333 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1334 return true;
1335
1336 return false;
1337
1338 case TemplateName::DependentTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return false;
1341
1342 case TemplateName::QualifiedTemplate:
1343 // FIXME: Visit nested-name-specifier.
1344 return Visit(MakeCursorTemplateRef(
1345 Name.getAsQualifiedTemplateName()->getDecl(),
1346 Loc, TU));
1347
1348 case TemplateName::SubstTemplateTemplateParm:
1349 return Visit(MakeCursorTemplateRef(
1350 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1351 Loc, TU));
1352
1353 case TemplateName::SubstTemplateTemplateParmPack:
1354 return Visit(MakeCursorTemplateRef(
1355 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1356 Loc, TU));
1357 }
1358
1359 llvm_unreachable("Invalid TemplateName::Kind!");
1360}
1361
1362bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1363 switch (TAL.getArgument().getKind()) {
1364 case TemplateArgument::Null:
1365 case TemplateArgument::Integral:
1366 case TemplateArgument::Pack:
1367 return false;
1368
1369 case TemplateArgument::Type:
1370 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1371 return Visit(TSInfo->getTypeLoc());
1372 return false;
1373
1374 case TemplateArgument::Declaration:
1375 if (Expr *E = TAL.getSourceDeclExpression())
1376 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1377 return false;
1378
1379 case TemplateArgument::NullPtr:
1380 if (Expr *E = TAL.getSourceNullPtrExpression())
1381 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1382 return false;
1383
1384 case TemplateArgument::Expression:
1385 if (Expr *E = TAL.getSourceExpression())
1386 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1387 return false;
1388
1389 case TemplateArgument::Template:
1390 case TemplateArgument::TemplateExpansion:
1391 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1392 return true;
1393
1394 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1395 TAL.getTemplateNameLoc());
1396 }
1397
1398 llvm_unreachable("Invalid TemplateArgument::Kind!");
1399}
1400
1401bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1402 return VisitDeclContext(D);
1403}
1404
1405bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1406 return Visit(TL.getUnqualifiedLoc());
1407}
1408
1409bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1410 ASTContext &Context = AU->getASTContext();
1411
1412 // Some builtin types (such as Objective-C's "id", "sel", and
1413 // "Class") have associated declarations. Create cursors for those.
1414 QualType VisitType;
1415 switch (TL.getTypePtr()->getKind()) {
1416
1417 case BuiltinType::Void:
1418 case BuiltinType::NullPtr:
1419 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001420 case BuiltinType::OCLImage1d:
1421 case BuiltinType::OCLImage1dArray:
1422 case BuiltinType::OCLImage1dBuffer:
1423 case BuiltinType::OCLImage2d:
1424 case BuiltinType::OCLImage2dArray:
1425 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001426 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001427 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001428#define BUILTIN_TYPE(Id, SingletonId)
1429#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#include "clang/AST/BuiltinTypes.def"
1434 break;
1435
1436 case BuiltinType::ObjCId:
1437 VisitType = Context.getObjCIdType();
1438 break;
1439
1440 case BuiltinType::ObjCClass:
1441 VisitType = Context.getObjCClassType();
1442 break;
1443
1444 case BuiltinType::ObjCSel:
1445 VisitType = Context.getObjCSelType();
1446 break;
1447 }
1448
1449 if (!VisitType.isNull()) {
1450 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1451 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1452 TU));
1453 }
1454
1455 return false;
1456}
1457
1458bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1463 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1464}
1465
1466bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1467 if (TL.isDefinition())
1468 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1469
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1474 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1475}
1476
1477bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1478 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1479 return true;
1480
1481 return false;
1482}
1483
1484bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1485 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1486 return true;
1487
1488 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1489 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1490 TU)))
1491 return true;
1492 }
1493
1494 return false;
1495}
1496
1497bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1502 return Visit(TL.getInnerLoc());
1503}
1504
1505bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1522 return Visit(TL.getPointeeLoc());
1523}
1524
1525bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1526 return Visit(TL.getModifiedLoc());
1527}
1528
1529bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1530 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001531 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 return true;
1533
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001534 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1535 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001536 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1537 return true;
1538
1539 return false;
1540}
1541
1542bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1543 if (Visit(TL.getElementLoc()))
1544 return true;
1545
1546 if (Expr *Size = TL.getSizeExpr())
1547 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1548
1549 return false;
1550}
1551
Reid Kleckner8a365022013-06-24 17:51:48 +00001552bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Reid Kleckner0503a872013-12-05 01:23:43 +00001556bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1557 return Visit(TL.getOriginalLoc());
1558}
1559
Guy Benyei11169dd2012-12-18 14:30:41 +00001560bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1561 TemplateSpecializationTypeLoc TL) {
1562 // Visit the template name.
1563 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1564 TL.getTemplateNameLoc()))
1565 return true;
1566
1567 // Visit the template arguments.
1568 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1569 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1570 return true;
1571
1572 return false;
1573}
1574
1575bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1576 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1577}
1578
1579bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1580 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1581 return Visit(TSInfo->getTypeLoc());
1582
1583 return false;
1584}
1585
1586bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1587 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1588 return Visit(TSInfo->getTypeLoc());
1589
1590 return false;
1591}
1592
1593bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1594 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1595 return true;
1596
1597 return false;
1598}
1599
1600bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1601 DependentTemplateSpecializationTypeLoc TL) {
1602 // Visit the nested-name-specifier, if there is one.
1603 if (TL.getQualifierLoc() &&
1604 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1605 return true;
1606
1607 // Visit the template arguments.
1608 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1609 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1610 return true;
1611
1612 return false;
1613}
1614
1615bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1616 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1617 return true;
1618
1619 return Visit(TL.getNamedTypeLoc());
1620}
1621
1622bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1623 return Visit(TL.getPatternLoc());
1624}
1625
1626bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1627 if (Expr *E = TL.getUnderlyingExpr())
1628 return Visit(MakeCXCursor(E, StmtParent, TU));
1629
1630 return false;
1631}
1632
1633bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1634 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1635}
1636
1637bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1638 return Visit(TL.getValueLoc());
1639}
1640
1641#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1642bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1643 return Visit##PARENT##Loc(TL); \
1644}
1645
1646DEFAULT_TYPELOC_IMPL(Complex, Type)
1647DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1648DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1652DEFAULT_TYPELOC_IMPL(Vector, Type)
1653DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1654DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1655DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1656DEFAULT_TYPELOC_IMPL(Record, TagType)
1657DEFAULT_TYPELOC_IMPL(Enum, TagType)
1658DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1659DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1660DEFAULT_TYPELOC_IMPL(Auto, Type)
1661
1662bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1663 // Visit the nested-name-specifier, if present.
1664 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1665 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1666 return true;
1667
1668 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001669 for (const auto &I : D->bases()) {
1670 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001671 return true;
1672 }
1673 }
1674
1675 return VisitTagDecl(D);
1676}
1677
1678bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001679 for (const auto *I : D->attrs())
1680 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001681 return true;
1682
1683 return false;
1684}
1685
1686//===----------------------------------------------------------------------===//
1687// Data-recursive visitor methods.
1688//===----------------------------------------------------------------------===//
1689
1690namespace {
1691#define DEF_JOB(NAME, DATA, KIND)\
1692class NAME : public VisitorJob {\
1693public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001694 NAME(const DATA *d, CXCursor parent) : \
1695 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001696 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001697 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001698};
1699
1700DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1701DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1702DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1703DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1704DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1705 ExplicitTemplateArgsVisitKind)
1706DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1707DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1708DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1709#undef DEF_JOB
1710
1711class DeclVisit : public VisitorJob {
1712public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001713 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001715 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 static bool classof(const VisitorJob *VJ) {
1717 return VJ->getKind() == DeclVisitKind;
1718 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001719 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001720 bool isFirst() const { return data[1] ? true : false; }
1721};
1722class TypeLocVisit : public VisitorJob {
1723public:
1724 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1725 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1726 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1727
1728 static bool classof(const VisitorJob *VJ) {
1729 return VJ->getKind() == TypeLocVisitKind;
1730 }
1731
1732 TypeLoc get() const {
1733 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001734 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 }
1736};
1737
1738class LabelRefVisit : public VisitorJob {
1739public:
1740 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1741 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1742 labelLoc.getPtrEncoding()) {}
1743
1744 static bool classof(const VisitorJob *VJ) {
1745 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1746 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 const LabelDecl *get() const {
1748 return static_cast<const LabelDecl *>(data[0]);
1749 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 SourceLocation getLoc() const {
1751 return SourceLocation::getFromPtrEncoding(data[1]); }
1752};
1753
1754class NestedNameSpecifierLocVisit : public VisitorJob {
1755public:
1756 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1757 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1758 Qualifier.getNestedNameSpecifier(),
1759 Qualifier.getOpaqueData()) { }
1760
1761 static bool classof(const VisitorJob *VJ) {
1762 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1763 }
1764
1765 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 return NestedNameSpecifierLoc(
1767 const_cast<NestedNameSpecifier *>(
1768 static_cast<const NestedNameSpecifier *>(data[0])),
1769 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 }
1771};
1772
1773class DeclarationNameInfoVisit : public VisitorJob {
1774public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001775 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001776 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001777 static bool classof(const VisitorJob *VJ) {
1778 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1779 }
1780 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001781 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 switch (S->getStmtClass()) {
1783 default:
1784 llvm_unreachable("Unhandled Stmt");
1785 case clang::Stmt::MSDependentExistsStmtClass:
1786 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1787 case Stmt::CXXDependentScopeMemberExprClass:
1788 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1789 case Stmt::DependentScopeDeclRefExprClass:
1790 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001791 case Stmt::OMPCriticalDirectiveClass:
1792 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 }
1794 }
1795};
1796class MemberRefVisit : public VisitorJob {
1797public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001799 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1800 L.getPtrEncoding()) {}
1801 static bool classof(const VisitorJob *VJ) {
1802 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1803 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804 const FieldDecl *get() const {
1805 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001806 }
1807 SourceLocation getLoc() const {
1808 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1809 }
1810};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001811class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001812 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001813 VisitorWorkList &WL;
1814 CXCursor Parent;
1815public:
1816 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1817 : WL(wl), Parent(parent) {}
1818
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001819 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1820 void VisitBlockExpr(const BlockExpr *B);
1821 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1822 void VisitCompoundStmt(const CompoundStmt *S);
1823 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1824 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1825 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1826 void VisitCXXNewExpr(const CXXNewExpr *E);
1827 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1828 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1829 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1830 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1831 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1832 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1833 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1834 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1835 void VisitDeclRefExpr(const DeclRefExpr *D);
1836 void VisitDeclStmt(const DeclStmt *S);
1837 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1838 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1839 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1840 void VisitForStmt(const ForStmt *FS);
1841 void VisitGotoStmt(const GotoStmt *GS);
1842 void VisitIfStmt(const IfStmt *If);
1843 void VisitInitListExpr(const InitListExpr *IE);
1844 void VisitMemberExpr(const MemberExpr *M);
1845 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1846 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1847 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1848 void VisitOverloadExpr(const OverloadExpr *E);
1849 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1850 void VisitStmt(const Stmt *S);
1851 void VisitSwitchStmt(const SwitchStmt *S);
1852 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1854 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1855 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1856 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1857 void VisitVAArgExpr(const VAArgExpr *E);
1858 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1859 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1860 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1861 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001862 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001863 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001865 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001866 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001867 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001868 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001869 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001870 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001871 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001872 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001873 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001874 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001875 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001876 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001877 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001878 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001879 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001880 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881
Guy Benyei11169dd2012-12-18 14:30:41 +00001882private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001884 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1885 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001886 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1887 void AddStmt(const Stmt *S);
1888 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001889 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001890 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001891 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001892};
1893} // end anonyous namespace
1894
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001895void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001896 // 'S' should always be non-null, since it comes from the
1897 // statement we are visiting.
1898 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1899}
1900
1901void
1902EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1903 if (Qualifier)
1904 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1905}
1906
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001907void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001908 if (S)
1909 WL.push_back(StmtVisit(S, Parent));
1910}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001911void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001912 if (D)
1913 WL.push_back(DeclVisit(D, Parent, isFirst));
1914}
1915void EnqueueVisitor::
1916 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1917 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001918 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001919}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001920void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001921 if (D)
1922 WL.push_back(MemberRefVisit(D, L, Parent));
1923}
1924void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1925 if (TI)
1926 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1927 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001928void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001929 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001930 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001931 AddStmt(*Child);
1932 }
1933 if (size == WL.size())
1934 return;
1935 // Now reverse the entries we just added. This will match the DFS
1936 // ordering performed by the worklist.
1937 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1938 std::reverse(I, E);
1939}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001940namespace {
1941class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1942 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001943 /// \brief Process clauses with list of variables.
1944 template <typename T>
1945 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946public:
1947 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1948#define OPENMP_CLAUSE(Name, Class) \
1949 void Visit##Class(const Class *C);
1950#include "clang/Basic/OpenMPKinds.def"
1951};
1952
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001953void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1954 Visitor->AddStmt(C->getCondition());
1955}
1956
Alexey Bataev3778b602014-07-17 07:32:53 +00001957void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1958 Visitor->AddStmt(C->getCondition());
1959}
1960
Alexey Bataev568a8332014-03-06 06:15:19 +00001961void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1962 Visitor->AddStmt(C->getNumThreads());
1963}
1964
Alexey Bataev62c87d22014-03-21 04:51:18 +00001965void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1966 Visitor->AddStmt(C->getSafelen());
1967}
1968
Alexander Musman8bd31e62014-05-27 15:12:19 +00001969void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1970 Visitor->AddStmt(C->getNumForLoops());
1971}
1972
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001973void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001974
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001975void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1976
Alexey Bataev56dafe82014-06-20 07:16:17 +00001977void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1978 Visitor->AddStmt(C->getChunkSize());
1979}
1980
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001981void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1982
Alexey Bataev236070f2014-06-20 11:19:47 +00001983void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1984
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001985void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1986
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001987void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1988
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001989void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1990
Alexey Bataevdea47612014-07-23 07:46:59 +00001991void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1992
Alexey Bataev67a4f222014-07-23 10:25:33 +00001993void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
1994
Alexey Bataev459dec02014-07-24 06:46:57 +00001995void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
1996
Alexey Bataev82bad8b2014-07-24 08:55:34 +00001997void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
1998
Alexey Bataev756c1962013-09-24 03:17:45 +00001999template<typename T>
2000void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002001 for (const auto *I : Node->varlists())
2002 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00002003}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002004
2005void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002006 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002007}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002008void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2009 const OMPFirstprivateClause *C) {
2010 VisitOMPClauseList(C);
2011}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002012void OMPClauseEnqueue::VisitOMPLastprivateClause(
2013 const OMPLastprivateClause *C) {
2014 VisitOMPClauseList(C);
2015}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002016void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002017 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002018}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002019void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2020 VisitOMPClauseList(C);
2021}
Alexander Musman8dba6642014-04-22 13:09:42 +00002022void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2023 VisitOMPClauseList(C);
2024 Visitor->AddStmt(C->getStep());
2025}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002026void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2027 VisitOMPClauseList(C);
2028 Visitor->AddStmt(C->getAlignment());
2029}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002030void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2031 VisitOMPClauseList(C);
2032}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002033void
2034OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2035 VisitOMPClauseList(C);
2036}
Alexey Bataev6125da92014-07-21 11:26:11 +00002037void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2038 VisitOMPClauseList(C);
2039}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002040}
Alexey Bataev756c1962013-09-24 03:17:45 +00002041
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002042void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2043 unsigned size = WL.size();
2044 OMPClauseEnqueue Visitor(this);
2045 Visitor.Visit(S);
2046 if (size == WL.size())
2047 return;
2048 // Now reverse the entries we just added. This will match the DFS
2049 // ordering performed by the worklist.
2050 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2051 std::reverse(I, E);
2052}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002054 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2055}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002056void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002057 AddDecl(B->getBlockDecl());
2058}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 EnqueueChildren(E);
2061 AddTypeLoc(E->getTypeSourceInfo());
2062}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002063void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2064 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002065 E = S->body_rend(); I != E; ++I) {
2066 AddStmt(*I);
2067 }
2068}
2069void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002070VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002071 AddStmt(S->getSubStmt());
2072 AddDeclarationNameInfo(S);
2073 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2074 AddNestedNameSpecifierLoc(QualifierLoc);
2075}
2076
2077void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002078VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002079 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2080 AddDeclarationNameInfo(E);
2081 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2082 AddNestedNameSpecifierLoc(QualifierLoc);
2083 if (!E->isImplicitAccess())
2084 AddStmt(E->getBase());
2085}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002086void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002087 // Enqueue the initializer , if any.
2088 AddStmt(E->getInitializer());
2089 // Enqueue the array size, if any.
2090 AddStmt(E->getArraySize());
2091 // Enqueue the allocated type.
2092 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2093 // Enqueue the placement arguments.
2094 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2095 AddStmt(E->getPlacementArg(I-1));
2096}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2099 AddStmt(CE->getArg(I-1));
2100 AddStmt(CE->getCallee());
2101 AddStmt(CE->getArg(0));
2102}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002103void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2104 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 // Visit the name of the type being destroyed.
2106 AddTypeLoc(E->getDestroyedTypeInfo());
2107 // Visit the scope type that looks disturbingly like the nested-name-specifier
2108 // but isn't.
2109 AddTypeLoc(E->getScopeTypeInfo());
2110 // Visit the nested-name-specifier.
2111 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2112 AddNestedNameSpecifierLoc(QualifierLoc);
2113 // Visit base expression.
2114 AddStmt(E->getBase());
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2117 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 AddTypeLoc(E->getTypeSourceInfo());
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2121 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002122 EnqueueChildren(E);
2123 AddTypeLoc(E->getTypeSourceInfo());
2124}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 EnqueueChildren(E);
2127 if (E->isTypeOperand())
2128 AddTypeLoc(E->getTypeOperandSourceInfo());
2129}
2130
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2132 const CXXUnresolvedConstructExpr *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::VisitCXXUuidofExpr(const CXXUuidofExpr *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::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 EnqueueChildren(S);
2144 AddDecl(S->getExceptionDecl());
2145}
2146
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 if (DR->hasExplicitTemplateArgs()) {
2149 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2150 }
2151 WL.push_back(DeclRefExprParts(DR, Parent));
2152}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2154 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2156 AddDeclarationNameInfo(E);
2157 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2158}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002159void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002160 unsigned size = WL.size();
2161 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002162 for (const auto *D : S->decls()) {
2163 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002164 isFirst = false;
2165 }
2166 if (size == WL.size())
2167 return;
2168 // Now reverse the entries we just added. This will match the DFS
2169 // ordering performed by the worklist.
2170 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2171 std::reverse(I, E);
2172}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002173void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002174 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 D = E->designators_rbegin(), DEnd = E->designators_rend();
2177 D != DEnd; ++D) {
2178 if (D->isFieldDesignator()) {
2179 if (FieldDecl *Field = D->getField())
2180 AddMemberRef(Field, D->getFieldLoc());
2181 continue;
2182 }
2183 if (D->isArrayDesignator()) {
2184 AddStmt(E->getArrayIndex(*D));
2185 continue;
2186 }
2187 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2188 AddStmt(E->getArrayRangeEnd(*D));
2189 AddStmt(E->getArrayRangeStart(*D));
2190 }
2191}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 EnqueueChildren(E);
2194 AddTypeLoc(E->getTypeInfoAsWritten());
2195}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002196void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 AddStmt(FS->getBody());
2198 AddStmt(FS->getInc());
2199 AddStmt(FS->getCond());
2200 AddDecl(FS->getConditionVariable());
2201 AddStmt(FS->getInit());
2202}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2205}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 AddStmt(If->getElse());
2208 AddStmt(If->getThen());
2209 AddStmt(If->getCond());
2210 AddDecl(If->getConditionVariable());
2211}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 // We care about the syntactic form of the initializer list, only.
2214 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2215 IE = Syntactic;
2216 EnqueueChildren(IE);
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 WL.push_back(MemberExprParts(M, Parent));
2220
2221 // If the base of the member access expression is an implicit 'this', don't
2222 // visit it.
2223 // FIXME: If we ever want to show these implicit accesses, this will be
2224 // unfortunate. However, clang_getCursor() relies on this behavior.
2225 if (!M->isImplicitAccess())
2226 AddStmt(M->getBase());
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 AddTypeLoc(E->getEncodedTypeSourceInfo());
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 EnqueueChildren(M);
2233 AddTypeLoc(M->getClassReceiverTypeInfo());
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 // Visit the components of the offsetof expression.
2237 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2238 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2239 const OffsetOfNode &Node = E->getComponent(I-1);
2240 switch (Node.getKind()) {
2241 case OffsetOfNode::Array:
2242 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2243 break;
2244 case OffsetOfNode::Field:
2245 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2246 break;
2247 case OffsetOfNode::Identifier:
2248 case OffsetOfNode::Base:
2249 continue;
2250 }
2251 }
2252 // Visit the type into which we're computing the offset.
2253 AddTypeLoc(E->getTypeSourceInfo());
2254}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2257 WL.push_back(OverloadExprParts(E, Parent));
2258}
2259void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 EnqueueChildren(E);
2262 if (E->isArgumentType())
2263 AddTypeLoc(E->getArgumentTypeInfo());
2264}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002265void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002266 EnqueueChildren(S);
2267}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002269 AddStmt(S->getBody());
2270 AddStmt(S->getCond());
2271 AddDecl(S->getConditionVariable());
2272}
2273
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 AddStmt(W->getBody());
2276 AddStmt(W->getCond());
2277 AddDecl(W->getConditionVariable());
2278}
2279
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 for (unsigned I = E->getNumArgs(); I > 0; --I)
2282 AddTypeLoc(E->getArg(I-1));
2283}
2284
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 AddTypeLoc(E->getQueriedTypeSourceInfo());
2287}
2288
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002289void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002290 EnqueueChildren(E);
2291}
2292
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002293void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002294 VisitOverloadExpr(U);
2295 if (!U->isImplicitAccess())
2296 AddStmt(U->getBase());
2297}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002298void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002299 AddStmt(E->getSubExpr());
2300 AddTypeLoc(E->getWrittenTypeInfo());
2301}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002302void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 WL.push_back(SizeOfPackExprParts(E, Parent));
2304}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002305void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002306 // If the opaque value has a source expression, just transparently
2307 // visit that. This is useful for (e.g.) pseudo-object expressions.
2308 if (Expr *SourceExpr = E->getSourceExpr())
2309 return Visit(SourceExpr);
2310}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002311void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 AddStmt(E->getBody());
2313 WL.push_back(LambdaExprParts(E, Parent));
2314}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002315void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 // Treat the expression like its syntactic form.
2317 Visit(E->getSyntacticForm());
2318}
2319
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002320void EnqueueVisitor::VisitOMPExecutableDirective(
2321 const OMPExecutableDirective *D) {
2322 EnqueueChildren(D);
2323 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2324 E = D->clauses().end();
2325 I != E; ++I)
2326 EnqueueChildren(*I);
2327}
2328
Alexander Musman3aaab662014-08-19 11:27:13 +00002329void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2330 VisitOMPExecutableDirective(D);
2331}
2332
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002333void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2334 VisitOMPExecutableDirective(D);
2335}
2336
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002337void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002338 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002339}
2340
Alexey Bataevf29276e2014-06-18 04:14:57 +00002341void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002342 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002343}
2344
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002345void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2346 VisitOMPExecutableDirective(D);
2347}
2348
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002349void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2350 VisitOMPExecutableDirective(D);
2351}
2352
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002353void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2354 VisitOMPExecutableDirective(D);
2355}
2356
Alexander Musman80c22892014-07-17 08:54:58 +00002357void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2358 VisitOMPExecutableDirective(D);
2359}
2360
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002361void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2362 VisitOMPExecutableDirective(D);
2363 AddDeclarationNameInfo(D);
2364}
2365
Alexey Bataev4acb8592014-07-07 13:01:15 +00002366void
2367EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002368 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002369}
2370
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002371void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2372 const OMPParallelSectionsDirective *D) {
2373 VisitOMPExecutableDirective(D);
2374}
2375
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002376void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2377 VisitOMPExecutableDirective(D);
2378}
2379
Alexey Bataev68446b72014-07-18 07:47:19 +00002380void
2381EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2382 VisitOMPExecutableDirective(D);
2383}
2384
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002385void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2386 VisitOMPExecutableDirective(D);
2387}
2388
Alexey Bataev2df347a2014-07-18 10:17:07 +00002389void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2390 VisitOMPExecutableDirective(D);
2391}
2392
Alexey Bataev6125da92014-07-21 11:26:11 +00002393void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2394 VisitOMPExecutableDirective(D);
2395}
2396
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002397void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2398 VisitOMPExecutableDirective(D);
2399}
2400
Alexey Bataev0162e452014-07-22 10:10:35 +00002401void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2402 VisitOMPExecutableDirective(D);
2403}
2404
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002405void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002406 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2407}
2408
2409bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2410 if (RegionOfInterest.isValid()) {
2411 SourceRange Range = getRawCursorExtent(C);
2412 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2413 return false;
2414 }
2415 return true;
2416}
2417
2418bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2419 while (!WL.empty()) {
2420 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002421 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002422
2423 // Set the Parent field, then back to its old value once we're done.
2424 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2425
2426 switch (LI.getKind()) {
2427 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002428 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002429 if (!D)
2430 continue;
2431
2432 // For now, perform default visitation for Decls.
2433 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2434 cast<DeclVisit>(&LI)->isFirst())))
2435 return true;
2436
2437 continue;
2438 }
2439 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2440 const ASTTemplateArgumentListInfo *ArgList =
2441 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2442 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2443 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2444 Arg != ArgEnd; ++Arg) {
2445 if (VisitTemplateArgumentLoc(*Arg))
2446 return true;
2447 }
2448 continue;
2449 }
2450 case VisitorJob::TypeLocVisitKind: {
2451 // Perform default visitation for TypeLocs.
2452 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2453 return true;
2454 continue;
2455 }
2456 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002457 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002458 if (LabelStmt *stmt = LS->getStmt()) {
2459 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2460 TU))) {
2461 return true;
2462 }
2463 }
2464 continue;
2465 }
2466
2467 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2468 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2469 if (VisitNestedNameSpecifierLoc(V->get()))
2470 return true;
2471 continue;
2472 }
2473
2474 case VisitorJob::DeclarationNameInfoVisitKind: {
2475 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2476 ->get()))
2477 return true;
2478 continue;
2479 }
2480 case VisitorJob::MemberRefVisitKind: {
2481 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2482 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2483 return true;
2484 continue;
2485 }
2486 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002487 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002488 if (!S)
2489 continue;
2490
2491 // Update the current cursor.
2492 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2493 if (!IsInRegionOfInterest(Cursor))
2494 continue;
2495 switch (Visitor(Cursor, Parent, ClientData)) {
2496 case CXChildVisit_Break: return true;
2497 case CXChildVisit_Continue: break;
2498 case CXChildVisit_Recurse:
2499 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002500 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002501 EnqueueWorkList(WL, S);
2502 break;
2503 }
2504 continue;
2505 }
2506 case VisitorJob::MemberExprPartsKind: {
2507 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002508 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002509
2510 // Visit the nested-name-specifier
2511 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2512 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2513 return true;
2514
2515 // Visit the declaration name.
2516 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2517 return true;
2518
2519 // Visit the explicitly-specified template arguments, if any.
2520 if (M->hasExplicitTemplateArgs()) {
2521 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2522 *ArgEnd = Arg + M->getNumTemplateArgs();
2523 Arg != ArgEnd; ++Arg) {
2524 if (VisitTemplateArgumentLoc(*Arg))
2525 return true;
2526 }
2527 }
2528 continue;
2529 }
2530 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002531 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002532 // Visit nested-name-specifier, if present.
2533 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2534 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2535 return true;
2536 // Visit declaration name.
2537 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2538 return true;
2539 continue;
2540 }
2541 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002542 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002543 // Visit the nested-name-specifier.
2544 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2545 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2546 return true;
2547 // Visit the declaration name.
2548 if (VisitDeclarationNameInfo(O->getNameInfo()))
2549 return true;
2550 // Visit the overloaded declaration reference.
2551 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2552 return true;
2553 continue;
2554 }
2555 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002556 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002557 NamedDecl *Pack = E->getPack();
2558 if (isa<TemplateTypeParmDecl>(Pack)) {
2559 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2560 E->getPackLoc(), TU)))
2561 return true;
2562
2563 continue;
2564 }
2565
2566 if (isa<TemplateTemplateParmDecl>(Pack)) {
2567 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2568 E->getPackLoc(), TU)))
2569 return true;
2570
2571 continue;
2572 }
2573
2574 // Non-type template parameter packs and function parameter packs are
2575 // treated like DeclRefExpr cursors.
2576 continue;
2577 }
2578
2579 case VisitorJob::LambdaExprPartsKind: {
2580 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002581 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002582 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2583 CEnd = E->explicit_capture_end();
2584 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002585 // FIXME: Lambda init-captures.
2586 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002587 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002588
Guy Benyei11169dd2012-12-18 14:30:41 +00002589 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2590 C->getLocation(),
2591 TU)))
2592 return true;
2593 }
2594
2595 // Visit parameters and return type, if present.
2596 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2597 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2598 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2599 // Visit the whole type.
2600 if (Visit(TL))
2601 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002602 } else if (FunctionProtoTypeLoc Proto =
2603 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002604 if (E->hasExplicitParameters()) {
2605 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002606 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2607 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002608 return true;
2609 } else {
2610 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002611 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002612 return true;
2613 }
2614 }
2615 }
2616 break;
2617 }
2618
2619 case VisitorJob::PostChildrenVisitKind:
2620 if (PostChildrenVisitor(Parent, ClientData))
2621 return true;
2622 break;
2623 }
2624 }
2625 return false;
2626}
2627
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002628bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002629 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002630 if (!WorkListFreeList.empty()) {
2631 WL = WorkListFreeList.back();
2632 WL->clear();
2633 WorkListFreeList.pop_back();
2634 }
2635 else {
2636 WL = new VisitorWorkList();
2637 WorkListCache.push_back(WL);
2638 }
2639 EnqueueWorkList(*WL, S);
2640 bool result = RunVisitorWorkList(*WL);
2641 WorkListFreeList.push_back(WL);
2642 return result;
2643}
2644
2645namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002646typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002647RefNamePieces
2648buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2649 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2650 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002651 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2652 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2653 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2654
2655 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2656
2657 RefNamePieces Pieces;
2658
2659 if (WantQualifier && QLoc.isValid())
2660 Pieces.push_back(QLoc);
2661
2662 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2663 Pieces.push_back(NI.getLoc());
2664
2665 if (WantTemplateArgs && TemplateArgs)
2666 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2667 TemplateArgs->RAngleLoc));
2668
2669 if (Kind == DeclarationName::CXXOperatorName) {
2670 Pieces.push_back(SourceLocation::getFromRawEncoding(
2671 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2672 Pieces.push_back(SourceLocation::getFromRawEncoding(
2673 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2674 }
2675
2676 if (WantSinglePiece) {
2677 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2678 Pieces.clear();
2679 Pieces.push_back(R);
2680 }
2681
2682 return Pieces;
2683}
2684}
2685
2686//===----------------------------------------------------------------------===//
2687// Misc. API hooks.
2688//===----------------------------------------------------------------------===//
2689
Chad Rosier05c71aa2013-03-27 18:28:23 +00002690static void fatal_error_handler(void *user_data, const std::string& reason,
2691 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002692 // Write the result out to stderr avoiding errs() because raw_ostreams can
2693 // call report_fatal_error.
2694 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2695 ::abort();
2696}
2697
Chandler Carruth66660742014-06-27 16:37:27 +00002698namespace {
2699struct RegisterFatalErrorHandler {
2700 RegisterFatalErrorHandler() {
2701 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2702 }
2703};
2704}
2705
2706static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2707
Guy Benyei11169dd2012-12-18 14:30:41 +00002708extern "C" {
2709CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2710 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002711 // We use crash recovery to make some of our APIs more reliable, implicitly
2712 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002713 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2714 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002715
Chandler Carruth66660742014-06-27 16:37:27 +00002716 // Look through the managed static to trigger construction of the managed
2717 // static which registers our fatal error handler. This ensures it is only
2718 // registered once.
2719 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002720
2721 CIndexer *CIdxr = new CIndexer();
2722 if (excludeDeclarationsFromPCH)
2723 CIdxr->setOnlyLocalDecls();
2724 if (displayDiagnostics)
2725 CIdxr->setDisplayDiagnostics();
2726
2727 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2728 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2729 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2730 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2731 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2732 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2733
2734 return CIdxr;
2735}
2736
2737void clang_disposeIndex(CXIndex CIdx) {
2738 if (CIdx)
2739 delete static_cast<CIndexer *>(CIdx);
2740}
2741
2742void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2743 if (CIdx)
2744 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2745}
2746
2747unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2748 if (CIdx)
2749 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2750 return 0;
2751}
2752
2753void clang_toggleCrashRecovery(unsigned isEnabled) {
2754 if (isEnabled)
2755 llvm::CrashRecoveryContext::Enable();
2756 else
2757 llvm::CrashRecoveryContext::Disable();
2758}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002759
Guy Benyei11169dd2012-12-18 14:30:41 +00002760CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2761 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002762 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002763 enum CXErrorCode Result =
2764 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002765 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002766 assert((TU && Result == CXError_Success) ||
2767 (!TU && Result != CXError_Success));
2768 return TU;
2769}
2770
2771enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2772 const char *ast_filename,
2773 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002774 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002775 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002776
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002777 if (!CIdx || !ast_filename || !out_TU)
2778 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002779
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002780 LOG_FUNC_SECTION {
2781 *Log << ast_filename;
2782 }
2783
Guy Benyei11169dd2012-12-18 14:30:41 +00002784 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2785 FileSystemOptions FileSystemOpts;
2786
2787 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
David Blaikie6f7382d2014-08-10 19:08:04 +00002788 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2789 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2790 /*CaptureDiagnostics=*/true,
2791 /*AllowPCHWithCompilerErrors=*/true,
2792 /*UserFilesAreVolatile=*/true);
2793 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002794 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002795}
2796
2797unsigned clang_defaultEditingTranslationUnitOptions() {
2798 return CXTranslationUnit_PrecompiledPreamble |
2799 CXTranslationUnit_CacheCompletionResults;
2800}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002801
Guy Benyei11169dd2012-12-18 14:30:41 +00002802CXTranslationUnit
2803clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2804 const char *source_filename,
2805 int num_command_line_args,
2806 const char * const *command_line_args,
2807 unsigned num_unsaved_files,
2808 struct CXUnsavedFile *unsaved_files) {
2809 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2810 return clang_parseTranslationUnit(CIdx, source_filename,
2811 command_line_args, num_command_line_args,
2812 unsaved_files, num_unsaved_files,
2813 Options);
2814}
2815
2816struct ParseTranslationUnitInfo {
2817 CXIndex CIdx;
2818 const char *source_filename;
2819 const char *const *command_line_args;
2820 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002821 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002822 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002823 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002824 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002825};
2826static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002827 const ParseTranslationUnitInfo *PTUI =
2828 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002829 CXIndex CIdx = PTUI->CIdx;
2830 const char *source_filename = PTUI->source_filename;
2831 const char * const *command_line_args = PTUI->command_line_args;
2832 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002833 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002834 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002835
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002836 // Set up the initial return values.
2837 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002838 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002839
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002840 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002841 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002842 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002843 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002844 }
2845
Guy Benyei11169dd2012-12-18 14:30:41 +00002846 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2847
2848 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2849 setThreadBackgroundPriority();
2850
2851 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2852 // FIXME: Add a flag for modules.
2853 TranslationUnitKind TUKind
2854 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002855 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 = options & CXTranslationUnit_CacheCompletionResults;
2857 bool IncludeBriefCommentsInCodeCompletion
2858 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2859 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2860 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2861
2862 // Configure the diagnostics.
2863 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002864 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002865
2866 // Recover resources if we crash before exiting this function.
2867 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2868 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002869 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002870
Ahmed Charlesb8984322014-03-07 20:03:18 +00002871 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2872 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002873
2874 // Recover resources if we crash before exiting this function.
2875 llvm::CrashRecoveryContextCleanupRegistrar<
2876 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2877
Alp Toker9d85b182014-07-07 01:23:14 +00002878 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002879 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002880 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002881 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002882 }
2883
Ahmed Charlesb8984322014-03-07 20:03:18 +00002884 std::unique_ptr<std::vector<const char *>> Args(
2885 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002886
2887 // Recover resources if we crash before exiting this method.
2888 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2889 ArgsCleanup(Args.get());
2890
2891 // Since the Clang C library is primarily used by batch tools dealing with
2892 // (often very broken) source code, where spell-checking can have a
2893 // significant negative impact on performance (particularly when
2894 // precompiled headers are involved), we disable it by default.
2895 // Only do this if we haven't found a spell-checking-related argument.
2896 bool FoundSpellCheckingArgument = false;
2897 for (int I = 0; I != num_command_line_args; ++I) {
2898 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2899 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2900 FoundSpellCheckingArgument = true;
2901 break;
2902 }
2903 }
2904 if (!FoundSpellCheckingArgument)
2905 Args->push_back("-fno-spell-checking");
2906
2907 Args->insert(Args->end(), command_line_args,
2908 command_line_args + num_command_line_args);
2909
2910 // The 'source_filename' argument is optional. If the caller does not
2911 // specify it then it is assumed that the source file is specified
2912 // in the actual argument list.
2913 // Put the source file after command_line_args otherwise if '-x' flag is
2914 // present it will be unused.
2915 if (source_filename)
2916 Args->push_back(source_filename);
2917
2918 // Do we need the detailed preprocessing record?
2919 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2920 Args->push_back("-Xclang");
2921 Args->push_back("-detailed-preprocessing-record");
2922 }
2923
2924 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002925 std::unique_ptr<ASTUnit> ErrUnit;
2926 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002927 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002928 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2929 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2930 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2931 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2932 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2933 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002934
2935 if (NumErrors != Diags->getClient()->getNumErrors()) {
2936 // Make sure to check that 'Unit' is non-NULL.
2937 if (CXXIdx->getDisplayDiagnostics())
2938 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2939 }
2940
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002941 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2942 PTUI->result = CXError_ASTReadError;
2943 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002944 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002945 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2946 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002947}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002948
2949CXTranslationUnit
2950clang_parseTranslationUnit(CXIndex CIdx,
2951 const char *source_filename,
2952 const char *const *command_line_args,
2953 int num_command_line_args,
2954 struct CXUnsavedFile *unsaved_files,
2955 unsigned num_unsaved_files,
2956 unsigned options) {
2957 CXTranslationUnit TU;
2958 enum CXErrorCode Result = clang_parseTranslationUnit2(
2959 CIdx, source_filename, command_line_args, num_command_line_args,
2960 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002961 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002962 assert((TU && Result == CXError_Success) ||
2963 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002964 return TU;
2965}
2966
2967enum CXErrorCode clang_parseTranslationUnit2(
2968 CXIndex CIdx,
2969 const char *source_filename,
2970 const char *const *command_line_args,
2971 int num_command_line_args,
2972 struct CXUnsavedFile *unsaved_files,
2973 unsigned num_unsaved_files,
2974 unsigned options,
2975 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002976 LOG_FUNC_SECTION {
2977 *Log << source_filename << ": ";
2978 for (int i = 0; i != num_command_line_args; ++i)
2979 *Log << command_line_args[i] << " ";
2980 }
2981
Alp Toker9d85b182014-07-07 01:23:14 +00002982 if (num_unsaved_files && !unsaved_files)
2983 return CXError_InvalidArguments;
2984
Alp Toker5c532982014-07-07 22:42:03 +00002985 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002986 ParseTranslationUnitInfo PTUI = {
2987 CIdx,
2988 source_filename,
2989 command_line_args,
2990 num_command_line_args,
2991 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2992 options,
2993 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002994 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002995 llvm::CrashRecoveryContext CRC;
2996
2997 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2998 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2999 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3000 fprintf(stderr, " 'command_line_args' : [");
3001 for (int i = 0; i != num_command_line_args; ++i) {
3002 if (i)
3003 fprintf(stderr, ", ");
3004 fprintf(stderr, "'%s'", command_line_args[i]);
3005 }
3006 fprintf(stderr, "],\n");
3007 fprintf(stderr, " 'unsaved_files' : [");
3008 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3009 if (i)
3010 fprintf(stderr, ", ");
3011 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3012 unsaved_files[i].Length);
3013 }
3014 fprintf(stderr, "],\n");
3015 fprintf(stderr, " 'options' : %d,\n", options);
3016 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003017
3018 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003019 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003020 if (CXTranslationUnit *TU = PTUI.out_TU)
3021 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003022 }
Alp Toker5c532982014-07-07 22:42:03 +00003023
3024 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003025}
3026
3027unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3028 return CXSaveTranslationUnit_None;
3029}
3030
3031namespace {
3032
3033struct SaveTranslationUnitInfo {
3034 CXTranslationUnit TU;
3035 const char *FileName;
3036 unsigned options;
3037 CXSaveError result;
3038};
3039
3040}
3041
3042static void clang_saveTranslationUnit_Impl(void *UserData) {
3043 SaveTranslationUnitInfo *STUI =
3044 static_cast<SaveTranslationUnitInfo*>(UserData);
3045
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003046 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003047 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3048 setThreadBackgroundPriority();
3049
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003050 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003051 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3052}
3053
3054int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3055 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003056 LOG_FUNC_SECTION {
3057 *Log << TU << ' ' << FileName;
3058 }
3059
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003060 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003061 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003062 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003063 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003064
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003065 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003066 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3067 if (!CXXUnit->hasSema())
3068 return CXSaveError_InvalidTU;
3069
3070 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3071
3072 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3073 getenv("LIBCLANG_NOTHREADS")) {
3074 clang_saveTranslationUnit_Impl(&STUI);
3075
3076 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3077 PrintLibclangResourceUsage(TU);
3078
3079 return STUI.result;
3080 }
3081
3082 // We have an AST that has invalid nodes due to compiler errors.
3083 // Use a crash recovery thread for protection.
3084
3085 llvm::CrashRecoveryContext CRC;
3086
3087 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3088 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3089 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3090 fprintf(stderr, " 'options' : %d,\n", options);
3091 fprintf(stderr, "}\n");
3092
3093 return CXSaveError_Unknown;
3094
3095 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3096 PrintLibclangResourceUsage(TU);
3097 }
3098
3099 return STUI.result;
3100}
3101
3102void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3103 if (CTUnit) {
3104 // If the translation unit has been marked as unsafe to free, just discard
3105 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003106 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3107 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003108 return;
3109
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003110 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003111 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003112 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3113 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003114 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003115 delete CTUnit;
3116 }
3117}
3118
3119unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3120 return CXReparse_None;
3121}
3122
3123struct ReparseTranslationUnitInfo {
3124 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003125 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003127 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003128};
3129
3130static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003131 const ReparseTranslationUnitInfo *RTUI =
3132 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003133 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003134 unsigned options = RTUI->options;
3135 (void) options;
3136
3137 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003138 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003139 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003140 RTUI->result = CXError_InvalidArguments;
3141 return;
3142 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003143
3144 // Reset the associated diagnostics.
3145 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003146 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003147
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003148 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3150 setThreadBackgroundPriority();
3151
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003152 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003153 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003154
3155 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3156 new std::vector<ASTUnit::RemappedFile>());
3157
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 // Recover resources if we crash before exiting this function.
3159 llvm::CrashRecoveryContextCleanupRegistrar<
3160 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003161
3162 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003163 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003164 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003165 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003166 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003167
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003168 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003169 RTUI->result = CXError_Success;
3170 else if (isASTReadError(CXXUnit))
3171 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003172}
3173
3174int clang_reparseTranslationUnit(CXTranslationUnit TU,
3175 unsigned num_unsaved_files,
3176 struct CXUnsavedFile *unsaved_files,
3177 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003178 LOG_FUNC_SECTION {
3179 *Log << TU;
3180 }
3181
Alp Toker9d85b182014-07-07 01:23:14 +00003182 if (num_unsaved_files && !unsaved_files)
3183 return CXError_InvalidArguments;
3184
Alp Toker5c532982014-07-07 22:42:03 +00003185 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003186 ReparseTranslationUnitInfo RTUI = {
3187 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003188 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003189
3190 if (getenv("LIBCLANG_NOTHREADS")) {
3191 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003192 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003193 }
3194
3195 llvm::CrashRecoveryContext CRC;
3196
3197 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3198 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003199 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003200 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3202 PrintLibclangResourceUsage(TU);
3203
Alp Toker5c532982014-07-07 22:42:03 +00003204 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003205}
3206
3207
3208CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003209 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003210 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003211 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003212 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003213
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003214 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003215 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003216}
3217
3218CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003219 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003220 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003221 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003222 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003223
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003224 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3226}
3227
3228} // end: extern "C"
3229
3230//===----------------------------------------------------------------------===//
3231// CXFile Operations.
3232//===----------------------------------------------------------------------===//
3233
3234extern "C" {
3235CXString clang_getFileName(CXFile SFile) {
3236 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003237 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003238
3239 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003240 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003241}
3242
3243time_t clang_getFileTime(CXFile SFile) {
3244 if (!SFile)
3245 return 0;
3246
3247 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3248 return FEnt->getModificationTime();
3249}
3250
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003251CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003252 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003253 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003254 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003255 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003256
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003257 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003258
3259 FileManager &FMgr = CXXUnit->getFileManager();
3260 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3261}
3262
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003263unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3264 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003265 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003266 LOG_BAD_TU(TU);
3267 return 0;
3268 }
3269
3270 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 return 0;
3272
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003273 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003274 FileEntry *FEnt = static_cast<FileEntry *>(file);
3275 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3276 .isFileMultipleIncludeGuarded(FEnt);
3277}
3278
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003279int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3280 if (!file || !outID)
3281 return 1;
3282
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003283 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003284 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3285 outID->data[0] = ID.getDevice();
3286 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003287 outID->data[2] = FEnt->getModificationTime();
3288 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003289}
3290
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003291int clang_File_isEqual(CXFile file1, CXFile file2) {
3292 if (file1 == file2)
3293 return true;
3294
3295 if (!file1 || !file2)
3296 return false;
3297
3298 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3299 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3300 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3301}
3302
Guy Benyei11169dd2012-12-18 14:30:41 +00003303} // end: extern "C"
3304
3305//===----------------------------------------------------------------------===//
3306// CXCursor Operations.
3307//===----------------------------------------------------------------------===//
3308
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003309static const Decl *getDeclFromExpr(const Stmt *E) {
3310 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 return getDeclFromExpr(CE->getSubExpr());
3312
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003313 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003315 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003317 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003319 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003320 if (PRE->isExplicitProperty())
3321 return PRE->getExplicitProperty();
3322 // It could be messaging both getter and setter as in:
3323 // ++myobj.myprop;
3324 // in which case prefer to associate the setter since it is less obvious
3325 // from inspecting the source that the setter is going to get called.
3326 if (PRE->isMessagingSetter())
3327 return PRE->getImplicitPropertySetter();
3328 return PRE->getImplicitPropertyGetter();
3329 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003330 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003332 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 if (Expr *Src = OVE->getSourceExpr())
3334 return getDeclFromExpr(Src);
3335
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003336 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003338 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 if (!CE->isElidable())
3340 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003341 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 return OME->getMethodDecl();
3343
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003344 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003346 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3348 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003349 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3351 isa<ParmVarDecl>(SizeOfPack->getPack()))
3352 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003353
3354 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003355}
3356
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003357static SourceLocation getLocationFromExpr(const Expr *E) {
3358 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 return getLocationFromExpr(CE->getSubExpr());
3360
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003361 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003363 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003365 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003367 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003369 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003371 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 return PropRef->getLocation();
3373
3374 return E->getLocStart();
3375}
3376
3377extern "C" {
3378
3379unsigned clang_visitChildren(CXCursor parent,
3380 CXCursorVisitor visitor,
3381 CXClientData client_data) {
3382 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3383 /*VisitPreprocessorLast=*/false);
3384 return CursorVis.VisitChildren(parent);
3385}
3386
3387#ifndef __has_feature
3388#define __has_feature(x) 0
3389#endif
3390#if __has_feature(blocks)
3391typedef enum CXChildVisitResult
3392 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3393
3394static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3395 CXClientData client_data) {
3396 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3397 return block(cursor, parent);
3398}
3399#else
3400// If we are compiled with a compiler that doesn't have native blocks support,
3401// define and call the block manually, so the
3402typedef struct _CXChildVisitResult
3403{
3404 void *isa;
3405 int flags;
3406 int reserved;
3407 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3408 CXCursor);
3409} *CXCursorVisitorBlock;
3410
3411static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3412 CXClientData client_data) {
3413 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3414 return block->invoke(block, cursor, parent);
3415}
3416#endif
3417
3418
3419unsigned clang_visitChildrenWithBlock(CXCursor parent,
3420 CXCursorVisitorBlock block) {
3421 return clang_visitChildren(parent, visitWithBlock, block);
3422}
3423
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003424static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003426 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003427
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003428 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003430 if (const ObjCPropertyImplDecl *PropImpl =
3431 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003433 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003434
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003435 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003437 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003438
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003439 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 }
3441
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003442 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003443 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003444
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003445 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3447 // and returns different names. NamedDecl returns the class name and
3448 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003449 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003450
3451 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003452 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003453
3454 SmallString<1024> S;
3455 llvm::raw_svector_ostream os(S);
3456 ND->printName(os);
3457
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003458 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003459}
3460
3461CXString clang_getCursorSpelling(CXCursor C) {
3462 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003463 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003464
3465 if (clang_isReference(C.kind)) {
3466 switch (C.kind) {
3467 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003468 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003469 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 }
3471 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003472 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003473 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 }
3475 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003476 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003477 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003478 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 }
3480 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003481 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003482 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 }
3484 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003485 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 assert(Type && "Missing type decl");
3487
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003488 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 getAsString());
3490 }
3491 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003492 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 assert(Template && "Missing template decl");
3494
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003495 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 }
3497
3498 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003499 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 assert(NS && "Missing namespace decl");
3501
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003502 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003503 }
3504
3505 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003506 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 assert(Field && "Missing member decl");
3508
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003509 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 }
3511
3512 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003513 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 assert(Label && "Missing label");
3515
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003516 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 }
3518
3519 case CXCursor_OverloadedDeclRef: {
3520 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003521 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3522 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003523 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003524 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003525 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003526 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003527 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 OverloadedTemplateStorage *Ovl
3529 = Storage.get<OverloadedTemplateStorage*>();
3530 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003531 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003532 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 }
3534
3535 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003536 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 assert(Var && "Missing variable decl");
3538
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003539 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 }
3541
3542 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003543 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 }
3545 }
3546
3547 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003548 const Expr *E = getCursorExpr(C);
3549
3550 if (C.kind == CXCursor_ObjCStringLiteral ||
3551 C.kind == CXCursor_StringLiteral) {
3552 const StringLiteral *SLit;
3553 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3554 SLit = OSL->getString();
3555 } else {
3556 SLit = cast<StringLiteral>(E);
3557 }
3558 SmallString<256> Buf;
3559 llvm::raw_svector_ostream OS(Buf);
3560 SLit->outputString(OS);
3561 return cxstring::createDup(OS.str());
3562 }
3563
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003564 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 if (D)
3566 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003567 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 }
3569
3570 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003571 const Stmt *S = getCursorStmt(C);
3572 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003573 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003574
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003575 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 }
3577
3578 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003579 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 ->getNameStart());
3581
3582 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003583 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003584 ->getNameStart());
3585
3586 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003587 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003588
3589 if (clang_isDeclaration(C.kind))
3590 return getDeclSpelling(getCursorDecl(C));
3591
3592 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003593 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003594 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 }
3596
3597 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003598 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003599 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 }
3601
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003602 if (C.kind == CXCursor_PackedAttr) {
3603 return cxstring::createRef("packed");
3604 }
3605
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003606 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003607}
3608
3609CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3610 unsigned pieceIndex,
3611 unsigned options) {
3612 if (clang_Cursor_isNull(C))
3613 return clang_getNullRange();
3614
3615 ASTContext &Ctx = getCursorContext(C);
3616
3617 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003618 const Stmt *S = getCursorStmt(C);
3619 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 if (pieceIndex > 0)
3621 return clang_getNullRange();
3622 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3623 }
3624
3625 return clang_getNullRange();
3626 }
3627
3628 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003629 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3631 if (pieceIndex >= ME->getNumSelectorLocs())
3632 return clang_getNullRange();
3633 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3634 }
3635 }
3636
3637 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3638 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003639 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3641 if (pieceIndex >= MD->getNumSelectorLocs())
3642 return clang_getNullRange();
3643 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3644 }
3645 }
3646
3647 if (C.kind == CXCursor_ObjCCategoryDecl ||
3648 C.kind == CXCursor_ObjCCategoryImplDecl) {
3649 if (pieceIndex > 0)
3650 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003651 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3653 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003654 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3656 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3657 }
3658
3659 if (C.kind == CXCursor_ModuleImportDecl) {
3660 if (pieceIndex > 0)
3661 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003662 if (const ImportDecl *ImportD =
3663 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3665 if (!Locs.empty())
3666 return cxloc::translateSourceRange(Ctx,
3667 SourceRange(Locs.front(), Locs.back()));
3668 }
3669 return clang_getNullRange();
3670 }
3671
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003672 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3673 C.kind == CXCursor_ConversionFunction) {
3674 if (pieceIndex > 0)
3675 return clang_getNullRange();
3676 if (const FunctionDecl *FD =
3677 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3678 DeclarationNameInfo FunctionName = FD->getNameInfo();
3679 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3680 }
3681 return clang_getNullRange();
3682 }
3683
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 // FIXME: A CXCursor_InclusionDirective should give the location of the
3685 // filename, but we don't keep track of this.
3686
3687 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3688 // but we don't keep track of this.
3689
3690 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3691 // but we don't keep track of this.
3692
3693 // Default handling, give the location of the cursor.
3694
3695 if (pieceIndex > 0)
3696 return clang_getNullRange();
3697
3698 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3699 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3700 return cxloc::translateSourceRange(Ctx, Loc);
3701}
3702
Eli Bendersky44a206f2014-07-31 18:04:56 +00003703CXString clang_Cursor_getMangling(CXCursor C) {
3704 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3705 return cxstring::createEmpty();
3706
Eli Bendersky44a206f2014-07-31 18:04:56 +00003707 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003708 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003709 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3710 return cxstring::createEmpty();
3711
Eli Bendersky79759592014-08-01 15:01:10 +00003712 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003713 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003714 ASTContext &Ctx = ND->getASTContext();
3715 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003716
Eli Bendersky79759592014-08-01 15:01:10 +00003717 std::string FrontendBuf;
3718 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3719 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003720
Eli Bendersky79759592014-08-01 15:01:10 +00003721 // Now apply backend mangling.
3722 std::unique_ptr<llvm::DataLayout> DL(
3723 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3724 llvm::Mangler BackendMangler(DL.get());
3725
3726 std::string FinalBuf;
3727 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3728 BackendMangler.getNameWithPrefix(FinalBufOS,
3729 llvm::Twine(FrontendBufOS.str()));
3730
3731 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003732}
3733
Guy Benyei11169dd2012-12-18 14:30:41 +00003734CXString clang_getCursorDisplayName(CXCursor C) {
3735 if (!clang_isDeclaration(C.kind))
3736 return clang_getCursorSpelling(C);
3737
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003738 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003740 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003741
3742 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003743 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 D = FunTmpl->getTemplatedDecl();
3745
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003746 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 SmallString<64> Str;
3748 llvm::raw_svector_ostream OS(Str);
3749 OS << *Function;
3750 if (Function->getPrimaryTemplate())
3751 OS << "<>";
3752 OS << "(";
3753 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3754 if (I)
3755 OS << ", ";
3756 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3757 }
3758
3759 if (Function->isVariadic()) {
3760 if (Function->getNumParams())
3761 OS << ", ";
3762 OS << "...";
3763 }
3764 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003765 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 }
3767
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003768 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 SmallString<64> Str;
3770 llvm::raw_svector_ostream OS(Str);
3771 OS << *ClassTemplate;
3772 OS << "<";
3773 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3774 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3775 if (I)
3776 OS << ", ";
3777
3778 NamedDecl *Param = Params->getParam(I);
3779 if (Param->getIdentifier()) {
3780 OS << Param->getIdentifier()->getName();
3781 continue;
3782 }
3783
3784 // There is no parameter name, which makes this tricky. Try to come up
3785 // with something useful that isn't too long.
3786 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3787 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3788 else if (NonTypeTemplateParmDecl *NTTP
3789 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3790 OS << NTTP->getType().getAsString(Policy);
3791 else
3792 OS << "template<...> class";
3793 }
3794
3795 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003796 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 }
3798
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003799 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3801 // If the type was explicitly written, use that.
3802 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003803 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003804
Benjamin Kramer9170e912013-02-22 15:46:01 +00003805 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 llvm::raw_svector_ostream OS(Str);
3807 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003808 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 ClassSpec->getTemplateArgs().data(),
3810 ClassSpec->getTemplateArgs().size(),
3811 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003812 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 }
3814
3815 return clang_getCursorSpelling(C);
3816}
3817
3818CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3819 switch (Kind) {
3820 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003943 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003945 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003947 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003948 case CXCursor_ObjCSelfExpr:
3949 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003951 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003953 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003955 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003957 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003959 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003961 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003963 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003965 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003967 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003969 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003971 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003973 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003975 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003977 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003979 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003981 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003983 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003985 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003987 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003989 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003991 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003993 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003995 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003997 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003998 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003999 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004001 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004003 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004005 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004007 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004009 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004011 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004012 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004013 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004014 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004015 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004017 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004019 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004021 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004023 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004025 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004027 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004029 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004031 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004033 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004035 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004037 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004038 case CXCursor_SEHLeaveStmt:
4039 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004041 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004043 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004045 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004047 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004049 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004051 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004053 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004055 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004057 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004059 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004061 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004063 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004065 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004067 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004068 case CXCursor_PackedAttr:
4069 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004070 case CXCursor_PureAttr:
4071 return cxstring::createRef("attribute(pure)");
4072 case CXCursor_ConstAttr:
4073 return cxstring::createRef("attribute(const)");
4074 case CXCursor_NoDuplicateAttr:
4075 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004076 case CXCursor_CUDAConstantAttr:
4077 return cxstring::createRef("attribute(constant)");
4078 case CXCursor_CUDADeviceAttr:
4079 return cxstring::createRef("attribute(device)");
4080 case CXCursor_CUDAGlobalAttr:
4081 return cxstring::createRef("attribute(global)");
4082 case CXCursor_CUDAHostAttr:
4083 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004084 case CXCursor_CUDASharedAttr:
4085 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004087 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004089 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004093 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004097 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004099 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004101 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004103 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004105 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004107 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004109 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004111 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004115 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004117 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004121 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004123 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004125 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004127 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004129 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004131 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004134 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004135 return cxstring::createRef("OMPParallelDirective");
4136 case CXCursor_OMPSimdDirective:
4137 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004138 case CXCursor_OMPForDirective:
4139 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004140 case CXCursor_OMPSectionsDirective:
4141 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004142 case CXCursor_OMPSectionDirective:
4143 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004144 case CXCursor_OMPSingleDirective:
4145 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004146 case CXCursor_OMPMasterDirective:
4147 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004148 case CXCursor_OMPCriticalDirective:
4149 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004150 case CXCursor_OMPParallelForDirective:
4151 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004152 case CXCursor_OMPParallelSectionsDirective:
4153 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004154 case CXCursor_OMPTaskDirective:
4155 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004156 case CXCursor_OMPTaskyieldDirective:
4157 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004158 case CXCursor_OMPBarrierDirective:
4159 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004160 case CXCursor_OMPTaskwaitDirective:
4161 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004162 case CXCursor_OMPFlushDirective:
4163 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004164 case CXCursor_OMPOrderedDirective:
4165 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004166 case CXCursor_OMPAtomicDirective:
4167 return cxstring::createRef("OMPAtomicDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 }
4169
4170 llvm_unreachable("Unhandled CXCursorKind");
4171}
4172
4173struct GetCursorData {
4174 SourceLocation TokenBeginLoc;
4175 bool PointsAtMacroArgExpansion;
4176 bool VisitedObjCPropertyImplDecl;
4177 SourceLocation VisitedDeclaratorDeclStartLoc;
4178 CXCursor &BestCursor;
4179
4180 GetCursorData(SourceManager &SM,
4181 SourceLocation tokenBegin, CXCursor &outputCursor)
4182 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4183 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4184 VisitedObjCPropertyImplDecl = false;
4185 }
4186};
4187
4188static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4189 CXCursor parent,
4190 CXClientData client_data) {
4191 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4192 CXCursor *BestCursor = &Data->BestCursor;
4193
4194 // If we point inside a macro argument we should provide info of what the
4195 // token is so use the actual cursor, don't replace it with a macro expansion
4196 // cursor.
4197 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4198 return CXChildVisit_Recurse;
4199
4200 if (clang_isDeclaration(cursor.kind)) {
4201 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004202 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4204 if (MD->isImplicit())
4205 return CXChildVisit_Break;
4206
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004207 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4209 // Check that when we have multiple @class references in the same line,
4210 // that later ones do not override the previous ones.
4211 // If we have:
4212 // @class Foo, Bar;
4213 // source ranges for both start at '@', so 'Bar' will end up overriding
4214 // 'Foo' even though the cursor location was at 'Foo'.
4215 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4216 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004217 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4219 if (PrevID != ID &&
4220 !PrevID->isThisDeclarationADefinition() &&
4221 !ID->isThisDeclarationADefinition())
4222 return CXChildVisit_Break;
4223 }
4224
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004225 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4227 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4228 // Check that when we have multiple declarators in the same line,
4229 // that later ones do not override the previous ones.
4230 // If we have:
4231 // int Foo, Bar;
4232 // source ranges for both start at 'int', so 'Bar' will end up overriding
4233 // 'Foo' even though the cursor location was at 'Foo'.
4234 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4235 return CXChildVisit_Break;
4236 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4237
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004238 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4240 (void)PropImp;
4241 // Check that when we have multiple @synthesize in the same line,
4242 // that later ones do not override the previous ones.
4243 // If we have:
4244 // @synthesize Foo, Bar;
4245 // source ranges for both start at '@', so 'Bar' will end up overriding
4246 // 'Foo' even though the cursor location was at 'Foo'.
4247 if (Data->VisitedObjCPropertyImplDecl)
4248 return CXChildVisit_Break;
4249 Data->VisitedObjCPropertyImplDecl = true;
4250 }
4251 }
4252
4253 if (clang_isExpression(cursor.kind) &&
4254 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004255 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 // Avoid having the cursor of an expression replace the declaration cursor
4257 // when the expression source range overlaps the declaration range.
4258 // This can happen for C++ constructor expressions whose range generally
4259 // include the variable declaration, e.g.:
4260 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4261 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4262 D->getLocation() == Data->TokenBeginLoc)
4263 return CXChildVisit_Break;
4264 }
4265 }
4266
4267 // If our current best cursor is the construction of a temporary object,
4268 // don't replace that cursor with a type reference, because we want
4269 // clang_getCursor() to point at the constructor.
4270 if (clang_isExpression(BestCursor->kind) &&
4271 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4272 cursor.kind == CXCursor_TypeRef) {
4273 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4274 // as having the actual point on the type reference.
4275 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4276 return CXChildVisit_Recurse;
4277 }
4278
4279 *BestCursor = cursor;
4280 return CXChildVisit_Recurse;
4281}
4282
4283CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004284 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004285 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004287 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004288
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004289 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4291
4292 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4293 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4294
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004295 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 CXFile SearchFile;
4297 unsigned SearchLine, SearchColumn;
4298 CXFile ResultFile;
4299 unsigned ResultLine, ResultColumn;
4300 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4301 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4302 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004303
4304 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4305 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004306 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004307 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 SearchFileName = clang_getFileName(SearchFile);
4309 ResultFileName = clang_getFileName(ResultFile);
4310 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4311 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004312 *Log << llvm::format("(%s:%d:%d) = %s",
4313 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4314 clang_getCString(KindSpelling))
4315 << llvm::format("(%s:%d:%d):%s%s",
4316 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4317 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 clang_disposeString(SearchFileName);
4319 clang_disposeString(ResultFileName);
4320 clang_disposeString(KindSpelling);
4321 clang_disposeString(USR);
4322
4323 CXCursor Definition = clang_getCursorDefinition(Result);
4324 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4325 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4326 CXString DefinitionKindSpelling
4327 = clang_getCursorKindSpelling(Definition.kind);
4328 CXFile DefinitionFile;
4329 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004330 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004331 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004333 *Log << llvm::format(" -> %s(%s:%d:%d)",
4334 clang_getCString(DefinitionKindSpelling),
4335 clang_getCString(DefinitionFileName),
4336 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004337 clang_disposeString(DefinitionFileName);
4338 clang_disposeString(DefinitionKindSpelling);
4339 }
4340 }
4341
4342 return Result;
4343}
4344
4345CXCursor clang_getNullCursor(void) {
4346 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4347}
4348
4349unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004350 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4351 // can't set consistently. For example, when visiting a DeclStmt we will set
4352 // it but we don't set it on the result of clang_getCursorDefinition for
4353 // a reference of the same declaration.
4354 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4355 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4356 // to provide that kind of info.
4357 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004358 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004359 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004360 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004361
Guy Benyei11169dd2012-12-18 14:30:41 +00004362 return X == Y;
4363}
4364
4365unsigned clang_hashCursor(CXCursor C) {
4366 unsigned Index = 0;
4367 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4368 Index = 1;
4369
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004370 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004371 std::make_pair(C.kind, C.data[Index]));
4372}
4373
4374unsigned clang_isInvalid(enum CXCursorKind K) {
4375 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4376}
4377
4378unsigned clang_isDeclaration(enum CXCursorKind K) {
4379 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4380 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4381}
4382
4383unsigned clang_isReference(enum CXCursorKind K) {
4384 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4385}
4386
4387unsigned clang_isExpression(enum CXCursorKind K) {
4388 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4389}
4390
4391unsigned clang_isStatement(enum CXCursorKind K) {
4392 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4393}
4394
4395unsigned clang_isAttribute(enum CXCursorKind K) {
4396 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4397}
4398
4399unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4400 return K == CXCursor_TranslationUnit;
4401}
4402
4403unsigned clang_isPreprocessing(enum CXCursorKind K) {
4404 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4405}
4406
4407unsigned clang_isUnexposed(enum CXCursorKind K) {
4408 switch (K) {
4409 case CXCursor_UnexposedDecl:
4410 case CXCursor_UnexposedExpr:
4411 case CXCursor_UnexposedStmt:
4412 case CXCursor_UnexposedAttr:
4413 return true;
4414 default:
4415 return false;
4416 }
4417}
4418
4419CXCursorKind clang_getCursorKind(CXCursor C) {
4420 return C.kind;
4421}
4422
4423CXSourceLocation clang_getCursorLocation(CXCursor C) {
4424 if (clang_isReference(C.kind)) {
4425 switch (C.kind) {
4426 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004427 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 = getCursorObjCSuperClassRef(C);
4429 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4430 }
4431
4432 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004433 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 = getCursorObjCProtocolRef(C);
4435 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4436 }
4437
4438 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004439 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 = getCursorObjCClassRef(C);
4441 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4442 }
4443
4444 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004445 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4447 }
4448
4449 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004450 std::pair<const TemplateDecl *, SourceLocation> P =
4451 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4453 }
4454
4455 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004456 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4458 }
4459
4460 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004461 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004462 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4463 }
4464
4465 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004466 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4468 }
4469
4470 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004471 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 if (!BaseSpec)
4473 return clang_getNullLocation();
4474
4475 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4476 return cxloc::translateSourceLocation(getCursorContext(C),
4477 TSInfo->getTypeLoc().getBeginLoc());
4478
4479 return cxloc::translateSourceLocation(getCursorContext(C),
4480 BaseSpec->getLocStart());
4481 }
4482
4483 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004484 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4486 }
4487
4488 case CXCursor_OverloadedDeclRef:
4489 return cxloc::translateSourceLocation(getCursorContext(C),
4490 getCursorOverloadedDeclRef(C).second);
4491
4492 default:
4493 // FIXME: Need a way to enumerate all non-reference cases.
4494 llvm_unreachable("Missed a reference kind");
4495 }
4496 }
4497
4498 if (clang_isExpression(C.kind))
4499 return cxloc::translateSourceLocation(getCursorContext(C),
4500 getLocationFromExpr(getCursorExpr(C)));
4501
4502 if (clang_isStatement(C.kind))
4503 return cxloc::translateSourceLocation(getCursorContext(C),
4504 getCursorStmt(C)->getLocStart());
4505
4506 if (C.kind == CXCursor_PreprocessingDirective) {
4507 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4508 return cxloc::translateSourceLocation(getCursorContext(C), L);
4509 }
4510
4511 if (C.kind == CXCursor_MacroExpansion) {
4512 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004513 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 return cxloc::translateSourceLocation(getCursorContext(C), L);
4515 }
4516
4517 if (C.kind == CXCursor_MacroDefinition) {
4518 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4519 return cxloc::translateSourceLocation(getCursorContext(C), L);
4520 }
4521
4522 if (C.kind == CXCursor_InclusionDirective) {
4523 SourceLocation L
4524 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4525 return cxloc::translateSourceLocation(getCursorContext(C), L);
4526 }
4527
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004528 if (clang_isAttribute(C.kind)) {
4529 SourceLocation L
4530 = cxcursor::getCursorAttr(C)->getLocation();
4531 return cxloc::translateSourceLocation(getCursorContext(C), L);
4532 }
4533
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 if (!clang_isDeclaration(C.kind))
4535 return clang_getNullLocation();
4536
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004537 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 if (!D)
4539 return clang_getNullLocation();
4540
4541 SourceLocation Loc = D->getLocation();
4542 // FIXME: Multiple variables declared in a single declaration
4543 // currently lack the information needed to correctly determine their
4544 // ranges when accounting for the type-specifier. We use context
4545 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4546 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004547 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 if (!cxcursor::isFirstInDeclGroup(C))
4549 Loc = VD->getLocation();
4550 }
4551
4552 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004553 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 Loc = MD->getSelectorStartLoc();
4555
4556 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4557}
4558
4559} // end extern "C"
4560
4561CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4562 assert(TU);
4563
4564 // Guard against an invalid SourceLocation, or we may assert in one
4565 // of the following calls.
4566 if (SLoc.isInvalid())
4567 return clang_getNullCursor();
4568
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004569 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004570
4571 // Translate the given source location to make it point at the beginning of
4572 // the token under the cursor.
4573 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4574 CXXUnit->getASTContext().getLangOpts());
4575
4576 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4577 if (SLoc.isValid()) {
4578 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4579 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4580 /*VisitPreprocessorLast=*/true,
4581 /*VisitIncludedEntities=*/false,
4582 SourceLocation(SLoc));
4583 CursorVis.visitFileRegion();
4584 }
4585
4586 return Result;
4587}
4588
4589static SourceRange getRawCursorExtent(CXCursor C) {
4590 if (clang_isReference(C.kind)) {
4591 switch (C.kind) {
4592 case CXCursor_ObjCSuperClassRef:
4593 return getCursorObjCSuperClassRef(C).second;
4594
4595 case CXCursor_ObjCProtocolRef:
4596 return getCursorObjCProtocolRef(C).second;
4597
4598 case CXCursor_ObjCClassRef:
4599 return getCursorObjCClassRef(C).second;
4600
4601 case CXCursor_TypeRef:
4602 return getCursorTypeRef(C).second;
4603
4604 case CXCursor_TemplateRef:
4605 return getCursorTemplateRef(C).second;
4606
4607 case CXCursor_NamespaceRef:
4608 return getCursorNamespaceRef(C).second;
4609
4610 case CXCursor_MemberRef:
4611 return getCursorMemberRef(C).second;
4612
4613 case CXCursor_CXXBaseSpecifier:
4614 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4615
4616 case CXCursor_LabelRef:
4617 return getCursorLabelRef(C).second;
4618
4619 case CXCursor_OverloadedDeclRef:
4620 return getCursorOverloadedDeclRef(C).second;
4621
4622 case CXCursor_VariableRef:
4623 return getCursorVariableRef(C).second;
4624
4625 default:
4626 // FIXME: Need a way to enumerate all non-reference cases.
4627 llvm_unreachable("Missed a reference kind");
4628 }
4629 }
4630
4631 if (clang_isExpression(C.kind))
4632 return getCursorExpr(C)->getSourceRange();
4633
4634 if (clang_isStatement(C.kind))
4635 return getCursorStmt(C)->getSourceRange();
4636
4637 if (clang_isAttribute(C.kind))
4638 return getCursorAttr(C)->getRange();
4639
4640 if (C.kind == CXCursor_PreprocessingDirective)
4641 return cxcursor::getCursorPreprocessingDirective(C);
4642
4643 if (C.kind == CXCursor_MacroExpansion) {
4644 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004645 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 return TU->mapRangeFromPreamble(Range);
4647 }
4648
4649 if (C.kind == CXCursor_MacroDefinition) {
4650 ASTUnit *TU = getCursorASTUnit(C);
4651 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4652 return TU->mapRangeFromPreamble(Range);
4653 }
4654
4655 if (C.kind == CXCursor_InclusionDirective) {
4656 ASTUnit *TU = getCursorASTUnit(C);
4657 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4658 return TU->mapRangeFromPreamble(Range);
4659 }
4660
4661 if (C.kind == CXCursor_TranslationUnit) {
4662 ASTUnit *TU = getCursorASTUnit(C);
4663 FileID MainID = TU->getSourceManager().getMainFileID();
4664 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4665 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4666 return SourceRange(Start, End);
4667 }
4668
4669 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004670 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 if (!D)
4672 return SourceRange();
4673
4674 SourceRange R = D->getSourceRange();
4675 // FIXME: Multiple variables declared in a single declaration
4676 // currently lack the information needed to correctly determine their
4677 // ranges when accounting for the type-specifier. We use context
4678 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4679 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004680 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 if (!cxcursor::isFirstInDeclGroup(C))
4682 R.setBegin(VD->getLocation());
4683 }
4684 return R;
4685 }
4686 return SourceRange();
4687}
4688
4689/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4690/// the decl-specifier-seq for declarations.
4691static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4692 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004693 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004694 if (!D)
4695 return SourceRange();
4696
4697 SourceRange R = D->getSourceRange();
4698
4699 // Adjust the start of the location for declarations preceded by
4700 // declaration specifiers.
4701 SourceLocation StartLoc;
4702 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4703 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4704 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004705 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004706 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4707 StartLoc = TI->getTypeLoc().getLocStart();
4708 }
4709
4710 if (StartLoc.isValid() && R.getBegin().isValid() &&
4711 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4712 R.setBegin(StartLoc);
4713
4714 // FIXME: Multiple variables declared in a single declaration
4715 // currently lack the information needed to correctly determine their
4716 // ranges when accounting for the type-specifier. We use context
4717 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4718 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004719 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004720 if (!cxcursor::isFirstInDeclGroup(C))
4721 R.setBegin(VD->getLocation());
4722 }
4723
4724 return R;
4725 }
4726
4727 return getRawCursorExtent(C);
4728}
4729
4730extern "C" {
4731
4732CXSourceRange clang_getCursorExtent(CXCursor C) {
4733 SourceRange R = getRawCursorExtent(C);
4734 if (R.isInvalid())
4735 return clang_getNullRange();
4736
4737 return cxloc::translateSourceRange(getCursorContext(C), R);
4738}
4739
4740CXCursor clang_getCursorReferenced(CXCursor C) {
4741 if (clang_isInvalid(C.kind))
4742 return clang_getNullCursor();
4743
4744 CXTranslationUnit tu = getCursorTU(C);
4745 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004746 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 if (!D)
4748 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004749 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004751 if (const ObjCPropertyImplDecl *PropImpl =
4752 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4754 return MakeCXCursor(Property, tu);
4755
4756 return C;
4757 }
4758
4759 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004760 const Expr *E = getCursorExpr(C);
4761 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004762 if (D) {
4763 CXCursor declCursor = MakeCXCursor(D, tu);
4764 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4765 declCursor);
4766 return declCursor;
4767 }
4768
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004769 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 return MakeCursorOverloadedDeclRef(Ovl, tu);
4771
4772 return clang_getNullCursor();
4773 }
4774
4775 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004776 const Stmt *S = getCursorStmt(C);
4777 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004778 if (LabelDecl *label = Goto->getLabel())
4779 if (LabelStmt *labelS = label->getStmt())
4780 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4781
4782 return clang_getNullCursor();
4783 }
4784
4785 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004786 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 return MakeMacroDefinitionCursor(Def, tu);
4788 }
4789
4790 if (!clang_isReference(C.kind))
4791 return clang_getNullCursor();
4792
4793 switch (C.kind) {
4794 case CXCursor_ObjCSuperClassRef:
4795 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4796
4797 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004798 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4799 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004800 return MakeCXCursor(Def, tu);
4801
4802 return MakeCXCursor(Prot, tu);
4803 }
4804
4805 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004806 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4807 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004808 return MakeCXCursor(Def, tu);
4809
4810 return MakeCXCursor(Class, tu);
4811 }
4812
4813 case CXCursor_TypeRef:
4814 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4815
4816 case CXCursor_TemplateRef:
4817 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4818
4819 case CXCursor_NamespaceRef:
4820 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4821
4822 case CXCursor_MemberRef:
4823 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4824
4825 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004826 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004827 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4828 tu ));
4829 }
4830
4831 case CXCursor_LabelRef:
4832 // FIXME: We end up faking the "parent" declaration here because we
4833 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004834 return MakeCXCursor(getCursorLabelRef(C).first,
4835 cxtu::getASTUnit(tu)->getASTContext()
4836 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 tu);
4838
4839 case CXCursor_OverloadedDeclRef:
4840 return C;
4841
4842 case CXCursor_VariableRef:
4843 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4844
4845 default:
4846 // We would prefer to enumerate all non-reference cursor kinds here.
4847 llvm_unreachable("Unhandled reference cursor kind");
4848 }
4849}
4850
4851CXCursor clang_getCursorDefinition(CXCursor C) {
4852 if (clang_isInvalid(C.kind))
4853 return clang_getNullCursor();
4854
4855 CXTranslationUnit TU = getCursorTU(C);
4856
4857 bool WasReference = false;
4858 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4859 C = clang_getCursorReferenced(C);
4860 WasReference = true;
4861 }
4862
4863 if (C.kind == CXCursor_MacroExpansion)
4864 return clang_getCursorReferenced(C);
4865
4866 if (!clang_isDeclaration(C.kind))
4867 return clang_getNullCursor();
4868
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004869 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004870 if (!D)
4871 return clang_getNullCursor();
4872
4873 switch (D->getKind()) {
4874 // Declaration kinds that don't really separate the notions of
4875 // declaration and definition.
4876 case Decl::Namespace:
4877 case Decl::Typedef:
4878 case Decl::TypeAlias:
4879 case Decl::TypeAliasTemplate:
4880 case Decl::TemplateTypeParm:
4881 case Decl::EnumConstant:
4882 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004883 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 case Decl::IndirectField:
4885 case Decl::ObjCIvar:
4886 case Decl::ObjCAtDefsField:
4887 case Decl::ImplicitParam:
4888 case Decl::ParmVar:
4889 case Decl::NonTypeTemplateParm:
4890 case Decl::TemplateTemplateParm:
4891 case Decl::ObjCCategoryImpl:
4892 case Decl::ObjCImplementation:
4893 case Decl::AccessSpec:
4894 case Decl::LinkageSpec:
4895 case Decl::ObjCPropertyImpl:
4896 case Decl::FileScopeAsm:
4897 case Decl::StaticAssert:
4898 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004899 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004900 case Decl::Label: // FIXME: Is this right??
4901 case Decl::ClassScopeFunctionSpecialization:
4902 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004903 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004904 return C;
4905
4906 // Declaration kinds that don't make any sense here, but are
4907 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004908 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004909 case Decl::TranslationUnit:
4910 break;
4911
4912 // Declaration kinds for which the definition is not resolvable.
4913 case Decl::UnresolvedUsingTypename:
4914 case Decl::UnresolvedUsingValue:
4915 break;
4916
4917 case Decl::UsingDirective:
4918 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4919 TU);
4920
4921 case Decl::NamespaceAlias:
4922 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4923
4924 case Decl::Enum:
4925 case Decl::Record:
4926 case Decl::CXXRecord:
4927 case Decl::ClassTemplateSpecialization:
4928 case Decl::ClassTemplatePartialSpecialization:
4929 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4930 return MakeCXCursor(Def, TU);
4931 return clang_getNullCursor();
4932
4933 case Decl::Function:
4934 case Decl::CXXMethod:
4935 case Decl::CXXConstructor:
4936 case Decl::CXXDestructor:
4937 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004938 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004939 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004940 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004941 return clang_getNullCursor();
4942 }
4943
Larisse Voufo39a1e502013-08-06 01:03:05 +00004944 case Decl::Var:
4945 case Decl::VarTemplateSpecialization:
4946 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004947 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004948 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004949 return MakeCXCursor(Def, TU);
4950 return clang_getNullCursor();
4951 }
4952
4953 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004954 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4956 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4957 return clang_getNullCursor();
4958 }
4959
4960 case Decl::ClassTemplate: {
4961 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4962 ->getDefinition())
4963 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4964 TU);
4965 return clang_getNullCursor();
4966 }
4967
Larisse Voufo39a1e502013-08-06 01:03:05 +00004968 case Decl::VarTemplate: {
4969 if (VarDecl *Def =
4970 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4971 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4972 return clang_getNullCursor();
4973 }
4974
Guy Benyei11169dd2012-12-18 14:30:41 +00004975 case Decl::Using:
4976 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4977 D->getLocation(), TU);
4978
4979 case Decl::UsingShadow:
4980 return clang_getCursorDefinition(
4981 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4982 TU));
4983
4984 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004985 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004986 if (Method->isThisDeclarationADefinition())
4987 return C;
4988
4989 // Dig out the method definition in the associated
4990 // @implementation, if we have it.
4991 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004992 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4994 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4995 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4996 Method->isInstanceMethod()))
4997 if (Def->isThisDeclarationADefinition())
4998 return MakeCXCursor(Def, TU);
4999
5000 return clang_getNullCursor();
5001 }
5002
5003 case Decl::ObjCCategory:
5004 if (ObjCCategoryImplDecl *Impl
5005 = cast<ObjCCategoryDecl>(D)->getImplementation())
5006 return MakeCXCursor(Impl, TU);
5007 return clang_getNullCursor();
5008
5009 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005010 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005011 return MakeCXCursor(Def, TU);
5012 return clang_getNullCursor();
5013
5014 case Decl::ObjCInterface: {
5015 // There are two notions of a "definition" for an Objective-C
5016 // class: the interface and its implementation. When we resolved a
5017 // reference to an Objective-C class, produce the @interface as
5018 // the definition; when we were provided with the interface,
5019 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005020 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005021 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005022 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005023 return MakeCXCursor(Def, TU);
5024 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5025 return MakeCXCursor(Impl, TU);
5026 return clang_getNullCursor();
5027 }
5028
5029 case Decl::ObjCProperty:
5030 // FIXME: We don't really know where to find the
5031 // ObjCPropertyImplDecls that implement this property.
5032 return clang_getNullCursor();
5033
5034 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005035 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005036 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005037 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005038 return MakeCXCursor(Def, TU);
5039
5040 return clang_getNullCursor();
5041
5042 case Decl::Friend:
5043 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5044 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5045 return clang_getNullCursor();
5046
5047 case Decl::FriendTemplate:
5048 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5049 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5050 return clang_getNullCursor();
5051 }
5052
5053 return clang_getNullCursor();
5054}
5055
5056unsigned clang_isCursorDefinition(CXCursor C) {
5057 if (!clang_isDeclaration(C.kind))
5058 return 0;
5059
5060 return clang_getCursorDefinition(C) == C;
5061}
5062
5063CXCursor clang_getCanonicalCursor(CXCursor C) {
5064 if (!clang_isDeclaration(C.kind))
5065 return C;
5066
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005067 if (const Decl *D = getCursorDecl(C)) {
5068 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5070 return MakeCXCursor(CatD, getCursorTU(C));
5071
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005072 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5073 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005074 return MakeCXCursor(IFD, getCursorTU(C));
5075
5076 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5077 }
5078
5079 return C;
5080}
5081
5082int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5083 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5084}
5085
5086unsigned clang_getNumOverloadedDecls(CXCursor C) {
5087 if (C.kind != CXCursor_OverloadedDeclRef)
5088 return 0;
5089
5090 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005091 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 return E->getNumDecls();
5093
5094 if (OverloadedTemplateStorage *S
5095 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5096 return S->size();
5097
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005098 const Decl *D = Storage.get<const Decl *>();
5099 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 return Using->shadow_size();
5101
5102 return 0;
5103}
5104
5105CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5106 if (cursor.kind != CXCursor_OverloadedDeclRef)
5107 return clang_getNullCursor();
5108
5109 if (index >= clang_getNumOverloadedDecls(cursor))
5110 return clang_getNullCursor();
5111
5112 CXTranslationUnit TU = getCursorTU(cursor);
5113 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005114 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005115 return MakeCXCursor(E->decls_begin()[index], TU);
5116
5117 if (OverloadedTemplateStorage *S
5118 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5119 return MakeCXCursor(S->begin()[index], TU);
5120
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005121 const Decl *D = Storage.get<const Decl *>();
5122 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005123 // FIXME: This is, unfortunately, linear time.
5124 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5125 std::advance(Pos, index);
5126 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5127 }
5128
5129 return clang_getNullCursor();
5130}
5131
5132void clang_getDefinitionSpellingAndExtent(CXCursor C,
5133 const char **startBuf,
5134 const char **endBuf,
5135 unsigned *startLine,
5136 unsigned *startColumn,
5137 unsigned *endLine,
5138 unsigned *endColumn) {
5139 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005140 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5142
5143 SourceManager &SM = FD->getASTContext().getSourceManager();
5144 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5145 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5146 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5147 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5148 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5149 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5150}
5151
5152
5153CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5154 unsigned PieceIndex) {
5155 RefNamePieces Pieces;
5156
5157 switch (C.kind) {
5158 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005159 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5161 E->getQualifierLoc().getSourceRange());
5162 break;
5163
5164 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005165 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5167 E->getQualifierLoc().getSourceRange(),
5168 E->getOptionalExplicitTemplateArgs());
5169 break;
5170
5171 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005172 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005173 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005174 const Expr *Callee = OCE->getCallee();
5175 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 Callee = ICE->getSubExpr();
5177
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005178 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005179 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5180 DRE->getQualifierLoc().getSourceRange());
5181 }
5182 break;
5183
5184 default:
5185 break;
5186 }
5187
5188 if (Pieces.empty()) {
5189 if (PieceIndex == 0)
5190 return clang_getCursorExtent(C);
5191 } else if (PieceIndex < Pieces.size()) {
5192 SourceRange R = Pieces[PieceIndex];
5193 if (R.isValid())
5194 return cxloc::translateSourceRange(getCursorContext(C), R);
5195 }
5196
5197 return clang_getNullRange();
5198}
5199
5200void clang_enableStackTraces(void) {
5201 llvm::sys::PrintStackTraceOnErrorSignal();
5202}
5203
5204void clang_executeOnThread(void (*fn)(void*), void *user_data,
5205 unsigned stack_size) {
5206 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5207}
5208
5209} // end: extern "C"
5210
5211//===----------------------------------------------------------------------===//
5212// Token-based Operations.
5213//===----------------------------------------------------------------------===//
5214
5215/* CXToken layout:
5216 * int_data[0]: a CXTokenKind
5217 * int_data[1]: starting token location
5218 * int_data[2]: token length
5219 * int_data[3]: reserved
5220 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5221 * otherwise unused.
5222 */
5223extern "C" {
5224
5225CXTokenKind clang_getTokenKind(CXToken CXTok) {
5226 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5227}
5228
5229CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5230 switch (clang_getTokenKind(CXTok)) {
5231 case CXToken_Identifier:
5232 case CXToken_Keyword:
5233 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005234 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005235 ->getNameStart());
5236
5237 case CXToken_Literal: {
5238 // We have stashed the starting pointer in the ptr_data field. Use it.
5239 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005240 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005241 }
5242
5243 case CXToken_Punctuation:
5244 case CXToken_Comment:
5245 break;
5246 }
5247
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005248 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005249 LOG_BAD_TU(TU);
5250 return cxstring::createEmpty();
5251 }
5252
Guy Benyei11169dd2012-12-18 14:30:41 +00005253 // We have to find the starting buffer pointer the hard way, by
5254 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005255 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005257 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005258
5259 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5260 std::pair<FileID, unsigned> LocInfo
5261 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5262 bool Invalid = false;
5263 StringRef Buffer
5264 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5265 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005266 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005267
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005268 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005269}
5270
5271CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005272 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005273 LOG_BAD_TU(TU);
5274 return clang_getNullLocation();
5275 }
5276
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005277 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 if (!CXXUnit)
5279 return clang_getNullLocation();
5280
5281 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5282 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5283}
5284
5285CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005286 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005287 LOG_BAD_TU(TU);
5288 return clang_getNullRange();
5289 }
5290
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005291 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 if (!CXXUnit)
5293 return clang_getNullRange();
5294
5295 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5296 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5297}
5298
5299static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5300 SmallVectorImpl<CXToken> &CXTokens) {
5301 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5302 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005303 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005305 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005306
5307 // Cannot tokenize across files.
5308 if (BeginLocInfo.first != EndLocInfo.first)
5309 return;
5310
5311 // Create a lexer
5312 bool Invalid = false;
5313 StringRef Buffer
5314 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5315 if (Invalid)
5316 return;
5317
5318 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5319 CXXUnit->getASTContext().getLangOpts(),
5320 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5321 Lex.SetCommentRetentionState(true);
5322
5323 // Lex tokens until we hit the end of the range.
5324 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5325 Token Tok;
5326 bool previousWasAt = false;
5327 do {
5328 // Lex the next token
5329 Lex.LexFromRawLexer(Tok);
5330 if (Tok.is(tok::eof))
5331 break;
5332
5333 // Initialize the CXToken.
5334 CXToken CXTok;
5335
5336 // - Common fields
5337 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5338 CXTok.int_data[2] = Tok.getLength();
5339 CXTok.int_data[3] = 0;
5340
5341 // - Kind-specific fields
5342 if (Tok.isLiteral()) {
5343 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005344 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005345 } else if (Tok.is(tok::raw_identifier)) {
5346 // Lookup the identifier to determine whether we have a keyword.
5347 IdentifierInfo *II
5348 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5349
5350 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5351 CXTok.int_data[0] = CXToken_Keyword;
5352 }
5353 else {
5354 CXTok.int_data[0] = Tok.is(tok::identifier)
5355 ? CXToken_Identifier
5356 : CXToken_Keyword;
5357 }
5358 CXTok.ptr_data = II;
5359 } else if (Tok.is(tok::comment)) {
5360 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005361 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 } else {
5363 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005364 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 }
5366 CXTokens.push_back(CXTok);
5367 previousWasAt = Tok.is(tok::at);
5368 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5369}
5370
5371void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5372 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005373 LOG_FUNC_SECTION {
5374 *Log << TU << ' ' << Range;
5375 }
5376
Guy Benyei11169dd2012-12-18 14:30:41 +00005377 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005378 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005379 if (NumTokens)
5380 *NumTokens = 0;
5381
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005382 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005383 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005384 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005385 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005386
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005387 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005388 if (!CXXUnit || !Tokens || !NumTokens)
5389 return;
5390
5391 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5392
5393 SourceRange R = cxloc::translateCXSourceRange(Range);
5394 if (R.isInvalid())
5395 return;
5396
5397 SmallVector<CXToken, 32> CXTokens;
5398 getTokens(CXXUnit, R, CXTokens);
5399
5400 if (CXTokens.empty())
5401 return;
5402
5403 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5404 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5405 *NumTokens = CXTokens.size();
5406}
5407
5408void clang_disposeTokens(CXTranslationUnit TU,
5409 CXToken *Tokens, unsigned NumTokens) {
5410 free(Tokens);
5411}
5412
5413} // end: extern "C"
5414
5415//===----------------------------------------------------------------------===//
5416// Token annotation APIs.
5417//===----------------------------------------------------------------------===//
5418
Guy Benyei11169dd2012-12-18 14:30:41 +00005419static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5420 CXCursor parent,
5421 CXClientData client_data);
5422static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5423 CXClientData client_data);
5424
5425namespace {
5426class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005427 CXToken *Tokens;
5428 CXCursor *Cursors;
5429 unsigned NumTokens;
5430 unsigned TokIdx;
5431 unsigned PreprocessingTokIdx;
5432 CursorVisitor AnnotateVis;
5433 SourceManager &SrcMgr;
5434 bool HasContextSensitiveKeywords;
5435
5436 struct PostChildrenInfo {
5437 CXCursor Cursor;
5438 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005439 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005440 unsigned BeforeChildrenTokenIdx;
5441 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005442 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005443
5444 CXToken &getTok(unsigned Idx) {
5445 assert(Idx < NumTokens);
5446 return Tokens[Idx];
5447 }
5448 const CXToken &getTok(unsigned Idx) const {
5449 assert(Idx < NumTokens);
5450 return Tokens[Idx];
5451 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005452 bool MoreTokens() const { return TokIdx < NumTokens; }
5453 unsigned NextToken() const { return TokIdx; }
5454 void AdvanceToken() { ++TokIdx; }
5455 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005456 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 }
5458 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005459 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005460 }
5461 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005462 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 }
5464
5465 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005466 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 SourceRange);
5468
5469public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005470 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005471 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005472 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005474 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 AnnotateTokensVisitor, this,
5476 /*VisitPreprocessorLast=*/true,
5477 /*VisitIncludedEntities=*/false,
5478 RegionOfInterest,
5479 /*VisitDeclsOnly=*/false,
5480 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005481 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 HasContextSensitiveKeywords(false) { }
5483
5484 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5485 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5486 bool postVisitChildren(CXCursor cursor);
5487 void AnnotateTokens();
5488
5489 /// \brief Determine whether the annotator saw any cursors that have
5490 /// context-sensitive keywords.
5491 bool hasContextSensitiveKeywords() const {
5492 return HasContextSensitiveKeywords;
5493 }
5494
5495 ~AnnotateTokensWorker() {
5496 assert(PostChildrenInfos.empty());
5497 }
5498};
5499}
5500
5501void AnnotateTokensWorker::AnnotateTokens() {
5502 // Walk the AST within the region of interest, annotating tokens
5503 // along the way.
5504 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005505}
Guy Benyei11169dd2012-12-18 14:30:41 +00005506
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005507static inline void updateCursorAnnotation(CXCursor &Cursor,
5508 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005509 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005510 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005511 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005512}
5513
5514/// \brief It annotates and advances tokens with a cursor until the comparison
5515//// between the cursor location and the source range is the same as
5516/// \arg compResult.
5517///
5518/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5519/// Pass RangeOverlap to annotate tokens inside a range.
5520void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5521 RangeComparisonResult compResult,
5522 SourceRange range) {
5523 while (MoreTokens()) {
5524 const unsigned I = NextToken();
5525 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005526 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5527 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005528
5529 SourceLocation TokLoc = GetTokenLoc(I);
5530 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005531 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005532 AdvanceToken();
5533 continue;
5534 }
5535 break;
5536 }
5537}
5538
5539/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005540/// \returns true if it advanced beyond all macro tokens, false otherwise.
5541bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005542 CXCursor updateC,
5543 RangeComparisonResult compResult,
5544 SourceRange range) {
5545 assert(MoreTokens());
5546 assert(isFunctionMacroToken(NextToken()) &&
5547 "Should be called only for macro arg tokens");
5548
5549 // This works differently than annotateAndAdvanceTokens; because expanded
5550 // macro arguments can have arbitrary translation-unit source order, we do not
5551 // advance the token index one by one until a token fails the range test.
5552 // We only advance once past all of the macro arg tokens if all of them
5553 // pass the range test. If one of them fails we keep the token index pointing
5554 // at the start of the macro arg tokens so that the failing token will be
5555 // annotated by a subsequent annotation try.
5556
5557 bool atLeastOneCompFail = false;
5558
5559 unsigned I = NextToken();
5560 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5561 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5562 if (TokLoc.isFileID())
5563 continue; // not macro arg token, it's parens or comma.
5564 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5565 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5566 Cursors[I] = updateC;
5567 } else
5568 atLeastOneCompFail = true;
5569 }
5570
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005571 if (atLeastOneCompFail)
5572 return false;
5573
5574 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5575 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005576}
5577
5578enum CXChildVisitResult
5579AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005580 SourceRange cursorRange = getRawCursorExtent(cursor);
5581 if (cursorRange.isInvalid())
5582 return CXChildVisit_Recurse;
5583
5584 if (!HasContextSensitiveKeywords) {
5585 // Objective-C properties can have context-sensitive keywords.
5586 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005587 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005588 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5589 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5590 }
5591 // Objective-C methods can have context-sensitive keywords.
5592 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5593 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005594 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5596 if (Method->getObjCDeclQualifier())
5597 HasContextSensitiveKeywords = true;
5598 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005599 for (const auto *P : Method->params()) {
5600 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005601 HasContextSensitiveKeywords = true;
5602 break;
5603 }
5604 }
5605 }
5606 }
5607 }
5608 // C++ methods can have context-sensitive keywords.
5609 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005610 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005611 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5612 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5613 HasContextSensitiveKeywords = true;
5614 }
5615 }
5616 // C++ classes can have context-sensitive keywords.
5617 else if (cursor.kind == CXCursor_StructDecl ||
5618 cursor.kind == CXCursor_ClassDecl ||
5619 cursor.kind == CXCursor_ClassTemplate ||
5620 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005621 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005622 if (D->hasAttr<FinalAttr>())
5623 HasContextSensitiveKeywords = true;
5624 }
5625 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005626
5627 // Don't override a property annotation with its getter/setter method.
5628 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5629 parent.kind == CXCursor_ObjCPropertyDecl)
5630 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005631
5632 if (clang_isPreprocessing(cursor.kind)) {
5633 // Items in the preprocessing record are kept separate from items in
5634 // declarations, so we keep a separate token index.
5635 unsigned SavedTokIdx = TokIdx;
5636 TokIdx = PreprocessingTokIdx;
5637
5638 // Skip tokens up until we catch up to the beginning of the preprocessing
5639 // entry.
5640 while (MoreTokens()) {
5641 const unsigned I = NextToken();
5642 SourceLocation TokLoc = GetTokenLoc(I);
5643 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5644 case RangeBefore:
5645 AdvanceToken();
5646 continue;
5647 case RangeAfter:
5648 case RangeOverlap:
5649 break;
5650 }
5651 break;
5652 }
5653
5654 // Look at all of the tokens within this range.
5655 while (MoreTokens()) {
5656 const unsigned I = NextToken();
5657 SourceLocation TokLoc = GetTokenLoc(I);
5658 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5659 case RangeBefore:
5660 llvm_unreachable("Infeasible");
5661 case RangeAfter:
5662 break;
5663 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005664 // For macro expansions, just note where the beginning of the macro
5665 // expansion occurs.
5666 if (cursor.kind == CXCursor_MacroExpansion) {
5667 if (TokLoc == cursorRange.getBegin())
5668 Cursors[I] = cursor;
5669 AdvanceToken();
5670 break;
5671 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005672 // We may have already annotated macro names inside macro definitions.
5673 if (Cursors[I].kind != CXCursor_MacroExpansion)
5674 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 continue;
5677 }
5678 break;
5679 }
5680
5681 // Save the preprocessing token index; restore the non-preprocessing
5682 // token index.
5683 PreprocessingTokIdx = TokIdx;
5684 TokIdx = SavedTokIdx;
5685 return CXChildVisit_Recurse;
5686 }
5687
5688 if (cursorRange.isInvalid())
5689 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005690
5691 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005692 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005693 const enum CXCursorKind K = clang_getCursorKind(parent);
5694 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005695 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5696 // Attributes are annotated out-of-order, skip tokens until we reach it.
5697 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005698 ? clang_getNullCursor() : parent;
5699
5700 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5701
5702 // Avoid having the cursor of an expression "overwrite" the annotation of the
5703 // variable declaration that it belongs to.
5704 // This can happen for C++ constructor expressions whose range generally
5705 // include the variable declaration, e.g.:
5706 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005707 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005708 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005709 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005710 const unsigned I = NextToken();
5711 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5712 E->getLocStart() == D->getLocation() &&
5713 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005714 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005715 AdvanceToken();
5716 }
5717 }
5718 }
5719
5720 // Before recursing into the children keep some state that we are going
5721 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5722 // extra work after the child nodes are visited.
5723 // Note that we don't call VisitChildren here to avoid traversing statements
5724 // code-recursively which can blow the stack.
5725
5726 PostChildrenInfo Info;
5727 Info.Cursor = cursor;
5728 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005729 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005730 Info.BeforeChildrenTokenIdx = NextToken();
5731 PostChildrenInfos.push_back(Info);
5732
5733 return CXChildVisit_Recurse;
5734}
5735
5736bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5737 if (PostChildrenInfos.empty())
5738 return false;
5739 const PostChildrenInfo &Info = PostChildrenInfos.back();
5740 if (!clang_equalCursors(Info.Cursor, cursor))
5741 return false;
5742
5743 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5744 const unsigned AfterChildren = NextToken();
5745 SourceRange cursorRange = Info.CursorRange;
5746
5747 // Scan the tokens that are at the end of the cursor, but are not captured
5748 // but the child cursors.
5749 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5750
5751 // Scan the tokens that are at the beginning of the cursor, but are not
5752 // capture by the child cursors.
5753 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5754 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5755 break;
5756
5757 Cursors[I] = cursor;
5758 }
5759
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005760 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5761 // encountered the attribute cursor.
5762 if (clang_isAttribute(cursor.kind))
5763 TokIdx = Info.BeforeReachingCursorIdx;
5764
Guy Benyei11169dd2012-12-18 14:30:41 +00005765 PostChildrenInfos.pop_back();
5766 return false;
5767}
5768
5769static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5770 CXCursor parent,
5771 CXClientData client_data) {
5772 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5773}
5774
5775static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5776 CXClientData client_data) {
5777 return static_cast<AnnotateTokensWorker*>(client_data)->
5778 postVisitChildren(cursor);
5779}
5780
5781namespace {
5782
5783/// \brief Uses the macro expansions in the preprocessing record to find
5784/// and mark tokens that are macro arguments. This info is used by the
5785/// AnnotateTokensWorker.
5786class MarkMacroArgTokensVisitor {
5787 SourceManager &SM;
5788 CXToken *Tokens;
5789 unsigned NumTokens;
5790 unsigned CurIdx;
5791
5792public:
5793 MarkMacroArgTokensVisitor(SourceManager &SM,
5794 CXToken *tokens, unsigned numTokens)
5795 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5796
5797 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5798 if (cursor.kind != CXCursor_MacroExpansion)
5799 return CXChildVisit_Continue;
5800
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005801 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005802 if (macroRange.getBegin() == macroRange.getEnd())
5803 return CXChildVisit_Continue; // it's not a function macro.
5804
5805 for (; CurIdx < NumTokens; ++CurIdx) {
5806 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5807 macroRange.getBegin()))
5808 break;
5809 }
5810
5811 if (CurIdx == NumTokens)
5812 return CXChildVisit_Break;
5813
5814 for (; CurIdx < NumTokens; ++CurIdx) {
5815 SourceLocation tokLoc = getTokenLoc(CurIdx);
5816 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5817 break;
5818
5819 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5820 }
5821
5822 if (CurIdx == NumTokens)
5823 return CXChildVisit_Break;
5824
5825 return CXChildVisit_Continue;
5826 }
5827
5828private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005829 CXToken &getTok(unsigned Idx) {
5830 assert(Idx < NumTokens);
5831 return Tokens[Idx];
5832 }
5833 const CXToken &getTok(unsigned Idx) const {
5834 assert(Idx < NumTokens);
5835 return Tokens[Idx];
5836 }
5837
Guy Benyei11169dd2012-12-18 14:30:41 +00005838 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005839 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005840 }
5841
5842 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5843 // The third field is reserved and currently not used. Use it here
5844 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005845 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005846 }
5847};
5848
5849} // end anonymous namespace
5850
5851static CXChildVisitResult
5852MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5853 CXClientData client_data) {
5854 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5855 parent);
5856}
5857
5858namespace {
5859 struct clang_annotateTokens_Data {
5860 CXTranslationUnit TU;
5861 ASTUnit *CXXUnit;
5862 CXToken *Tokens;
5863 unsigned NumTokens;
5864 CXCursor *Cursors;
5865 };
5866}
5867
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005868/// \brief Used by \c annotatePreprocessorTokens.
5869/// \returns true if lexing was finished, false otherwise.
5870static bool lexNext(Lexer &Lex, Token &Tok,
5871 unsigned &NextIdx, unsigned NumTokens) {
5872 if (NextIdx >= NumTokens)
5873 return true;
5874
5875 ++NextIdx;
5876 Lex.LexFromRawLexer(Tok);
5877 if (Tok.is(tok::eof))
5878 return true;
5879
5880 return false;
5881}
5882
Guy Benyei11169dd2012-12-18 14:30:41 +00005883static void annotatePreprocessorTokens(CXTranslationUnit TU,
5884 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005885 CXCursor *Cursors,
5886 CXToken *Tokens,
5887 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005888 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005889
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005890 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5892 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005893 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005894 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005895 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005896
5897 if (BeginLocInfo.first != EndLocInfo.first)
5898 return;
5899
5900 StringRef Buffer;
5901 bool Invalid = false;
5902 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5903 if (Buffer.empty() || Invalid)
5904 return;
5905
5906 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5907 CXXUnit->getASTContext().getLangOpts(),
5908 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5909 Buffer.end());
5910 Lex.SetCommentRetentionState(true);
5911
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005912 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005913 // Lex tokens in raw mode until we hit the end of the range, to avoid
5914 // entering #includes or expanding macros.
5915 while (true) {
5916 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005917 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5918 break;
5919 unsigned TokIdx = NextIdx-1;
5920 assert(Tok.getLocation() ==
5921 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005922
5923 reprocess:
5924 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005925 // We have found a preprocessing directive. Annotate the tokens
5926 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005927 //
5928 // FIXME: Some simple tests here could identify macro definitions and
5929 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005930
5931 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005932 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5933 break;
5934
Craig Topper69186e72014-06-08 08:38:04 +00005935 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005936 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005937 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5938 break;
5939
5940 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005941 IdentifierInfo &II =
5942 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005943 SourceLocation MappedTokLoc =
5944 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5945 MI = getMacroInfo(II, MappedTokLoc, TU);
5946 }
5947 }
5948
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005949 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005950 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005951 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5952 finished = true;
5953 break;
5954 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005955 // If we are in a macro definition, check if the token was ever a
5956 // macro name and annotate it if that's the case.
5957 if (MI) {
5958 SourceLocation SaveLoc = Tok.getLocation();
5959 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5960 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5961 Tok.setLocation(SaveLoc);
5962 if (MacroDef)
5963 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5964 Tok.getLocation(), TU);
5965 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005966 } while (!Tok.isAtStartOfLine());
5967
5968 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5969 assert(TokIdx <= LastIdx);
5970 SourceLocation EndLoc =
5971 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5972 CXCursor Cursor =
5973 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5974
5975 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005976 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005977
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005978 if (finished)
5979 break;
5980 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005981 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005982 }
5983}
5984
5985// This gets run a separate thread to avoid stack blowout.
5986static void clang_annotateTokensImpl(void *UserData) {
5987 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5988 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5989 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5990 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5991 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5992
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005993 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005994 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5995 setThreadBackgroundPriority();
5996
5997 // Determine the region of interest, which contains all of the tokens.
5998 SourceRange RegionOfInterest;
5999 RegionOfInterest.setBegin(
6000 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6001 RegionOfInterest.setEnd(
6002 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6003 Tokens[NumTokens-1])));
6004
Guy Benyei11169dd2012-12-18 14:30:41 +00006005 // Relex the tokens within the source range to look for preprocessing
6006 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006007 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006008
6009 // If begin location points inside a macro argument, set it to the expansion
6010 // location so we can have the full context when annotating semantically.
6011 {
6012 SourceManager &SM = CXXUnit->getSourceManager();
6013 SourceLocation Loc =
6014 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6015 if (Loc.isMacroID())
6016 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6017 }
6018
Guy Benyei11169dd2012-12-18 14:30:41 +00006019 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6020 // Search and mark tokens that are macro argument expansions.
6021 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6022 Tokens, NumTokens);
6023 CursorVisitor MacroArgMarker(TU,
6024 MarkMacroArgTokensVisitorDelegate, &Visitor,
6025 /*VisitPreprocessorLast=*/true,
6026 /*VisitIncludedEntities=*/false,
6027 RegionOfInterest);
6028 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6029 }
6030
6031 // Annotate all of the source locations in the region of interest that map to
6032 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006033 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006034
6035 // FIXME: We use a ridiculous stack size here because the data-recursion
6036 // algorithm uses a large stack frame than the non-data recursive version,
6037 // and AnnotationTokensWorker currently transforms the data-recursion
6038 // algorithm back into a traditional recursion by explicitly calling
6039 // VisitChildren(). We will need to remove this explicit recursive call.
6040 W.AnnotateTokens();
6041
6042 // If we ran into any entities that involve context-sensitive keywords,
6043 // take another pass through the tokens to mark them as such.
6044 if (W.hasContextSensitiveKeywords()) {
6045 for (unsigned I = 0; I != NumTokens; ++I) {
6046 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6047 continue;
6048
6049 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6050 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006051 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006052 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6053 if (Property->getPropertyAttributesAsWritten() != 0 &&
6054 llvm::StringSwitch<bool>(II->getName())
6055 .Case("readonly", true)
6056 .Case("assign", true)
6057 .Case("unsafe_unretained", true)
6058 .Case("readwrite", true)
6059 .Case("retain", true)
6060 .Case("copy", true)
6061 .Case("nonatomic", true)
6062 .Case("atomic", true)
6063 .Case("getter", true)
6064 .Case("setter", true)
6065 .Case("strong", true)
6066 .Case("weak", true)
6067 .Default(false))
6068 Tokens[I].int_data[0] = CXToken_Keyword;
6069 }
6070 continue;
6071 }
6072
6073 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6074 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6075 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6076 if (llvm::StringSwitch<bool>(II->getName())
6077 .Case("in", true)
6078 .Case("out", true)
6079 .Case("inout", true)
6080 .Case("oneway", true)
6081 .Case("bycopy", true)
6082 .Case("byref", true)
6083 .Default(false))
6084 Tokens[I].int_data[0] = CXToken_Keyword;
6085 continue;
6086 }
6087
6088 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6089 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6090 Tokens[I].int_data[0] = CXToken_Keyword;
6091 continue;
6092 }
6093 }
6094 }
6095}
6096
6097extern "C" {
6098
6099void clang_annotateTokens(CXTranslationUnit TU,
6100 CXToken *Tokens, unsigned NumTokens,
6101 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006102 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006103 LOG_BAD_TU(TU);
6104 return;
6105 }
6106 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006107 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006108 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006109 }
6110
6111 LOG_FUNC_SECTION {
6112 *Log << TU << ' ';
6113 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6114 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6115 *Log << clang_getRange(bloc, eloc);
6116 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006117
6118 // Any token we don't specifically annotate will have a NULL cursor.
6119 CXCursor C = clang_getNullCursor();
6120 for (unsigned I = 0; I != NumTokens; ++I)
6121 Cursors[I] = C;
6122
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006123 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006124 if (!CXXUnit)
6125 return;
6126
6127 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6128
6129 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6130 llvm::CrashRecoveryContext CRC;
6131 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6132 GetSafetyThreadStackSize() * 2)) {
6133 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6134 }
6135}
6136
6137} // end: extern "C"
6138
6139//===----------------------------------------------------------------------===//
6140// Operations for querying linkage of a cursor.
6141//===----------------------------------------------------------------------===//
6142
6143extern "C" {
6144CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6145 if (!clang_isDeclaration(cursor.kind))
6146 return CXLinkage_Invalid;
6147
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006148 const Decl *D = cxcursor::getCursorDecl(cursor);
6149 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006150 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006151 case NoLinkage:
6152 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 case InternalLinkage: return CXLinkage_Internal;
6154 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6155 case ExternalLinkage: return CXLinkage_External;
6156 };
6157
6158 return CXLinkage_Invalid;
6159}
6160} // end: extern "C"
6161
6162//===----------------------------------------------------------------------===//
6163// Operations for querying language of a cursor.
6164//===----------------------------------------------------------------------===//
6165
6166static CXLanguageKind getDeclLanguage(const Decl *D) {
6167 if (!D)
6168 return CXLanguage_C;
6169
6170 switch (D->getKind()) {
6171 default:
6172 break;
6173 case Decl::ImplicitParam:
6174 case Decl::ObjCAtDefsField:
6175 case Decl::ObjCCategory:
6176 case Decl::ObjCCategoryImpl:
6177 case Decl::ObjCCompatibleAlias:
6178 case Decl::ObjCImplementation:
6179 case Decl::ObjCInterface:
6180 case Decl::ObjCIvar:
6181 case Decl::ObjCMethod:
6182 case Decl::ObjCProperty:
6183 case Decl::ObjCPropertyImpl:
6184 case Decl::ObjCProtocol:
6185 return CXLanguage_ObjC;
6186 case Decl::CXXConstructor:
6187 case Decl::CXXConversion:
6188 case Decl::CXXDestructor:
6189 case Decl::CXXMethod:
6190 case Decl::CXXRecord:
6191 case Decl::ClassTemplate:
6192 case Decl::ClassTemplatePartialSpecialization:
6193 case Decl::ClassTemplateSpecialization:
6194 case Decl::Friend:
6195 case Decl::FriendTemplate:
6196 case Decl::FunctionTemplate:
6197 case Decl::LinkageSpec:
6198 case Decl::Namespace:
6199 case Decl::NamespaceAlias:
6200 case Decl::NonTypeTemplateParm:
6201 case Decl::StaticAssert:
6202 case Decl::TemplateTemplateParm:
6203 case Decl::TemplateTypeParm:
6204 case Decl::UnresolvedUsingTypename:
6205 case Decl::UnresolvedUsingValue:
6206 case Decl::Using:
6207 case Decl::UsingDirective:
6208 case Decl::UsingShadow:
6209 return CXLanguage_CPlusPlus;
6210 }
6211
6212 return CXLanguage_C;
6213}
6214
6215extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006216
6217static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6218 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6219 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006220
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006221 switch (D->getAvailability()) {
6222 case AR_Available:
6223 case AR_NotYetIntroduced:
6224 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006225 return getCursorAvailabilityForDecl(
6226 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006227 return CXAvailability_Available;
6228
6229 case AR_Deprecated:
6230 return CXAvailability_Deprecated;
6231
6232 case AR_Unavailable:
6233 return CXAvailability_NotAvailable;
6234 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006235
6236 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006237}
6238
Guy Benyei11169dd2012-12-18 14:30:41 +00006239enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6240 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006241 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6242 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006243
6244 return CXAvailability_Available;
6245}
6246
6247static CXVersion convertVersion(VersionTuple In) {
6248 CXVersion Out = { -1, -1, -1 };
6249 if (In.empty())
6250 return Out;
6251
6252 Out.Major = In.getMajor();
6253
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006254 Optional<unsigned> Minor = In.getMinor();
6255 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006256 Out.Minor = *Minor;
6257 else
6258 return Out;
6259
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006260 Optional<unsigned> Subminor = In.getSubminor();
6261 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006262 Out.Subminor = *Subminor;
6263
6264 return Out;
6265}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006266
6267static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6268 int *always_deprecated,
6269 CXString *deprecated_message,
6270 int *always_unavailable,
6271 CXString *unavailable_message,
6272 CXPlatformAvailability *availability,
6273 int availability_size) {
6274 bool HadAvailAttr = false;
6275 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006276 for (auto A : D->attrs()) {
6277 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006278 HadAvailAttr = true;
6279 if (always_deprecated)
6280 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006281 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006282 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006283 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006284 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006285 continue;
6286 }
6287
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006288 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006289 HadAvailAttr = true;
6290 if (always_unavailable)
6291 *always_unavailable = 1;
6292 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006293 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006294 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6295 }
6296 continue;
6297 }
6298
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006299 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006300 HadAvailAttr = true;
6301 if (N < availability_size) {
6302 availability[N].Platform
6303 = cxstring::createDup(Avail->getPlatform()->getName());
6304 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6305 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6306 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6307 availability[N].Unavailable = Avail->getUnavailable();
6308 availability[N].Message = cxstring::createDup(Avail->getMessage());
6309 }
6310 ++N;
6311 }
6312 }
6313
6314 if (!HadAvailAttr)
6315 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6316 return getCursorPlatformAvailabilityForDecl(
6317 cast<Decl>(EnumConst->getDeclContext()),
6318 always_deprecated,
6319 deprecated_message,
6320 always_unavailable,
6321 unavailable_message,
6322 availability,
6323 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006324
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006325 return N;
6326}
6327
Guy Benyei11169dd2012-12-18 14:30:41 +00006328int clang_getCursorPlatformAvailability(CXCursor cursor,
6329 int *always_deprecated,
6330 CXString *deprecated_message,
6331 int *always_unavailable,
6332 CXString *unavailable_message,
6333 CXPlatformAvailability *availability,
6334 int availability_size) {
6335 if (always_deprecated)
6336 *always_deprecated = 0;
6337 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006338 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006339 if (always_unavailable)
6340 *always_unavailable = 0;
6341 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006342 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006343
Guy Benyei11169dd2012-12-18 14:30:41 +00006344 if (!clang_isDeclaration(cursor.kind))
6345 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006346
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006347 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006348 if (!D)
6349 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006350
6351 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6352 deprecated_message,
6353 always_unavailable,
6354 unavailable_message,
6355 availability,
6356 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006357}
6358
6359void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6360 clang_disposeString(availability->Platform);
6361 clang_disposeString(availability->Message);
6362}
6363
6364CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6365 if (clang_isDeclaration(cursor.kind))
6366 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6367
6368 return CXLanguage_Invalid;
6369}
6370
6371 /// \brief If the given cursor is the "templated" declaration
6372 /// descibing a class or function template, return the class or
6373 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006374static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006375 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006376 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006377
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006378 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006379 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6380 return FunTmpl;
6381
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006382 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006383 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6384 return ClassTmpl;
6385
6386 return D;
6387}
6388
6389CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6390 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006391 if (const Decl *D = getCursorDecl(cursor)) {
6392 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006393 if (!DC)
6394 return clang_getNullCursor();
6395
6396 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6397 getCursorTU(cursor));
6398 }
6399 }
6400
6401 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006402 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006403 return MakeCXCursor(D, getCursorTU(cursor));
6404 }
6405
6406 return clang_getNullCursor();
6407}
6408
6409CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6410 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006411 if (const Decl *D = getCursorDecl(cursor)) {
6412 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006413 if (!DC)
6414 return clang_getNullCursor();
6415
6416 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6417 getCursorTU(cursor));
6418 }
6419 }
6420
6421 // FIXME: Note that we can't easily compute the lexical context of a
6422 // statement or expression, so we return nothing.
6423 return clang_getNullCursor();
6424}
6425
6426CXFile clang_getIncludedFile(CXCursor cursor) {
6427 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006428 return nullptr;
6429
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006430 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006431 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006432}
6433
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006434unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6435 if (C.kind != CXCursor_ObjCPropertyDecl)
6436 return CXObjCPropertyAttr_noattr;
6437
6438 unsigned Result = CXObjCPropertyAttr_noattr;
6439 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6440 ObjCPropertyDecl::PropertyAttributeKind Attr =
6441 PD->getPropertyAttributesAsWritten();
6442
6443#define SET_CXOBJCPROP_ATTR(A) \
6444 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6445 Result |= CXObjCPropertyAttr_##A
6446 SET_CXOBJCPROP_ATTR(readonly);
6447 SET_CXOBJCPROP_ATTR(getter);
6448 SET_CXOBJCPROP_ATTR(assign);
6449 SET_CXOBJCPROP_ATTR(readwrite);
6450 SET_CXOBJCPROP_ATTR(retain);
6451 SET_CXOBJCPROP_ATTR(copy);
6452 SET_CXOBJCPROP_ATTR(nonatomic);
6453 SET_CXOBJCPROP_ATTR(setter);
6454 SET_CXOBJCPROP_ATTR(atomic);
6455 SET_CXOBJCPROP_ATTR(weak);
6456 SET_CXOBJCPROP_ATTR(strong);
6457 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6458#undef SET_CXOBJCPROP_ATTR
6459
6460 return Result;
6461}
6462
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006463unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6464 if (!clang_isDeclaration(C.kind))
6465 return CXObjCDeclQualifier_None;
6466
6467 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6468 const Decl *D = getCursorDecl(C);
6469 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6470 QT = MD->getObjCDeclQualifier();
6471 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6472 QT = PD->getObjCDeclQualifier();
6473 if (QT == Decl::OBJC_TQ_None)
6474 return CXObjCDeclQualifier_None;
6475
6476 unsigned Result = CXObjCDeclQualifier_None;
6477 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6478 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6479 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6480 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6481 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6482 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6483
6484 return Result;
6485}
6486
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006487unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6488 if (!clang_isDeclaration(C.kind))
6489 return 0;
6490
6491 const Decl *D = getCursorDecl(C);
6492 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6493 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6494 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6495 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6496
6497 return 0;
6498}
6499
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006500unsigned clang_Cursor_isVariadic(CXCursor C) {
6501 if (!clang_isDeclaration(C.kind))
6502 return 0;
6503
6504 const Decl *D = getCursorDecl(C);
6505 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6506 return FD->isVariadic();
6507 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6508 return MD->isVariadic();
6509
6510 return 0;
6511}
6512
Guy Benyei11169dd2012-12-18 14:30:41 +00006513CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6514 if (!clang_isDeclaration(C.kind))
6515 return clang_getNullRange();
6516
6517 const Decl *D = getCursorDecl(C);
6518 ASTContext &Context = getCursorContext(C);
6519 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6520 if (!RC)
6521 return clang_getNullRange();
6522
6523 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6524}
6525
6526CXString clang_Cursor_getRawCommentText(CXCursor C) {
6527 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006528 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006529
6530 const Decl *D = getCursorDecl(C);
6531 ASTContext &Context = getCursorContext(C);
6532 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6533 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6534 StringRef();
6535
6536 // Don't duplicate the string because RawText points directly into source
6537 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006538 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006539}
6540
6541CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6542 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006543 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006544
6545 const Decl *D = getCursorDecl(C);
6546 const ASTContext &Context = getCursorContext(C);
6547 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6548
6549 if (RC) {
6550 StringRef BriefText = RC->getBriefText(Context);
6551
6552 // Don't duplicate the string because RawComment ensures that this memory
6553 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006554 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006555 }
6556
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006557 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006558}
6559
Guy Benyei11169dd2012-12-18 14:30:41 +00006560CXModule clang_Cursor_getModule(CXCursor C) {
6561 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006562 if (const ImportDecl *ImportD =
6563 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006564 return ImportD->getImportedModule();
6565 }
6566
Craig Topper69186e72014-06-08 08:38:04 +00006567 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006568}
6569
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006570CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6571 if (isNotUsableTU(TU)) {
6572 LOG_BAD_TU(TU);
6573 return nullptr;
6574 }
6575 if (!File)
6576 return nullptr;
6577 FileEntry *FE = static_cast<FileEntry *>(File);
6578
6579 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6580 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6581 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6582
6583 if (Module *Mod = Header.getModule()) {
6584 if (Header.getRole() != ModuleMap::ExcludedHeader)
6585 return Mod;
6586 }
6587 return nullptr;
6588}
6589
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006590CXFile clang_Module_getASTFile(CXModule CXMod) {
6591 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006592 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006593 Module *Mod = static_cast<Module*>(CXMod);
6594 return const_cast<FileEntry *>(Mod->getASTFile());
6595}
6596
Guy Benyei11169dd2012-12-18 14:30:41 +00006597CXModule clang_Module_getParent(CXModule CXMod) {
6598 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006599 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006600 Module *Mod = static_cast<Module*>(CXMod);
6601 return Mod->Parent;
6602}
6603
6604CXString clang_Module_getName(CXModule CXMod) {
6605 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006606 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006607 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006608 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006609}
6610
6611CXString clang_Module_getFullName(CXModule CXMod) {
6612 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006613 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006614 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006615 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006616}
6617
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006618int clang_Module_isSystem(CXModule CXMod) {
6619 if (!CXMod)
6620 return 0;
6621 Module *Mod = static_cast<Module*>(CXMod);
6622 return Mod->IsSystem;
6623}
6624
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006625unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6626 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006627 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006628 LOG_BAD_TU(TU);
6629 return 0;
6630 }
6631 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006632 return 0;
6633 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006634 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6635 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6636 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006637}
6638
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006639CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6640 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006641 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006642 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006643 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006644 }
6645 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006646 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006647 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006648 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006649
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006650 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6651 if (Index < TopHeaders.size())
6652 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006653
Craig Topper69186e72014-06-08 08:38:04 +00006654 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006655}
6656
6657} // end: extern "C"
6658
6659//===----------------------------------------------------------------------===//
6660// C++ AST instrospection.
6661//===----------------------------------------------------------------------===//
6662
6663extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006664unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6665 if (!clang_isDeclaration(C.kind))
6666 return 0;
6667
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006668 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006669 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006670 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006671 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6672}
6673
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006674unsigned clang_CXXMethod_isConst(CXCursor C) {
6675 if (!clang_isDeclaration(C.kind))
6676 return 0;
6677
6678 const Decl *D = cxcursor::getCursorDecl(C);
6679 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006680 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006681 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6682}
6683
Guy Benyei11169dd2012-12-18 14:30:41 +00006684unsigned clang_CXXMethod_isStatic(CXCursor C) {
6685 if (!clang_isDeclaration(C.kind))
6686 return 0;
6687
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006688 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006689 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006690 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006691 return (Method && Method->isStatic()) ? 1 : 0;
6692}
6693
6694unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6695 if (!clang_isDeclaration(C.kind))
6696 return 0;
6697
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006698 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006699 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006700 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006701 return (Method && Method->isVirtual()) ? 1 : 0;
6702}
6703} // end: extern "C"
6704
6705//===----------------------------------------------------------------------===//
6706// Attribute introspection.
6707//===----------------------------------------------------------------------===//
6708
6709extern "C" {
6710CXType clang_getIBOutletCollectionType(CXCursor C) {
6711 if (C.kind != CXCursor_IBOutletCollectionAttr)
6712 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6713
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006714 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006715 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6716
6717 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6718}
6719} // end: extern "C"
6720
6721//===----------------------------------------------------------------------===//
6722// Inspecting memory usage.
6723//===----------------------------------------------------------------------===//
6724
6725typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6726
6727static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6728 enum CXTUResourceUsageKind k,
6729 unsigned long amount) {
6730 CXTUResourceUsageEntry entry = { k, amount };
6731 entries.push_back(entry);
6732}
6733
6734extern "C" {
6735
6736const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6737 const char *str = "";
6738 switch (kind) {
6739 case CXTUResourceUsage_AST:
6740 str = "ASTContext: expressions, declarations, and types";
6741 break;
6742 case CXTUResourceUsage_Identifiers:
6743 str = "ASTContext: identifiers";
6744 break;
6745 case CXTUResourceUsage_Selectors:
6746 str = "ASTContext: selectors";
6747 break;
6748 case CXTUResourceUsage_GlobalCompletionResults:
6749 str = "Code completion: cached global results";
6750 break;
6751 case CXTUResourceUsage_SourceManagerContentCache:
6752 str = "SourceManager: content cache allocator";
6753 break;
6754 case CXTUResourceUsage_AST_SideTables:
6755 str = "ASTContext: side tables";
6756 break;
6757 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6758 str = "SourceManager: malloc'ed memory buffers";
6759 break;
6760 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6761 str = "SourceManager: mmap'ed memory buffers";
6762 break;
6763 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6764 str = "ExternalASTSource: malloc'ed memory buffers";
6765 break;
6766 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6767 str = "ExternalASTSource: mmap'ed memory buffers";
6768 break;
6769 case CXTUResourceUsage_Preprocessor:
6770 str = "Preprocessor: malloc'ed memory";
6771 break;
6772 case CXTUResourceUsage_PreprocessingRecord:
6773 str = "Preprocessor: PreprocessingRecord";
6774 break;
6775 case CXTUResourceUsage_SourceManager_DataStructures:
6776 str = "SourceManager: data structures and tables";
6777 break;
6778 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6779 str = "Preprocessor: header search tables";
6780 break;
6781 }
6782 return str;
6783}
6784
6785CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006786 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006787 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006788 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006789 return usage;
6790 }
6791
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006792 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006793 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006794 ASTContext &astContext = astUnit->getASTContext();
6795
6796 // How much memory is used by AST nodes and types?
6797 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6798 (unsigned long) astContext.getASTAllocatedMemory());
6799
6800 // How much memory is used by identifiers?
6801 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6802 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6803
6804 // How much memory is used for selectors?
6805 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6806 (unsigned long) astContext.Selectors.getTotalMemory());
6807
6808 // How much memory is used by ASTContext's side tables?
6809 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6810 (unsigned long) astContext.getSideTableAllocatedMemory());
6811
6812 // How much memory is used for caching global code completion results?
6813 unsigned long completionBytes = 0;
6814 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006815 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006816 completionBytes = completionAllocator->getTotalMemory();
6817 }
6818 createCXTUResourceUsageEntry(*entries,
6819 CXTUResourceUsage_GlobalCompletionResults,
6820 completionBytes);
6821
6822 // How much memory is being used by SourceManager's content cache?
6823 createCXTUResourceUsageEntry(*entries,
6824 CXTUResourceUsage_SourceManagerContentCache,
6825 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6826
6827 // How much memory is being used by the MemoryBuffer's in SourceManager?
6828 const SourceManager::MemoryBufferSizes &srcBufs =
6829 astUnit->getSourceManager().getMemoryBufferSizes();
6830
6831 createCXTUResourceUsageEntry(*entries,
6832 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6833 (unsigned long) srcBufs.malloc_bytes);
6834 createCXTUResourceUsageEntry(*entries,
6835 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6836 (unsigned long) srcBufs.mmap_bytes);
6837 createCXTUResourceUsageEntry(*entries,
6838 CXTUResourceUsage_SourceManager_DataStructures,
6839 (unsigned long) astContext.getSourceManager()
6840 .getDataStructureSizes());
6841
6842 // How much memory is being used by the ExternalASTSource?
6843 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6844 const ExternalASTSource::MemoryBufferSizes &sizes =
6845 esrc->getMemoryBufferSizes();
6846
6847 createCXTUResourceUsageEntry(*entries,
6848 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6849 (unsigned long) sizes.malloc_bytes);
6850 createCXTUResourceUsageEntry(*entries,
6851 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6852 (unsigned long) sizes.mmap_bytes);
6853 }
6854
6855 // How much memory is being used by the Preprocessor?
6856 Preprocessor &pp = astUnit->getPreprocessor();
6857 createCXTUResourceUsageEntry(*entries,
6858 CXTUResourceUsage_Preprocessor,
6859 pp.getTotalMemory());
6860
6861 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6862 createCXTUResourceUsageEntry(*entries,
6863 CXTUResourceUsage_PreprocessingRecord,
6864 pRec->getTotalMemory());
6865 }
6866
6867 createCXTUResourceUsageEntry(*entries,
6868 CXTUResourceUsage_Preprocessor_HeaderSearch,
6869 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006870
Guy Benyei11169dd2012-12-18 14:30:41 +00006871 CXTUResourceUsage usage = { (void*) entries.get(),
6872 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006873 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006874 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006875 return usage;
6876}
6877
6878void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6879 if (usage.data)
6880 delete (MemUsageEntries*) usage.data;
6881}
6882
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006883CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6884 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006885 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006886 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006887
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006888 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006889 LOG_BAD_TU(TU);
6890 return skipped;
6891 }
6892
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006893 if (!file)
6894 return skipped;
6895
6896 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6897 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6898 if (!ppRec)
6899 return skipped;
6900
6901 ASTContext &Ctx = astUnit->getASTContext();
6902 SourceManager &sm = Ctx.getSourceManager();
6903 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6904 FileID wantedFileID = sm.translateFile(fileEntry);
6905
6906 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6907 std::vector<SourceRange> wantedRanges;
6908 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6909 i != ei; ++i) {
6910 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6911 wantedRanges.push_back(*i);
6912 }
6913
6914 skipped->count = wantedRanges.size();
6915 skipped->ranges = new CXSourceRange[skipped->count];
6916 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6917 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6918
6919 return skipped;
6920}
6921
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006922void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6923 if (ranges) {
6924 delete[] ranges->ranges;
6925 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006926 }
6927}
6928
Guy Benyei11169dd2012-12-18 14:30:41 +00006929} // end extern "C"
6930
6931void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6932 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6933 for (unsigned I = 0; I != Usage.numEntries; ++I)
6934 fprintf(stderr, " %s: %lu\n",
6935 clang_getTUResourceUsageName(Usage.entries[I].kind),
6936 Usage.entries[I].amount);
6937
6938 clang_disposeCXTUResourceUsage(Usage);
6939}
6940
6941//===----------------------------------------------------------------------===//
6942// Misc. utility functions.
6943//===----------------------------------------------------------------------===//
6944
6945/// Default to using an 8 MB stack size on "safety" threads.
6946static unsigned SafetyStackThreadSize = 8 << 20;
6947
6948namespace clang {
6949
6950bool RunSafely(llvm::CrashRecoveryContext &CRC,
6951 void (*Fn)(void*), void *UserData,
6952 unsigned Size) {
6953 if (!Size)
6954 Size = GetSafetyThreadStackSize();
6955 if (Size)
6956 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6957 return CRC.RunSafely(Fn, UserData);
6958}
6959
6960unsigned GetSafetyThreadStackSize() {
6961 return SafetyStackThreadSize;
6962}
6963
6964void SetSafetyThreadStackSize(unsigned Value) {
6965 SafetyStackThreadSize = Value;
6966}
6967
6968}
6969
6970void clang::setThreadBackgroundPriority() {
6971 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6972 return;
6973
Alp Toker1a86ad22014-07-06 06:24:00 +00006974#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006975 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6976#endif
6977}
6978
6979void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6980 if (!Unit)
6981 return;
6982
6983 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6984 DEnd = Unit->stored_diag_end();
6985 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006986 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006987 CXString Msg = clang_formatDiagnostic(&Diag,
6988 clang_defaultDiagnosticDisplayOptions());
6989 fprintf(stderr, "%s\n", clang_getCString(Msg));
6990 clang_disposeString(Msg);
6991 }
6992#ifdef LLVM_ON_WIN32
6993 // On Windows, force a flush, since there may be multiple copies of
6994 // stderr and stdout in the file system, all with different buffers
6995 // but writing to the same device.
6996 fflush(stderr);
6997#endif
6998}
6999
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007000MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7001 SourceLocation MacroDefLoc,
7002 CXTranslationUnit TU){
7003 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007004 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007005 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007006 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007007
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007008 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007009 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007010 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007011 if (MD) {
7012 for (MacroDirective::DefInfo
7013 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7014 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7015 return Def.getMacroInfo();
7016 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007017 }
7018
Craig Topper69186e72014-06-08 08:38:04 +00007019 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007020}
7021
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007022const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7023 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007024 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007025 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007026 const IdentifierInfo *II = MacroDef->getName();
7027 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007028 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007029
7030 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7031}
7032
7033MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7034 const Token &Tok,
7035 CXTranslationUnit TU) {
7036 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007037 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007038 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007039 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007040
7041 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007042 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007043 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7044 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007045 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007046
7047 // Check that the token is inside the definition and not its argument list.
7048 SourceManager &SM = Unit->getSourceManager();
7049 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007050 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007051 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007052 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007053
7054 Preprocessor &PP = Unit->getPreprocessor();
7055 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7056 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007057 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007058
Alp Toker2d57cea2014-05-17 04:53:25 +00007059 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007060 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007061 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007062
7063 // Check that the identifier is not one of the macro arguments.
7064 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007065 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007066
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007067 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7068 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007069 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007070
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007071 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007072}
7073
7074MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7075 SourceLocation Loc,
7076 CXTranslationUnit TU) {
7077 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007078 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007079
7080 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007081 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007082 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007083 Preprocessor &PP = Unit->getPreprocessor();
7084 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007085 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007086 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7087 Token Tok;
7088 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007089 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007090
7091 return checkForMacroInMacroDefinition(MI, Tok, TU);
7092}
7093
Guy Benyei11169dd2012-12-18 14:30:41 +00007094extern "C" {
7095
7096CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007097 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007098}
7099
7100} // end: extern "C"
7101
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007102Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7103 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007104 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007105 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007106 if (Unit->isMainFileAST())
7107 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007108 return *this;
7109 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007110 } else {
7111 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007112 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007113 return *this;
7114}
7115
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007116Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7117 *this << FE->getName();
7118 return *this;
7119}
7120
7121Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7122 CXString cursorName = clang_getCursorDisplayName(cursor);
7123 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7124 clang_disposeString(cursorName);
7125 return *this;
7126}
7127
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007128Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7129 CXFile File;
7130 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007131 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007132 CXString FileName = clang_getFileName(File);
7133 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7134 clang_disposeString(FileName);
7135 return *this;
7136}
7137
7138Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7139 CXSourceLocation BLoc = clang_getRangeStart(range);
7140 CXSourceLocation ELoc = clang_getRangeEnd(range);
7141
7142 CXFile BFile;
7143 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007144 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007145
7146 CXFile EFile;
7147 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007148 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007149
7150 CXString BFileName = clang_getFileName(BFile);
7151 if (BFile == EFile) {
7152 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7153 BLine, BColumn, ELine, EColumn);
7154 } else {
7155 CXString EFileName = clang_getFileName(EFile);
7156 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7157 BLine, BColumn)
7158 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7159 ELine, EColumn);
7160 clang_disposeString(EFileName);
7161 }
7162 clang_disposeString(BFileName);
7163 return *this;
7164}
7165
7166Logger &cxindex::Logger::operator<<(CXString Str) {
7167 *this << clang_getCString(Str);
7168 return *this;
7169}
7170
7171Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7172 LogOS << Fmt;
7173 return *this;
7174}
7175
Chandler Carruth37ad2582014-06-27 15:14:39 +00007176static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7177
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007178cxindex::Logger::~Logger() {
7179 LogOS.flush();
7180
Chandler Carruth37ad2582014-06-27 15:14:39 +00007181 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007182
7183 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7184
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007185 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007186 OS << "[libclang:" << Name << ':';
7187
Alp Toker1a86ad22014-07-06 06:24:00 +00007188#ifdef USE_DARWIN_THREADS
7189 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007190 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7191 OS << tid << ':';
7192#endif
7193
7194 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7195 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7196 OS << Msg.str() << '\n';
7197
7198 if (Trace) {
7199 llvm::sys::PrintStackTrace(stderr);
7200 OS << "--------------------------------------------------\n";
7201 }
7202}