blob: 1c97845462e887740cf80746c816b5cf077e31c8 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
243 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
244 Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
458
459 continue;
460 }
461
462 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
465
466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000572 if (MacroDefinition *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
667bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669 return Visit(TSInfo->getTypeLoc());
670
671 return false;
672}
673
674bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682 return VisitDeclContext(D);
683}
684
685bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686 ClassTemplateSpecializationDecl *D) {
687 bool ShouldVisitBody = false;
688 switch (D->getSpecializationKind()) {
689 case TSK_Undeclared:
690 case TSK_ImplicitInstantiation:
691 // Nothing to visit
692 return false;
693
694 case TSK_ExplicitInstantiationDeclaration:
695 case TSK_ExplicitInstantiationDefinition:
696 break;
697
698 case TSK_ExplicitSpecialization:
699 ShouldVisitBody = true;
700 break;
701 }
702
703 // Visit the template arguments used in the specialization.
704 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000706 if (TemplateSpecializationTypeLoc TSTLoc =
707 TL.getAs<TemplateSpecializationTypeLoc>()) {
708 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000710 return true;
711 }
712 }
713
714 if (ShouldVisitBody && VisitCXXRecordDecl(D))
715 return true;
716
717 return false;
718}
719
720bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721 ClassTemplatePartialSpecializationDecl *D) {
722 // FIXME: Visit the "outer" template parameter lists on the TagDecl
723 // before visiting these template parameters.
724 if (VisitTemplateParameters(D->getTemplateParameters()))
725 return true;
726
727 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000728 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732 return true;
733
734 return VisitCXXRecordDecl(D);
735}
736
737bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738 // Visit the default argument.
739 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741 if (Visit(DefArg->getTypeLoc()))
742 return true;
743
744 return false;
745}
746
747bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748 if (Expr *Init = D->getInitExpr())
749 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750 return false;
751}
752
753bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000754 unsigned NumParamList = DD->getNumTemplateParameterLists();
755 for (unsigned i = 0; i < NumParamList; i++) {
756 TemplateParameterList* Params = DD->getTemplateParameterList(i);
757 if (VisitTemplateParameters(Params))
758 return true;
759 }
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762 if (Visit(TSInfo->getTypeLoc()))
763 return true;
764
765 // Visit the nested-name-specifier, if present.
766 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
768 return true;
769
770 return false;
771}
772
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000773/// \brief Compare two base or member initializers based on their source order.
774static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775 CXXCtorInitializer *const *Y) {
776 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777}
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 unsigned NumParamList = ND->getNumTemplateParameterLists();
781 for (unsigned i = 0; i < NumParamList; i++) {
782 TemplateParameterList* Params = ND->getTemplateParameterList(i);
783 if (VisitTemplateParameters(Params))
784 return true;
785 }
786
Guy Benyei11169dd2012-12-18 14:30:41 +0000787 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788 // Visit the function declaration's syntactic components in the order
789 // written. This requires a bit of work.
790 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000791 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000792
793 // If we have a function declared directly (without the use of a typedef),
794 // visit just the return type. Otherwise, just visit the function's type
795 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000796 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000797 (!FTL && Visit(TL)))
798 return true;
799
800 // Visit the nested-name-specifier, if present.
801 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
803 return true;
804
805 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000806 if (!isa<CXXDestructorDecl>(ND))
807 if (VisitDeclarationNameInfo(ND->getNameInfo()))
808 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000809
810 // FIXME: Visit explicitly-specified template arguments!
811
812 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000813 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 return true;
815
Bill Wendling44426052012-12-20 19:22:21 +0000816 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 }
818
819 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821 // Find the initializers that were written in the source.
822 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 for (auto *I : Constructor->inits()) {
824 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 continue;
826
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 }
829
830 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000831 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832 &CompareCXXCtorInitializers);
833
Guy Benyei11169dd2012-12-18 14:30:41 +0000834 // Visit the initializers in source order
835 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836 CXXCtorInitializer *Init = WrittenInits[I];
837 if (Init->isAnyMemberInitializer()) {
838 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839 Init->getMemberLocation(), TU)))
840 return true;
841 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842 if (Visit(TInfo->getTypeLoc()))
843 return true;
844 }
845
846 // Visit the initializer value.
847 if (Expr *Initializer = Init->getInit())
848 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849 return true;
850 }
851 }
852
853 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854 return true;
855 }
856
857 return false;
858}
859
860bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861 if (VisitDeclaratorDecl(D))
862 return true;
863
864 if (Expr *BitWidth = D->getBitWidth())
865 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871 if (VisitDeclaratorDecl(D))
872 return true;
873
874 if (Expr *Init = D->getInit())
875 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876
877 return false;
878}
879
880bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881 if (VisitDeclaratorDecl(D))
882 return true;
883
884 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885 if (Expr *DefArg = D->getDefaultArgument())
886 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887
888 return false;
889}
890
891bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitFunctionDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901 // FIXME: Visit the "outer" template parameter lists on the TagDecl
902 // before visiting these template parameters.
903 if (VisitTemplateParameters(D->getTemplateParameters()))
904 return true;
905
906 return VisitCXXRecordDecl(D->getTemplatedDecl());
907}
908
909bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914 VisitTemplateArgumentLoc(D->getDefaultArgument()))
915 return true;
916
917 return false;
918}
919
920bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000921 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000922 if (Visit(TSInfo->getTypeLoc()))
923 return true;
924
Aaron Ballman43b68be2014-03-07 17:50:17 +0000925 for (const auto *P : ND->params()) {
926 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000927 return true;
928 }
929
930 if (ND->isThisDeclarationADefinition() &&
931 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
932 return true;
933
934 return false;
935}
936
937template <typename DeclIt>
938static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
939 SourceManager &SM, SourceLocation EndLoc,
940 SmallVectorImpl<Decl *> &Decls) {
941 DeclIt next = *DI_current;
942 while (++next != DE_current) {
943 Decl *D_next = *next;
944 if (!D_next)
945 break;
946 SourceLocation L = D_next->getLocStart();
947 if (!L.isValid())
948 break;
949 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
950 *DI_current = next;
951 Decls.push_back(D_next);
952 continue;
953 }
954 break;
955 }
956}
957
Guy Benyei11169dd2012-12-18 14:30:41 +0000958bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
959 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
960 // an @implementation can lexically contain Decls that are not properly
961 // nested in the AST. When we identify such cases, we need to retrofit
962 // this nesting here.
963 if (!DI_current && !FileDI_current)
964 return VisitDeclContext(D);
965
966 // Scan the Decls that immediately come after the container
967 // in the current DeclContext. If any fall within the
968 // container's lexical region, stash them into a vector
969 // for later processing.
970 SmallVector<Decl *, 24> DeclsInContainer;
971 SourceLocation EndLoc = D->getSourceRange().getEnd();
972 SourceManager &SM = AU->getSourceManager();
973 if (EndLoc.isValid()) {
974 if (DI_current) {
975 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
976 DeclsInContainer);
977 } else {
978 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
979 DeclsInContainer);
980 }
981 }
982
983 // The common case.
984 if (DeclsInContainer.empty())
985 return VisitDeclContext(D);
986
987 // Get all the Decls in the DeclContext, and sort them with the
988 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 for (auto *SubDecl : D->decls()) {
990 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
991 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000992 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000993 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000994 }
995
996 // Now sort the Decls so that they appear in lexical order.
997 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000998 [&SM](Decl *A, Decl *B) {
999 SourceLocation L_A = A->getLocStart();
1000 SourceLocation L_B = B->getLocStart();
1001 assert(L_A.isValid() && L_B.isValid());
1002 return SM.isBeforeInTranslationUnit(L_A, L_B);
1003 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001004
1005 // Now visit the decls.
1006 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1007 E = DeclsInContainer.end(); I != E; ++I) {
1008 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001009 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001010 if (!V.hasValue())
1011 continue;
1012 if (!V.getValue())
1013 return false;
1014 if (Visit(Cursor, true))
1015 return true;
1016 }
1017 return false;
1018}
1019
1020bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1021 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1022 TU)))
1023 return true;
1024
1025 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1026 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1027 E = ND->protocol_end(); I != E; ++I, ++PL)
1028 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1029 return true;
1030
1031 return VisitObjCContainerDecl(ND);
1032}
1033
1034bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1035 if (!PID->isThisDeclarationADefinition())
1036 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1037
1038 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1039 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1040 E = PID->protocol_end(); I != E; ++I, ++PL)
1041 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042 return true;
1043
1044 return VisitObjCContainerDecl(PID);
1045}
1046
1047bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1048 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1049 return true;
1050
1051 // FIXME: This implements a workaround with @property declarations also being
1052 // installed in the DeclContext for the @interface. Eventually this code
1053 // should be removed.
1054 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1055 if (!CDecl || !CDecl->IsClassExtension())
1056 return false;
1057
1058 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1059 if (!ID)
1060 return false;
1061
1062 IdentifierInfo *PropertyId = PD->getIdentifier();
1063 ObjCPropertyDecl *prevDecl =
1064 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1065
1066 if (!prevDecl)
1067 return false;
1068
1069 // Visit synthesized methods since they will be skipped when visiting
1070 // the @interface.
1071 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1072 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1073 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1074 return true;
1075
1076 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1077 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1078 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1079 return true;
1080
1081 return false;
1082}
1083
1084bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1085 if (!D->isThisDeclarationADefinition()) {
1086 // Forward declaration is treated like a reference.
1087 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1088 }
1089
1090 // Issue callbacks for super class.
1091 if (D->getSuperClass() &&
1092 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1093 D->getSuperClassLoc(),
1094 TU)))
1095 return true;
1096
1097 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1098 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1099 E = D->protocol_end(); I != E; ++I, ++PL)
1100 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1101 return true;
1102
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1107 return VisitObjCContainerDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1111 // 'ID' could be null when dealing with invalid code.
1112 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1113 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1114 return true;
1115
1116 return VisitObjCImplDecl(D);
1117}
1118
1119bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1120#if 0
1121 // Issue callbacks for super class.
1122 // FIXME: No source location information!
1123 if (D->getSuperClass() &&
1124 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125 D->getSuperClassLoc(),
1126 TU)))
1127 return true;
1128#endif
1129
1130 return VisitObjCImplDecl(D);
1131}
1132
1133bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1134 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1135 if (PD->isIvarNameSpecified())
1136 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1137
1138 return false;
1139}
1140
1141bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1142 return VisitDeclContext(D);
1143}
1144
1145bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1146 // Visit nested-name-specifier.
1147 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1148 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149 return true;
1150
1151 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1152 D->getTargetNameLoc(), TU));
1153}
1154
1155bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1156 // Visit nested-name-specifier.
1157 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1158 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1159 return true;
1160 }
1161
1162 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1163 return true;
1164
1165 return VisitDeclarationNameInfo(D->getNameInfo());
1166}
1167
1168bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1169 // Visit nested-name-specifier.
1170 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172 return true;
1173
1174 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1175 D->getIdentLocation(), TU));
1176}
1177
1178bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1179 // Visit nested-name-specifier.
1180 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1181 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1182 return true;
1183 }
1184
1185 return VisitDeclarationNameInfo(D->getNameInfo());
1186}
1187
1188bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1189 UnresolvedUsingTypenameDecl *D) {
1190 // Visit nested-name-specifier.
1191 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1192 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1193 return true;
1194
1195 return false;
1196}
1197
1198bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1199 switch (Name.getName().getNameKind()) {
1200 case clang::DeclarationName::Identifier:
1201 case clang::DeclarationName::CXXLiteralOperatorName:
1202 case clang::DeclarationName::CXXOperatorName:
1203 case clang::DeclarationName::CXXUsingDirective:
1204 return false;
1205
1206 case clang::DeclarationName::CXXConstructorName:
1207 case clang::DeclarationName::CXXDestructorName:
1208 case clang::DeclarationName::CXXConversionFunctionName:
1209 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1210 return Visit(TSInfo->getTypeLoc());
1211 return false;
1212
1213 case clang::DeclarationName::ObjCZeroArgSelector:
1214 case clang::DeclarationName::ObjCOneArgSelector:
1215 case clang::DeclarationName::ObjCMultiArgSelector:
1216 // FIXME: Per-identifier location info?
1217 return false;
1218 }
1219
1220 llvm_unreachable("Invalid DeclarationName::Kind!");
1221}
1222
1223bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1224 SourceRange Range) {
1225 // FIXME: This whole routine is a hack to work around the lack of proper
1226 // source information in nested-name-specifiers (PR5791). Since we do have
1227 // a beginning source location, we can visit the first component of the
1228 // nested-name-specifier, if it's a single-token component.
1229 if (!NNS)
1230 return false;
1231
1232 // Get the first component in the nested-name-specifier.
1233 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1234 NNS = Prefix;
1235
1236 switch (NNS->getKind()) {
1237 case NestedNameSpecifier::Namespace:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1239 TU));
1240
1241 case NestedNameSpecifier::NamespaceAlias:
1242 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1243 Range.getBegin(), TU));
1244
1245 case NestedNameSpecifier::TypeSpec: {
1246 // If the type has a form where we know that the beginning of the source
1247 // range matches up with a reference cursor. Visit the appropriate reference
1248 // cursor.
1249 const Type *T = NNS->getAsType();
1250 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1251 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1252 if (const TagType *Tag = dyn_cast<TagType>(T))
1253 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1254 if (const TemplateSpecializationType *TST
1255 = dyn_cast<TemplateSpecializationType>(T))
1256 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1257 break;
1258 }
1259
1260 case NestedNameSpecifier::TypeSpecWithTemplate:
1261 case NestedNameSpecifier::Global:
1262 case NestedNameSpecifier::Identifier:
1263 break;
1264 }
1265
1266 return false;
1267}
1268
1269bool
1270CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1271 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1272 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1273 Qualifiers.push_back(Qualifier);
1274
1275 while (!Qualifiers.empty()) {
1276 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1277 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1278 switch (NNS->getKind()) {
1279 case NestedNameSpecifier::Namespace:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::NamespaceAlias:
1288 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1289 Q.getLocalBeginLoc(),
1290 TU)))
1291 return true;
1292
1293 break;
1294
1295 case NestedNameSpecifier::TypeSpec:
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 if (Visit(Q.getTypeLoc()))
1298 return true;
1299
1300 break;
1301
1302 case NestedNameSpecifier::Global:
1303 case NestedNameSpecifier::Identifier:
1304 break;
1305 }
1306 }
1307
1308 return false;
1309}
1310
1311bool CursorVisitor::VisitTemplateParameters(
1312 const TemplateParameterList *Params) {
1313 if (!Params)
1314 return false;
1315
1316 for (TemplateParameterList::const_iterator P = Params->begin(),
1317 PEnd = Params->end();
1318 P != PEnd; ++P) {
1319 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1320 return true;
1321 }
1322
1323 return false;
1324}
1325
1326bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1327 switch (Name.getKind()) {
1328 case TemplateName::Template:
1329 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1330
1331 case TemplateName::OverloadedTemplate:
1332 // Visit the overloaded template set.
1333 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1334 return true;
1335
1336 return false;
1337
1338 case TemplateName::DependentTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return false;
1341
1342 case TemplateName::QualifiedTemplate:
1343 // FIXME: Visit nested-name-specifier.
1344 return Visit(MakeCursorTemplateRef(
1345 Name.getAsQualifiedTemplateName()->getDecl(),
1346 Loc, TU));
1347
1348 case TemplateName::SubstTemplateTemplateParm:
1349 return Visit(MakeCursorTemplateRef(
1350 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1351 Loc, TU));
1352
1353 case TemplateName::SubstTemplateTemplateParmPack:
1354 return Visit(MakeCursorTemplateRef(
1355 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1356 Loc, TU));
1357 }
1358
1359 llvm_unreachable("Invalid TemplateName::Kind!");
1360}
1361
1362bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1363 switch (TAL.getArgument().getKind()) {
1364 case TemplateArgument::Null:
1365 case TemplateArgument::Integral:
1366 case TemplateArgument::Pack:
1367 return false;
1368
1369 case TemplateArgument::Type:
1370 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1371 return Visit(TSInfo->getTypeLoc());
1372 return false;
1373
1374 case TemplateArgument::Declaration:
1375 if (Expr *E = TAL.getSourceDeclExpression())
1376 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1377 return false;
1378
1379 case TemplateArgument::NullPtr:
1380 if (Expr *E = TAL.getSourceNullPtrExpression())
1381 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1382 return false;
1383
1384 case TemplateArgument::Expression:
1385 if (Expr *E = TAL.getSourceExpression())
1386 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1387 return false;
1388
1389 case TemplateArgument::Template:
1390 case TemplateArgument::TemplateExpansion:
1391 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1392 return true;
1393
1394 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1395 TAL.getTemplateNameLoc());
1396 }
1397
1398 llvm_unreachable("Invalid TemplateArgument::Kind!");
1399}
1400
1401bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1402 return VisitDeclContext(D);
1403}
1404
1405bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1406 return Visit(TL.getUnqualifiedLoc());
1407}
1408
1409bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1410 ASTContext &Context = AU->getASTContext();
1411
1412 // Some builtin types (such as Objective-C's "id", "sel", and
1413 // "Class") have associated declarations. Create cursors for those.
1414 QualType VisitType;
1415 switch (TL.getTypePtr()->getKind()) {
1416
1417 case BuiltinType::Void:
1418 case BuiltinType::NullPtr:
1419 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001420 case BuiltinType::OCLImage1d:
1421 case BuiltinType::OCLImage1dArray:
1422 case BuiltinType::OCLImage1dBuffer:
1423 case BuiltinType::OCLImage2d:
1424 case BuiltinType::OCLImage2dArray:
1425 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001426 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001427 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001428#define BUILTIN_TYPE(Id, SingletonId)
1429#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#include "clang/AST/BuiltinTypes.def"
1434 break;
1435
1436 case BuiltinType::ObjCId:
1437 VisitType = Context.getObjCIdType();
1438 break;
1439
1440 case BuiltinType::ObjCClass:
1441 VisitType = Context.getObjCClassType();
1442 break;
1443
1444 case BuiltinType::ObjCSel:
1445 VisitType = Context.getObjCSelType();
1446 break;
1447 }
1448
1449 if (!VisitType.isNull()) {
1450 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1451 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1452 TU));
1453 }
1454
1455 return false;
1456}
1457
1458bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1463 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1464}
1465
1466bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1467 if (TL.isDefinition())
1468 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1469
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1474 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1475}
1476
1477bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1478 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1479 return true;
1480
1481 return false;
1482}
1483
1484bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1485 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1486 return true;
1487
1488 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1489 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1490 TU)))
1491 return true;
1492 }
1493
1494 return false;
1495}
1496
1497bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1502 return Visit(TL.getInnerLoc());
1503}
1504
1505bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1522 return Visit(TL.getPointeeLoc());
1523}
1524
1525bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1526 return Visit(TL.getModifiedLoc());
1527}
1528
1529bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1530 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001531 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 return true;
1533
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001534 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1535 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001536 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1537 return true;
1538
1539 return false;
1540}
1541
1542bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1543 if (Visit(TL.getElementLoc()))
1544 return true;
1545
1546 if (Expr *Size = TL.getSizeExpr())
1547 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1548
1549 return false;
1550}
1551
Reid Kleckner8a365022013-06-24 17:51:48 +00001552bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Reid Kleckner0503a872013-12-05 01:23:43 +00001556bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1557 return Visit(TL.getOriginalLoc());
1558}
1559
Guy Benyei11169dd2012-12-18 14:30:41 +00001560bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1561 TemplateSpecializationTypeLoc TL) {
1562 // Visit the template name.
1563 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1564 TL.getTemplateNameLoc()))
1565 return true;
1566
1567 // Visit the template arguments.
1568 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1569 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1570 return true;
1571
1572 return false;
1573}
1574
1575bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1576 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1577}
1578
1579bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1580 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1581 return Visit(TSInfo->getTypeLoc());
1582
1583 return false;
1584}
1585
1586bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1587 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1588 return Visit(TSInfo->getTypeLoc());
1589
1590 return false;
1591}
1592
1593bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1594 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1595 return true;
1596
1597 return false;
1598}
1599
1600bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1601 DependentTemplateSpecializationTypeLoc TL) {
1602 // Visit the nested-name-specifier, if there is one.
1603 if (TL.getQualifierLoc() &&
1604 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1605 return true;
1606
1607 // Visit the template arguments.
1608 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1609 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1610 return true;
1611
1612 return false;
1613}
1614
1615bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1616 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1617 return true;
1618
1619 return Visit(TL.getNamedTypeLoc());
1620}
1621
1622bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1623 return Visit(TL.getPatternLoc());
1624}
1625
1626bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1627 if (Expr *E = TL.getUnderlyingExpr())
1628 return Visit(MakeCXCursor(E, StmtParent, TU));
1629
1630 return false;
1631}
1632
1633bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1634 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1635}
1636
1637bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1638 return Visit(TL.getValueLoc());
1639}
1640
1641#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1642bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1643 return Visit##PARENT##Loc(TL); \
1644}
1645
1646DEFAULT_TYPELOC_IMPL(Complex, Type)
1647DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1648DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1652DEFAULT_TYPELOC_IMPL(Vector, Type)
1653DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1654DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1655DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1656DEFAULT_TYPELOC_IMPL(Record, TagType)
1657DEFAULT_TYPELOC_IMPL(Enum, TagType)
1658DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1659DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1660DEFAULT_TYPELOC_IMPL(Auto, Type)
1661
1662bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1663 // Visit the nested-name-specifier, if present.
1664 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1665 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1666 return true;
1667
1668 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001669 for (const auto &I : D->bases()) {
1670 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001671 return true;
1672 }
1673 }
1674
1675 return VisitTagDecl(D);
1676}
1677
1678bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001679 for (const auto *I : D->attrs())
1680 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001681 return true;
1682
1683 return false;
1684}
1685
1686//===----------------------------------------------------------------------===//
1687// Data-recursive visitor methods.
1688//===----------------------------------------------------------------------===//
1689
1690namespace {
1691#define DEF_JOB(NAME, DATA, KIND)\
1692class NAME : public VisitorJob {\
1693public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001694 NAME(const DATA *d, CXCursor parent) : \
1695 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001696 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001697 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001698};
1699
1700DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1701DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1702DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1703DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1704DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1705 ExplicitTemplateArgsVisitKind)
1706DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1707DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1708DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1709#undef DEF_JOB
1710
1711class DeclVisit : public VisitorJob {
1712public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001713 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001715 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 static bool classof(const VisitorJob *VJ) {
1717 return VJ->getKind() == DeclVisitKind;
1718 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001719 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001720 bool isFirst() const { return data[1] ? true : false; }
1721};
1722class TypeLocVisit : public VisitorJob {
1723public:
1724 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1725 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1726 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1727
1728 static bool classof(const VisitorJob *VJ) {
1729 return VJ->getKind() == TypeLocVisitKind;
1730 }
1731
1732 TypeLoc get() const {
1733 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001734 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 }
1736};
1737
1738class LabelRefVisit : public VisitorJob {
1739public:
1740 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1741 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1742 labelLoc.getPtrEncoding()) {}
1743
1744 static bool classof(const VisitorJob *VJ) {
1745 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1746 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 const LabelDecl *get() const {
1748 return static_cast<const LabelDecl *>(data[0]);
1749 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 SourceLocation getLoc() const {
1751 return SourceLocation::getFromPtrEncoding(data[1]); }
1752};
1753
1754class NestedNameSpecifierLocVisit : public VisitorJob {
1755public:
1756 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1757 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1758 Qualifier.getNestedNameSpecifier(),
1759 Qualifier.getOpaqueData()) { }
1760
1761 static bool classof(const VisitorJob *VJ) {
1762 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1763 }
1764
1765 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 return NestedNameSpecifierLoc(
1767 const_cast<NestedNameSpecifier *>(
1768 static_cast<const NestedNameSpecifier *>(data[0])),
1769 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 }
1771};
1772
1773class DeclarationNameInfoVisit : public VisitorJob {
1774public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001775 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001776 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001777 static bool classof(const VisitorJob *VJ) {
1778 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1779 }
1780 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001781 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 switch (S->getStmtClass()) {
1783 default:
1784 llvm_unreachable("Unhandled Stmt");
1785 case clang::Stmt::MSDependentExistsStmtClass:
1786 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1787 case Stmt::CXXDependentScopeMemberExprClass:
1788 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1789 case Stmt::DependentScopeDeclRefExprClass:
1790 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001791 case Stmt::OMPCriticalDirectiveClass:
1792 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 }
1794 }
1795};
1796class MemberRefVisit : public VisitorJob {
1797public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001799 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1800 L.getPtrEncoding()) {}
1801 static bool classof(const VisitorJob *VJ) {
1802 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1803 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804 const FieldDecl *get() const {
1805 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001806 }
1807 SourceLocation getLoc() const {
1808 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1809 }
1810};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001811class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001812 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001813 VisitorWorkList &WL;
1814 CXCursor Parent;
1815public:
1816 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1817 : WL(wl), Parent(parent) {}
1818
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001819 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1820 void VisitBlockExpr(const BlockExpr *B);
1821 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1822 void VisitCompoundStmt(const CompoundStmt *S);
1823 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1824 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1825 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1826 void VisitCXXNewExpr(const CXXNewExpr *E);
1827 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1828 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1829 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1830 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1831 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1832 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1833 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1834 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1835 void VisitDeclRefExpr(const DeclRefExpr *D);
1836 void VisitDeclStmt(const DeclStmt *S);
1837 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1838 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1839 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1840 void VisitForStmt(const ForStmt *FS);
1841 void VisitGotoStmt(const GotoStmt *GS);
1842 void VisitIfStmt(const IfStmt *If);
1843 void VisitInitListExpr(const InitListExpr *IE);
1844 void VisitMemberExpr(const MemberExpr *M);
1845 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1846 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1847 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1848 void VisitOverloadExpr(const OverloadExpr *E);
1849 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1850 void VisitStmt(const Stmt *S);
1851 void VisitSwitchStmt(const SwitchStmt *S);
1852 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1854 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1855 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1856 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1857 void VisitVAArgExpr(const VAArgExpr *E);
1858 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1859 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1860 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1861 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001862 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001863 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001865 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001866 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001867 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001868 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001869 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001870 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001871 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001872 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001873 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001874 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001875 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001876 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001877 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001878 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001879 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001880 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001881 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001882
Guy Benyei11169dd2012-12-18 14:30:41 +00001883private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1886 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1888 void AddStmt(const Stmt *S);
1889 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001892 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001893};
1894} // end anonyous namespace
1895
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001897 // 'S' should always be non-null, since it comes from the
1898 // statement we are visiting.
1899 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1900}
1901
1902void
1903EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1904 if (Qualifier)
1905 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1906}
1907
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001909 if (S)
1910 WL.push_back(StmtVisit(S, Parent));
1911}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001912void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001913 if (D)
1914 WL.push_back(DeclVisit(D, Parent, isFirst));
1915}
1916void EnqueueVisitor::
1917 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1918 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001919 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001920}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001921void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001922 if (D)
1923 WL.push_back(MemberRefVisit(D, L, Parent));
1924}
1925void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1926 if (TI)
1927 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1928 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001929void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001930 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001931 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001932 AddStmt(*Child);
1933 }
1934 if (size == WL.size())
1935 return;
1936 // Now reverse the entries we just added. This will match the DFS
1937 // ordering performed by the worklist.
1938 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1939 std::reverse(I, E);
1940}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001941namespace {
1942class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1943 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001944 /// \brief Process clauses with list of variables.
1945 template <typename T>
1946 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947public:
1948 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1949#define OPENMP_CLAUSE(Name, Class) \
1950 void Visit##Class(const Class *C);
1951#include "clang/Basic/OpenMPKinds.def"
1952};
1953
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001954void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1955 Visitor->AddStmt(C->getCondition());
1956}
1957
Alexey Bataev3778b602014-07-17 07:32:53 +00001958void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1959 Visitor->AddStmt(C->getCondition());
1960}
1961
Alexey Bataev568a8332014-03-06 06:15:19 +00001962void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1963 Visitor->AddStmt(C->getNumThreads());
1964}
1965
Alexey Bataev62c87d22014-03-21 04:51:18 +00001966void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1967 Visitor->AddStmt(C->getSafelen());
1968}
1969
Alexander Musman8bd31e62014-05-27 15:12:19 +00001970void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1971 Visitor->AddStmt(C->getNumForLoops());
1972}
1973
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001974void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001975
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001976void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1977
Alexey Bataev56dafe82014-06-20 07:16:17 +00001978void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1979 Visitor->AddStmt(C->getChunkSize());
1980}
1981
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001982void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1983
Alexey Bataev236070f2014-06-20 11:19:47 +00001984void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1985
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001986void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1987
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001988void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1989
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001990void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1991
Alexey Bataevdea47612014-07-23 07:46:59 +00001992void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1993
Alexey Bataev67a4f222014-07-23 10:25:33 +00001994void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
1995
Alexey Bataev459dec02014-07-24 06:46:57 +00001996void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
1997
Alexey Bataev82bad8b2014-07-24 08:55:34 +00001998void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
1999
Alexey Bataev756c1962013-09-24 03:17:45 +00002000template<typename T>
2001void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002002 for (const auto *I : Node->varlists())
2003 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00002004}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002005
2006void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002007 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002008}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002009void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2010 const OMPFirstprivateClause *C) {
2011 VisitOMPClauseList(C);
2012}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002013void OMPClauseEnqueue::VisitOMPLastprivateClause(
2014 const OMPLastprivateClause *C) {
2015 VisitOMPClauseList(C);
2016}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002017void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002018 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002019}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002020void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2021 VisitOMPClauseList(C);
2022}
Alexander Musman8dba6642014-04-22 13:09:42 +00002023void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2024 VisitOMPClauseList(C);
2025 Visitor->AddStmt(C->getStep());
2026}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002027void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2028 VisitOMPClauseList(C);
2029 Visitor->AddStmt(C->getAlignment());
2030}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002031void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2032 VisitOMPClauseList(C);
2033}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002034void
2035OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2036 VisitOMPClauseList(C);
2037}
Alexey Bataev6125da92014-07-21 11:26:11 +00002038void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2039 VisitOMPClauseList(C);
2040}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002041}
Alexey Bataev756c1962013-09-24 03:17:45 +00002042
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002043void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2044 unsigned size = WL.size();
2045 OMPClauseEnqueue Visitor(this);
2046 Visitor.Visit(S);
2047 if (size == WL.size())
2048 return;
2049 // Now reverse the entries we just added. This will match the DFS
2050 // ordering performed by the worklist.
2051 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2052 std::reverse(I, E);
2053}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2056}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002057void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002058 AddDecl(B->getBlockDecl());
2059}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002060void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002061 EnqueueChildren(E);
2062 AddTypeLoc(E->getTypeSourceInfo());
2063}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2065 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 E = S->body_rend(); I != E; ++I) {
2067 AddStmt(*I);
2068 }
2069}
2070void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002071VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002072 AddStmt(S->getSubStmt());
2073 AddDeclarationNameInfo(S);
2074 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2075 AddNestedNameSpecifierLoc(QualifierLoc);
2076}
2077
2078void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2081 AddDeclarationNameInfo(E);
2082 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2083 AddNestedNameSpecifierLoc(QualifierLoc);
2084 if (!E->isImplicitAccess())
2085 AddStmt(E->getBase());
2086}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002087void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002088 // Enqueue the initializer , if any.
2089 AddStmt(E->getInitializer());
2090 // Enqueue the array size, if any.
2091 AddStmt(E->getArraySize());
2092 // Enqueue the allocated type.
2093 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2094 // Enqueue the placement arguments.
2095 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2096 AddStmt(E->getPlacementArg(I-1));
2097}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2100 AddStmt(CE->getArg(I-1));
2101 AddStmt(CE->getCallee());
2102 AddStmt(CE->getArg(0));
2103}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002104void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2105 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002106 // Visit the name of the type being destroyed.
2107 AddTypeLoc(E->getDestroyedTypeInfo());
2108 // Visit the scope type that looks disturbingly like the nested-name-specifier
2109 // but isn't.
2110 AddTypeLoc(E->getScopeTypeInfo());
2111 // Visit the nested-name-specifier.
2112 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2113 AddNestedNameSpecifierLoc(QualifierLoc);
2114 // Visit base expression.
2115 AddStmt(E->getBase());
2116}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002117void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2118 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 AddTypeLoc(E->getTypeSourceInfo());
2120}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2122 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 EnqueueChildren(E);
2124 AddTypeLoc(E->getTypeSourceInfo());
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 EnqueueChildren(E);
2128 if (E->isTypeOperand())
2129 AddTypeLoc(E->getTypeOperandSourceInfo());
2130}
2131
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2133 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002134 EnqueueChildren(E);
2135 AddTypeLoc(E->getTypeSourceInfo());
2136}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 EnqueueChildren(E);
2139 if (E->isTypeOperand())
2140 AddTypeLoc(E->getTypeOperandSourceInfo());
2141}
2142
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002143void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002144 EnqueueChildren(S);
2145 AddDecl(S->getExceptionDecl());
2146}
2147
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002149 if (DR->hasExplicitTemplateArgs()) {
2150 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2151 }
2152 WL.push_back(DeclRefExprParts(DR, Parent));
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2155 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2157 AddDeclarationNameInfo(E);
2158 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2159}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002160void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002161 unsigned size = WL.size();
2162 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002163 for (const auto *D : S->decls()) {
2164 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 isFirst = false;
2166 }
2167 if (size == WL.size())
2168 return;
2169 // Now reverse the entries we just added. This will match the DFS
2170 // ordering performed by the worklist.
2171 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2172 std::reverse(I, E);
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002176 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002177 D = E->designators_rbegin(), DEnd = E->designators_rend();
2178 D != DEnd; ++D) {
2179 if (D->isFieldDesignator()) {
2180 if (FieldDecl *Field = D->getField())
2181 AddMemberRef(Field, D->getFieldLoc());
2182 continue;
2183 }
2184 if (D->isArrayDesignator()) {
2185 AddStmt(E->getArrayIndex(*D));
2186 continue;
2187 }
2188 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2189 AddStmt(E->getArrayRangeEnd(*D));
2190 AddStmt(E->getArrayRangeStart(*D));
2191 }
2192}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 EnqueueChildren(E);
2195 AddTypeLoc(E->getTypeInfoAsWritten());
2196}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 AddStmt(FS->getBody());
2199 AddStmt(FS->getInc());
2200 AddStmt(FS->getCond());
2201 AddDecl(FS->getConditionVariable());
2202 AddStmt(FS->getInit());
2203}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002205 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2206}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 AddStmt(If->getElse());
2209 AddStmt(If->getThen());
2210 AddStmt(If->getCond());
2211 AddDecl(If->getConditionVariable());
2212}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 // We care about the syntactic form of the initializer list, only.
2215 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2216 IE = Syntactic;
2217 EnqueueChildren(IE);
2218}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 WL.push_back(MemberExprParts(M, Parent));
2221
2222 // If the base of the member access expression is an implicit 'this', don't
2223 // visit it.
2224 // FIXME: If we ever want to show these implicit accesses, this will be
2225 // unfortunate. However, clang_getCursor() relies on this behavior.
2226 if (!M->isImplicitAccess())
2227 AddStmt(M->getBase());
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 AddTypeLoc(E->getEncodedTypeSourceInfo());
2231}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 EnqueueChildren(M);
2234 AddTypeLoc(M->getClassReceiverTypeInfo());
2235}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 // Visit the components of the offsetof expression.
2238 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2239 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2240 const OffsetOfNode &Node = E->getComponent(I-1);
2241 switch (Node.getKind()) {
2242 case OffsetOfNode::Array:
2243 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2244 break;
2245 case OffsetOfNode::Field:
2246 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2247 break;
2248 case OffsetOfNode::Identifier:
2249 case OffsetOfNode::Base:
2250 continue;
2251 }
2252 }
2253 // Visit the type into which we're computing the offset.
2254 AddTypeLoc(E->getTypeSourceInfo());
2255}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002256void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2258 WL.push_back(OverloadExprParts(E, Parent));
2259}
2260void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 EnqueueChildren(E);
2263 if (E->isArgumentType())
2264 AddTypeLoc(E->getArgumentTypeInfo());
2265}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002266void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002267 EnqueueChildren(S);
2268}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002269void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 AddStmt(S->getBody());
2271 AddStmt(S->getCond());
2272 AddDecl(S->getConditionVariable());
2273}
2274
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002276 AddStmt(W->getBody());
2277 AddStmt(W->getCond());
2278 AddDecl(W->getConditionVariable());
2279}
2280
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002281void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002282 for (unsigned I = E->getNumArgs(); I > 0; --I)
2283 AddTypeLoc(E->getArg(I-1));
2284}
2285
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002286void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002287 AddTypeLoc(E->getQueriedTypeSourceInfo());
2288}
2289
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002290void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002291 EnqueueChildren(E);
2292}
2293
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 VisitOverloadExpr(U);
2296 if (!U->isImplicitAccess())
2297 AddStmt(U->getBase());
2298}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002299void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002300 AddStmt(E->getSubExpr());
2301 AddTypeLoc(E->getWrittenTypeInfo());
2302}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002303void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002304 WL.push_back(SizeOfPackExprParts(E, Parent));
2305}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002306void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002307 // If the opaque value has a source expression, just transparently
2308 // visit that. This is useful for (e.g.) pseudo-object expressions.
2309 if (Expr *SourceExpr = E->getSourceExpr())
2310 return Visit(SourceExpr);
2311}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 AddStmt(E->getBody());
2314 WL.push_back(LambdaExprParts(E, Parent));
2315}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002316void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002317 // Treat the expression like its syntactic form.
2318 Visit(E->getSyntacticForm());
2319}
2320
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002321void EnqueueVisitor::VisitOMPExecutableDirective(
2322 const OMPExecutableDirective *D) {
2323 EnqueueChildren(D);
2324 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2325 E = D->clauses().end();
2326 I != E; ++I)
2327 EnqueueChildren(*I);
2328}
2329
Alexander Musman3aaab662014-08-19 11:27:13 +00002330void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2331 VisitOMPExecutableDirective(D);
2332}
2333
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002334void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2335 VisitOMPExecutableDirective(D);
2336}
2337
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002338void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002339 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002340}
2341
Alexey Bataevf29276e2014-06-18 04:14:57 +00002342void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002343 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002344}
2345
Alexander Musmanf82886e2014-09-18 05:12:34 +00002346void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2347 VisitOMPLoopDirective(D);
2348}
2349
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002350void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2351 VisitOMPExecutableDirective(D);
2352}
2353
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002354void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2355 VisitOMPExecutableDirective(D);
2356}
2357
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002358void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2359 VisitOMPExecutableDirective(D);
2360}
2361
Alexander Musman80c22892014-07-17 08:54:58 +00002362void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2363 VisitOMPExecutableDirective(D);
2364}
2365
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002366void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2367 VisitOMPExecutableDirective(D);
2368 AddDeclarationNameInfo(D);
2369}
2370
Alexey Bataev4acb8592014-07-07 13:01:15 +00002371void
2372EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002373 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002374}
2375
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002376void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2377 const OMPParallelSectionsDirective *D) {
2378 VisitOMPExecutableDirective(D);
2379}
2380
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002381void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2382 VisitOMPExecutableDirective(D);
2383}
2384
Alexey Bataev68446b72014-07-18 07:47:19 +00002385void
2386EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2387 VisitOMPExecutableDirective(D);
2388}
2389
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002390void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2391 VisitOMPExecutableDirective(D);
2392}
2393
Alexey Bataev2df347a2014-07-18 10:17:07 +00002394void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2395 VisitOMPExecutableDirective(D);
2396}
2397
Alexey Bataev6125da92014-07-21 11:26:11 +00002398void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2399 VisitOMPExecutableDirective(D);
2400}
2401
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002402void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2403 VisitOMPExecutableDirective(D);
2404}
2405
Alexey Bataev0162e452014-07-22 10:10:35 +00002406void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2407 VisitOMPExecutableDirective(D);
2408}
2409
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002410void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002411 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2412}
2413
2414bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2415 if (RegionOfInterest.isValid()) {
2416 SourceRange Range = getRawCursorExtent(C);
2417 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2418 return false;
2419 }
2420 return true;
2421}
2422
2423bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2424 while (!WL.empty()) {
2425 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002426 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002427
2428 // Set the Parent field, then back to its old value once we're done.
2429 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2430
2431 switch (LI.getKind()) {
2432 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002433 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 if (!D)
2435 continue;
2436
2437 // For now, perform default visitation for Decls.
2438 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2439 cast<DeclVisit>(&LI)->isFirst())))
2440 return true;
2441
2442 continue;
2443 }
2444 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2445 const ASTTemplateArgumentListInfo *ArgList =
2446 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2447 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2448 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2449 Arg != ArgEnd; ++Arg) {
2450 if (VisitTemplateArgumentLoc(*Arg))
2451 return true;
2452 }
2453 continue;
2454 }
2455 case VisitorJob::TypeLocVisitKind: {
2456 // Perform default visitation for TypeLocs.
2457 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2458 return true;
2459 continue;
2460 }
2461 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002462 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 if (LabelStmt *stmt = LS->getStmt()) {
2464 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2465 TU))) {
2466 return true;
2467 }
2468 }
2469 continue;
2470 }
2471
2472 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2473 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2474 if (VisitNestedNameSpecifierLoc(V->get()))
2475 return true;
2476 continue;
2477 }
2478
2479 case VisitorJob::DeclarationNameInfoVisitKind: {
2480 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2481 ->get()))
2482 return true;
2483 continue;
2484 }
2485 case VisitorJob::MemberRefVisitKind: {
2486 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2487 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2488 return true;
2489 continue;
2490 }
2491 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002492 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002493 if (!S)
2494 continue;
2495
2496 // Update the current cursor.
2497 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2498 if (!IsInRegionOfInterest(Cursor))
2499 continue;
2500 switch (Visitor(Cursor, Parent, ClientData)) {
2501 case CXChildVisit_Break: return true;
2502 case CXChildVisit_Continue: break;
2503 case CXChildVisit_Recurse:
2504 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002505 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002506 EnqueueWorkList(WL, S);
2507 break;
2508 }
2509 continue;
2510 }
2511 case VisitorJob::MemberExprPartsKind: {
2512 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002513 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002514
2515 // Visit the nested-name-specifier
2516 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2517 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2518 return true;
2519
2520 // Visit the declaration name.
2521 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2522 return true;
2523
2524 // Visit the explicitly-specified template arguments, if any.
2525 if (M->hasExplicitTemplateArgs()) {
2526 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2527 *ArgEnd = Arg + M->getNumTemplateArgs();
2528 Arg != ArgEnd; ++Arg) {
2529 if (VisitTemplateArgumentLoc(*Arg))
2530 return true;
2531 }
2532 }
2533 continue;
2534 }
2535 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002536 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002537 // Visit nested-name-specifier, if present.
2538 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2539 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2540 return true;
2541 // Visit declaration name.
2542 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2543 return true;
2544 continue;
2545 }
2546 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002547 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002548 // Visit the nested-name-specifier.
2549 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2550 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2551 return true;
2552 // Visit the declaration name.
2553 if (VisitDeclarationNameInfo(O->getNameInfo()))
2554 return true;
2555 // Visit the overloaded declaration reference.
2556 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2557 return true;
2558 continue;
2559 }
2560 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002561 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002562 NamedDecl *Pack = E->getPack();
2563 if (isa<TemplateTypeParmDecl>(Pack)) {
2564 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2565 E->getPackLoc(), TU)))
2566 return true;
2567
2568 continue;
2569 }
2570
2571 if (isa<TemplateTemplateParmDecl>(Pack)) {
2572 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2573 E->getPackLoc(), TU)))
2574 return true;
2575
2576 continue;
2577 }
2578
2579 // Non-type template parameter packs and function parameter packs are
2580 // treated like DeclRefExpr cursors.
2581 continue;
2582 }
2583
2584 case VisitorJob::LambdaExprPartsKind: {
2585 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002586 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002587 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2588 CEnd = E->explicit_capture_end();
2589 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002590 // FIXME: Lambda init-captures.
2591 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002592 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002593
Guy Benyei11169dd2012-12-18 14:30:41 +00002594 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2595 C->getLocation(),
2596 TU)))
2597 return true;
2598 }
2599
2600 // Visit parameters and return type, if present.
2601 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2602 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2603 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2604 // Visit the whole type.
2605 if (Visit(TL))
2606 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002607 } else if (FunctionProtoTypeLoc Proto =
2608 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002609 if (E->hasExplicitParameters()) {
2610 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002611 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2612 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002613 return true;
2614 } else {
2615 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002616 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002617 return true;
2618 }
2619 }
2620 }
2621 break;
2622 }
2623
2624 case VisitorJob::PostChildrenVisitKind:
2625 if (PostChildrenVisitor(Parent, ClientData))
2626 return true;
2627 break;
2628 }
2629 }
2630 return false;
2631}
2632
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002633bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002634 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002635 if (!WorkListFreeList.empty()) {
2636 WL = WorkListFreeList.back();
2637 WL->clear();
2638 WorkListFreeList.pop_back();
2639 }
2640 else {
2641 WL = new VisitorWorkList();
2642 WorkListCache.push_back(WL);
2643 }
2644 EnqueueWorkList(*WL, S);
2645 bool result = RunVisitorWorkList(*WL);
2646 WorkListFreeList.push_back(WL);
2647 return result;
2648}
2649
2650namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002651typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002652RefNamePieces
2653buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2654 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2655 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002656 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2657 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2658 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2659
2660 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2661
2662 RefNamePieces Pieces;
2663
2664 if (WantQualifier && QLoc.isValid())
2665 Pieces.push_back(QLoc);
2666
2667 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2668 Pieces.push_back(NI.getLoc());
2669
2670 if (WantTemplateArgs && TemplateArgs)
2671 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2672 TemplateArgs->RAngleLoc));
2673
2674 if (Kind == DeclarationName::CXXOperatorName) {
2675 Pieces.push_back(SourceLocation::getFromRawEncoding(
2676 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2677 Pieces.push_back(SourceLocation::getFromRawEncoding(
2678 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2679 }
2680
2681 if (WantSinglePiece) {
2682 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2683 Pieces.clear();
2684 Pieces.push_back(R);
2685 }
2686
2687 return Pieces;
2688}
2689}
2690
2691//===----------------------------------------------------------------------===//
2692// Misc. API hooks.
2693//===----------------------------------------------------------------------===//
2694
Chad Rosier05c71aa2013-03-27 18:28:23 +00002695static void fatal_error_handler(void *user_data, const std::string& reason,
2696 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002697 // Write the result out to stderr avoiding errs() because raw_ostreams can
2698 // call report_fatal_error.
2699 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2700 ::abort();
2701}
2702
Chandler Carruth66660742014-06-27 16:37:27 +00002703namespace {
2704struct RegisterFatalErrorHandler {
2705 RegisterFatalErrorHandler() {
2706 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2707 }
2708};
2709}
2710
2711static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2712
Guy Benyei11169dd2012-12-18 14:30:41 +00002713extern "C" {
2714CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2715 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002716 // We use crash recovery to make some of our APIs more reliable, implicitly
2717 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002718 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2719 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002720
Chandler Carruth66660742014-06-27 16:37:27 +00002721 // Look through the managed static to trigger construction of the managed
2722 // static which registers our fatal error handler. This ensures it is only
2723 // registered once.
2724 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002725
2726 CIndexer *CIdxr = new CIndexer();
2727 if (excludeDeclarationsFromPCH)
2728 CIdxr->setOnlyLocalDecls();
2729 if (displayDiagnostics)
2730 CIdxr->setDisplayDiagnostics();
2731
2732 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2733 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2734 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2735 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2736 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2737 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2738
2739 return CIdxr;
2740}
2741
2742void clang_disposeIndex(CXIndex CIdx) {
2743 if (CIdx)
2744 delete static_cast<CIndexer *>(CIdx);
2745}
2746
2747void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2748 if (CIdx)
2749 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2750}
2751
2752unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2753 if (CIdx)
2754 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2755 return 0;
2756}
2757
2758void clang_toggleCrashRecovery(unsigned isEnabled) {
2759 if (isEnabled)
2760 llvm::CrashRecoveryContext::Enable();
2761 else
2762 llvm::CrashRecoveryContext::Disable();
2763}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002764
Guy Benyei11169dd2012-12-18 14:30:41 +00002765CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2766 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002767 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002768 enum CXErrorCode Result =
2769 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002770 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002771 assert((TU && Result == CXError_Success) ||
2772 (!TU && Result != CXError_Success));
2773 return TU;
2774}
2775
2776enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2777 const char *ast_filename,
2778 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002779 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002780 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002781
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002782 if (!CIdx || !ast_filename || !out_TU)
2783 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002784
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002785 LOG_FUNC_SECTION {
2786 *Log << ast_filename;
2787 }
2788
Guy Benyei11169dd2012-12-18 14:30:41 +00002789 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2790 FileSystemOptions FileSystemOpts;
2791
2792 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
David Blaikie6f7382d2014-08-10 19:08:04 +00002793 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2794 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2795 /*CaptureDiagnostics=*/true,
2796 /*AllowPCHWithCompilerErrors=*/true,
2797 /*UserFilesAreVolatile=*/true);
2798 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002799 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002800}
2801
2802unsigned clang_defaultEditingTranslationUnitOptions() {
2803 return CXTranslationUnit_PrecompiledPreamble |
2804 CXTranslationUnit_CacheCompletionResults;
2805}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002806
Guy Benyei11169dd2012-12-18 14:30:41 +00002807CXTranslationUnit
2808clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2809 const char *source_filename,
2810 int num_command_line_args,
2811 const char * const *command_line_args,
2812 unsigned num_unsaved_files,
2813 struct CXUnsavedFile *unsaved_files) {
2814 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2815 return clang_parseTranslationUnit(CIdx, source_filename,
2816 command_line_args, num_command_line_args,
2817 unsaved_files, num_unsaved_files,
2818 Options);
2819}
2820
2821struct ParseTranslationUnitInfo {
2822 CXIndex CIdx;
2823 const char *source_filename;
2824 const char *const *command_line_args;
2825 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002826 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002827 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002828 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002829 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002830};
2831static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002832 const ParseTranslationUnitInfo *PTUI =
2833 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002834 CXIndex CIdx = PTUI->CIdx;
2835 const char *source_filename = PTUI->source_filename;
2836 const char * const *command_line_args = PTUI->command_line_args;
2837 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002838 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002839 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002840
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002841 // Set up the initial return values.
2842 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002843 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002844
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002845 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002846 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002847 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002848 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002849 }
2850
Guy Benyei11169dd2012-12-18 14:30:41 +00002851 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2852
2853 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2854 setThreadBackgroundPriority();
2855
2856 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2857 // FIXME: Add a flag for modules.
2858 TranslationUnitKind TUKind
2859 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002860 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002861 = options & CXTranslationUnit_CacheCompletionResults;
2862 bool IncludeBriefCommentsInCodeCompletion
2863 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2864 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2865 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2866
2867 // Configure the diagnostics.
2868 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002869 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002870
2871 // Recover resources if we crash before exiting this function.
2872 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2873 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002874 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002875
Ahmed Charlesb8984322014-03-07 20:03:18 +00002876 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2877 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002878
2879 // Recover resources if we crash before exiting this function.
2880 llvm::CrashRecoveryContextCleanupRegistrar<
2881 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2882
Alp Toker9d85b182014-07-07 01:23:14 +00002883 for (auto &UF : PTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002884 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00002885 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00002886 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00002887 }
2888
Ahmed Charlesb8984322014-03-07 20:03:18 +00002889 std::unique_ptr<std::vector<const char *>> Args(
2890 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002891
2892 // Recover resources if we crash before exiting this method.
2893 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2894 ArgsCleanup(Args.get());
2895
2896 // Since the Clang C library is primarily used by batch tools dealing with
2897 // (often very broken) source code, where spell-checking can have a
2898 // significant negative impact on performance (particularly when
2899 // precompiled headers are involved), we disable it by default.
2900 // Only do this if we haven't found a spell-checking-related argument.
2901 bool FoundSpellCheckingArgument = false;
2902 for (int I = 0; I != num_command_line_args; ++I) {
2903 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2904 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2905 FoundSpellCheckingArgument = true;
2906 break;
2907 }
2908 }
2909 if (!FoundSpellCheckingArgument)
2910 Args->push_back("-fno-spell-checking");
2911
2912 Args->insert(Args->end(), command_line_args,
2913 command_line_args + num_command_line_args);
2914
2915 // The 'source_filename' argument is optional. If the caller does not
2916 // specify it then it is assumed that the source file is specified
2917 // in the actual argument list.
2918 // Put the source file after command_line_args otherwise if '-x' flag is
2919 // present it will be unused.
2920 if (source_filename)
2921 Args->push_back(source_filename);
2922
2923 // Do we need the detailed preprocessing record?
2924 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2925 Args->push_back("-Xclang");
2926 Args->push_back("-detailed-preprocessing-record");
2927 }
2928
2929 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002930 std::unique_ptr<ASTUnit> ErrUnit;
2931 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002932 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002933 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2934 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2935 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2936 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2937 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2938 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002939
2940 if (NumErrors != Diags->getClient()->getNumErrors()) {
2941 // Make sure to check that 'Unit' is non-NULL.
2942 if (CXXIdx->getDisplayDiagnostics())
2943 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2944 }
2945
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002946 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2947 PTUI->result = CXError_ASTReadError;
2948 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002949 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002950 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2951 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002952}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002953
2954CXTranslationUnit
2955clang_parseTranslationUnit(CXIndex CIdx,
2956 const char *source_filename,
2957 const char *const *command_line_args,
2958 int num_command_line_args,
2959 struct CXUnsavedFile *unsaved_files,
2960 unsigned num_unsaved_files,
2961 unsigned options) {
2962 CXTranslationUnit TU;
2963 enum CXErrorCode Result = clang_parseTranslationUnit2(
2964 CIdx, source_filename, command_line_args, num_command_line_args,
2965 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002966 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002967 assert((TU && Result == CXError_Success) ||
2968 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002969 return TU;
2970}
2971
2972enum CXErrorCode clang_parseTranslationUnit2(
2973 CXIndex CIdx,
2974 const char *source_filename,
2975 const char *const *command_line_args,
2976 int num_command_line_args,
2977 struct CXUnsavedFile *unsaved_files,
2978 unsigned num_unsaved_files,
2979 unsigned options,
2980 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002981 LOG_FUNC_SECTION {
2982 *Log << source_filename << ": ";
2983 for (int i = 0; i != num_command_line_args; ++i)
2984 *Log << command_line_args[i] << " ";
2985 }
2986
Alp Toker9d85b182014-07-07 01:23:14 +00002987 if (num_unsaved_files && !unsaved_files)
2988 return CXError_InvalidArguments;
2989
Alp Toker5c532982014-07-07 22:42:03 +00002990 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002991 ParseTranslationUnitInfo PTUI = {
2992 CIdx,
2993 source_filename,
2994 command_line_args,
2995 num_command_line_args,
2996 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2997 options,
2998 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002999 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003000 llvm::CrashRecoveryContext CRC;
3001
3002 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3003 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3004 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3005 fprintf(stderr, " 'command_line_args' : [");
3006 for (int i = 0; i != num_command_line_args; ++i) {
3007 if (i)
3008 fprintf(stderr, ", ");
3009 fprintf(stderr, "'%s'", command_line_args[i]);
3010 }
3011 fprintf(stderr, "],\n");
3012 fprintf(stderr, " 'unsaved_files' : [");
3013 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3014 if (i)
3015 fprintf(stderr, ", ");
3016 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3017 unsaved_files[i].Length);
3018 }
3019 fprintf(stderr, "],\n");
3020 fprintf(stderr, " 'options' : %d,\n", options);
3021 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003022
3023 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003024 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003025 if (CXTranslationUnit *TU = PTUI.out_TU)
3026 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003027 }
Alp Toker5c532982014-07-07 22:42:03 +00003028
3029 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003030}
3031
3032unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3033 return CXSaveTranslationUnit_None;
3034}
3035
3036namespace {
3037
3038struct SaveTranslationUnitInfo {
3039 CXTranslationUnit TU;
3040 const char *FileName;
3041 unsigned options;
3042 CXSaveError result;
3043};
3044
3045}
3046
3047static void clang_saveTranslationUnit_Impl(void *UserData) {
3048 SaveTranslationUnitInfo *STUI =
3049 static_cast<SaveTranslationUnitInfo*>(UserData);
3050
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003051 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003052 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3053 setThreadBackgroundPriority();
3054
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003055 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003056 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3057}
3058
3059int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3060 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003061 LOG_FUNC_SECTION {
3062 *Log << TU << ' ' << FileName;
3063 }
3064
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003065 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003066 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003067 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003068 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003069
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003070 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003071 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3072 if (!CXXUnit->hasSema())
3073 return CXSaveError_InvalidTU;
3074
3075 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3076
3077 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3078 getenv("LIBCLANG_NOTHREADS")) {
3079 clang_saveTranslationUnit_Impl(&STUI);
3080
3081 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3082 PrintLibclangResourceUsage(TU);
3083
3084 return STUI.result;
3085 }
3086
3087 // We have an AST that has invalid nodes due to compiler errors.
3088 // Use a crash recovery thread for protection.
3089
3090 llvm::CrashRecoveryContext CRC;
3091
3092 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3093 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3094 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3095 fprintf(stderr, " 'options' : %d,\n", options);
3096 fprintf(stderr, "}\n");
3097
3098 return CXSaveError_Unknown;
3099
3100 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3101 PrintLibclangResourceUsage(TU);
3102 }
3103
3104 return STUI.result;
3105}
3106
3107void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3108 if (CTUnit) {
3109 // If the translation unit has been marked as unsafe to free, just discard
3110 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003111 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3112 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003113 return;
3114
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003115 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003116 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003117 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3118 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003119 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003120 delete CTUnit;
3121 }
3122}
3123
3124unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3125 return CXReparse_None;
3126}
3127
3128struct ReparseTranslationUnitInfo {
3129 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003130 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003131 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003132 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003133};
3134
3135static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003136 const ReparseTranslationUnitInfo *RTUI =
3137 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003139 unsigned options = RTUI->options;
3140 (void) options;
3141
3142 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003143 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003144 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003145 RTUI->result = CXError_InvalidArguments;
3146 return;
3147 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003148
3149 // Reset the associated diagnostics.
3150 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003151 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003152
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003153 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003154 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3155 setThreadBackgroundPriority();
3156
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003157 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003159
3160 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3161 new std::vector<ASTUnit::RemappedFile>());
3162
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 // Recover resources if we crash before exiting this function.
3164 llvm::CrashRecoveryContextCleanupRegistrar<
3165 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003166
3167 for (auto &UF : RTUI->unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003168 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003169 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003170 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003172
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003173 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003174 RTUI->result = CXError_Success;
3175 else if (isASTReadError(CXXUnit))
3176 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003177}
3178
3179int clang_reparseTranslationUnit(CXTranslationUnit TU,
3180 unsigned num_unsaved_files,
3181 struct CXUnsavedFile *unsaved_files,
3182 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003183 LOG_FUNC_SECTION {
3184 *Log << TU;
3185 }
3186
Alp Toker9d85b182014-07-07 01:23:14 +00003187 if (num_unsaved_files && !unsaved_files)
3188 return CXError_InvalidArguments;
3189
Alp Toker5c532982014-07-07 22:42:03 +00003190 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003191 ReparseTranslationUnitInfo RTUI = {
3192 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003193 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003194
3195 if (getenv("LIBCLANG_NOTHREADS")) {
3196 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003197 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 }
3199
3200 llvm::CrashRecoveryContext CRC;
3201
3202 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3203 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003204 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003205 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3207 PrintLibclangResourceUsage(TU);
3208
Alp Toker5c532982014-07-07 22:42:03 +00003209 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003210}
3211
3212
3213CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003214 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003215 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003216 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003217 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003218
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003219 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003220 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003221}
3222
3223CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003224 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003225 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003226 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003227 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003228
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003229 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003230 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3231}
3232
3233} // end: extern "C"
3234
3235//===----------------------------------------------------------------------===//
3236// CXFile Operations.
3237//===----------------------------------------------------------------------===//
3238
3239extern "C" {
3240CXString clang_getFileName(CXFile SFile) {
3241 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003242 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003243
3244 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003245 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003246}
3247
3248time_t clang_getFileTime(CXFile SFile) {
3249 if (!SFile)
3250 return 0;
3251
3252 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3253 return FEnt->getModificationTime();
3254}
3255
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003256CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003257 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003258 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003259 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003260 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003261
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003262 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003263
3264 FileManager &FMgr = CXXUnit->getFileManager();
3265 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3266}
3267
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003268unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3269 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003270 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003271 LOG_BAD_TU(TU);
3272 return 0;
3273 }
3274
3275 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 return 0;
3277
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003278 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003279 FileEntry *FEnt = static_cast<FileEntry *>(file);
3280 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3281 .isFileMultipleIncludeGuarded(FEnt);
3282}
3283
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003284int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3285 if (!file || !outID)
3286 return 1;
3287
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003288 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003289 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3290 outID->data[0] = ID.getDevice();
3291 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003292 outID->data[2] = FEnt->getModificationTime();
3293 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003294}
3295
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003296int clang_File_isEqual(CXFile file1, CXFile file2) {
3297 if (file1 == file2)
3298 return true;
3299
3300 if (!file1 || !file2)
3301 return false;
3302
3303 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3304 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3305 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3306}
3307
Guy Benyei11169dd2012-12-18 14:30:41 +00003308} // end: extern "C"
3309
3310//===----------------------------------------------------------------------===//
3311// CXCursor Operations.
3312//===----------------------------------------------------------------------===//
3313
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003314static const Decl *getDeclFromExpr(const Stmt *E) {
3315 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 return getDeclFromExpr(CE->getSubExpr());
3317
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003318 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003320 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003322 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003324 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 if (PRE->isExplicitProperty())
3326 return PRE->getExplicitProperty();
3327 // It could be messaging both getter and setter as in:
3328 // ++myobj.myprop;
3329 // in which case prefer to associate the setter since it is less obvious
3330 // from inspecting the source that the setter is going to get called.
3331 if (PRE->isMessagingSetter())
3332 return PRE->getImplicitPropertySetter();
3333 return PRE->getImplicitPropertyGetter();
3334 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003335 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003337 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 if (Expr *Src = OVE->getSourceExpr())
3339 return getDeclFromExpr(Src);
3340
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003341 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003343 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 if (!CE->isElidable())
3345 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003346 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 return OME->getMethodDecl();
3348
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003349 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003351 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3353 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003354 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3356 isa<ParmVarDecl>(SizeOfPack->getPack()))
3357 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003358
3359 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003360}
3361
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003362static SourceLocation getLocationFromExpr(const Expr *E) {
3363 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 return getLocationFromExpr(CE->getSubExpr());
3365
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003366 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003368 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003370 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003372 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003374 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003376 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 return PropRef->getLocation();
3378
3379 return E->getLocStart();
3380}
3381
3382extern "C" {
3383
3384unsigned clang_visitChildren(CXCursor parent,
3385 CXCursorVisitor visitor,
3386 CXClientData client_data) {
3387 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3388 /*VisitPreprocessorLast=*/false);
3389 return CursorVis.VisitChildren(parent);
3390}
3391
3392#ifndef __has_feature
3393#define __has_feature(x) 0
3394#endif
3395#if __has_feature(blocks)
3396typedef enum CXChildVisitResult
3397 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3398
3399static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3400 CXClientData client_data) {
3401 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3402 return block(cursor, parent);
3403}
3404#else
3405// If we are compiled with a compiler that doesn't have native blocks support,
3406// define and call the block manually, so the
3407typedef struct _CXChildVisitResult
3408{
3409 void *isa;
3410 int flags;
3411 int reserved;
3412 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3413 CXCursor);
3414} *CXCursorVisitorBlock;
3415
3416static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3417 CXClientData client_data) {
3418 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3419 return block->invoke(block, cursor, parent);
3420}
3421#endif
3422
3423
3424unsigned clang_visitChildrenWithBlock(CXCursor parent,
3425 CXCursorVisitorBlock block) {
3426 return clang_visitChildren(parent, visitWithBlock, block);
3427}
3428
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003429static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003430 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003431 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003432
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003433 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003434 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003435 if (const ObjCPropertyImplDecl *PropImpl =
3436 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003438 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003439
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003440 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003442 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003443
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003444 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 }
3446
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003447 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003448 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003449
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003450 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003451 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3452 // and returns different names. NamedDecl returns the class name and
3453 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003454 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003455
3456 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003457 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003458
3459 SmallString<1024> S;
3460 llvm::raw_svector_ostream os(S);
3461 ND->printName(os);
3462
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003463 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003464}
3465
3466CXString clang_getCursorSpelling(CXCursor C) {
3467 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003468 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003469
3470 if (clang_isReference(C.kind)) {
3471 switch (C.kind) {
3472 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003473 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003474 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 }
3476 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003477 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003478 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 }
3480 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003481 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003482 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003483 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 }
3485 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003486 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003487 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 }
3489 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003490 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 assert(Type && "Missing type decl");
3492
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003493 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 getAsString());
3495 }
3496 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003497 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 assert(Template && "Missing template decl");
3499
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003500 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003501 }
3502
3503 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003504 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 assert(NS && "Missing namespace decl");
3506
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003507 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 }
3509
3510 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003511 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 assert(Field && "Missing member decl");
3513
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003514 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003515 }
3516
3517 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003518 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 assert(Label && "Missing label");
3520
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003521 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 }
3523
3524 case CXCursor_OverloadedDeclRef: {
3525 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003526 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3527 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003528 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003529 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003530 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003532 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 OverloadedTemplateStorage *Ovl
3534 = Storage.get<OverloadedTemplateStorage*>();
3535 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003536 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003537 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 }
3539
3540 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003541 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 assert(Var && "Missing variable decl");
3543
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003544 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 }
3546
3547 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003548 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 }
3550 }
3551
3552 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003553 const Expr *E = getCursorExpr(C);
3554
3555 if (C.kind == CXCursor_ObjCStringLiteral ||
3556 C.kind == CXCursor_StringLiteral) {
3557 const StringLiteral *SLit;
3558 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3559 SLit = OSL->getString();
3560 } else {
3561 SLit = cast<StringLiteral>(E);
3562 }
3563 SmallString<256> Buf;
3564 llvm::raw_svector_ostream OS(Buf);
3565 SLit->outputString(OS);
3566 return cxstring::createDup(OS.str());
3567 }
3568
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003569 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 if (D)
3571 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003572 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 }
3574
3575 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003576 const Stmt *S = getCursorStmt(C);
3577 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003578 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003579
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003580 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 }
3582
3583 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003584 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 ->getNameStart());
3586
3587 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003588 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 ->getNameStart());
3590
3591 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003592 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003593
3594 if (clang_isDeclaration(C.kind))
3595 return getDeclSpelling(getCursorDecl(C));
3596
3597 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003598 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003599 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 }
3601
3602 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003603 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003604 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 }
3606
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003607 if (C.kind == CXCursor_PackedAttr) {
3608 return cxstring::createRef("packed");
3609 }
3610
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003611 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003612}
3613
3614CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3615 unsigned pieceIndex,
3616 unsigned options) {
3617 if (clang_Cursor_isNull(C))
3618 return clang_getNullRange();
3619
3620 ASTContext &Ctx = getCursorContext(C);
3621
3622 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003623 const Stmt *S = getCursorStmt(C);
3624 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 if (pieceIndex > 0)
3626 return clang_getNullRange();
3627 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3628 }
3629
3630 return clang_getNullRange();
3631 }
3632
3633 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003634 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3636 if (pieceIndex >= ME->getNumSelectorLocs())
3637 return clang_getNullRange();
3638 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3639 }
3640 }
3641
3642 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3643 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003644 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3646 if (pieceIndex >= MD->getNumSelectorLocs())
3647 return clang_getNullRange();
3648 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3649 }
3650 }
3651
3652 if (C.kind == CXCursor_ObjCCategoryDecl ||
3653 C.kind == CXCursor_ObjCCategoryImplDecl) {
3654 if (pieceIndex > 0)
3655 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003656 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3658 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003659 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3661 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3662 }
3663
3664 if (C.kind == CXCursor_ModuleImportDecl) {
3665 if (pieceIndex > 0)
3666 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003667 if (const ImportDecl *ImportD =
3668 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3670 if (!Locs.empty())
3671 return cxloc::translateSourceRange(Ctx,
3672 SourceRange(Locs.front(), Locs.back()));
3673 }
3674 return clang_getNullRange();
3675 }
3676
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003677 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3678 C.kind == CXCursor_ConversionFunction) {
3679 if (pieceIndex > 0)
3680 return clang_getNullRange();
3681 if (const FunctionDecl *FD =
3682 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3683 DeclarationNameInfo FunctionName = FD->getNameInfo();
3684 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3685 }
3686 return clang_getNullRange();
3687 }
3688
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 // FIXME: A CXCursor_InclusionDirective should give the location of the
3690 // filename, but we don't keep track of this.
3691
3692 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3693 // but we don't keep track of this.
3694
3695 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3696 // but we don't keep track of this.
3697
3698 // Default handling, give the location of the cursor.
3699
3700 if (pieceIndex > 0)
3701 return clang_getNullRange();
3702
3703 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3704 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3705 return cxloc::translateSourceRange(Ctx, Loc);
3706}
3707
Eli Bendersky44a206f2014-07-31 18:04:56 +00003708CXString clang_Cursor_getMangling(CXCursor C) {
3709 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3710 return cxstring::createEmpty();
3711
Eli Bendersky44a206f2014-07-31 18:04:56 +00003712 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003713 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003714 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3715 return cxstring::createEmpty();
3716
Eli Bendersky79759592014-08-01 15:01:10 +00003717 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003718 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003719 ASTContext &Ctx = ND->getASTContext();
3720 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003721
Eli Bendersky79759592014-08-01 15:01:10 +00003722 std::string FrontendBuf;
3723 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3724 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003725
Eli Bendersky79759592014-08-01 15:01:10 +00003726 // Now apply backend mangling.
3727 std::unique_ptr<llvm::DataLayout> DL(
3728 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3729 llvm::Mangler BackendMangler(DL.get());
3730
3731 std::string FinalBuf;
3732 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3733 BackendMangler.getNameWithPrefix(FinalBufOS,
3734 llvm::Twine(FrontendBufOS.str()));
3735
3736 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003737}
3738
Guy Benyei11169dd2012-12-18 14:30:41 +00003739CXString clang_getCursorDisplayName(CXCursor C) {
3740 if (!clang_isDeclaration(C.kind))
3741 return clang_getCursorSpelling(C);
3742
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003743 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003745 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003746
3747 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003748 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 D = FunTmpl->getTemplatedDecl();
3750
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003751 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 SmallString<64> Str;
3753 llvm::raw_svector_ostream OS(Str);
3754 OS << *Function;
3755 if (Function->getPrimaryTemplate())
3756 OS << "<>";
3757 OS << "(";
3758 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3759 if (I)
3760 OS << ", ";
3761 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3762 }
3763
3764 if (Function->isVariadic()) {
3765 if (Function->getNumParams())
3766 OS << ", ";
3767 OS << "...";
3768 }
3769 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003770 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 }
3772
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003773 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 SmallString<64> Str;
3775 llvm::raw_svector_ostream OS(Str);
3776 OS << *ClassTemplate;
3777 OS << "<";
3778 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3779 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3780 if (I)
3781 OS << ", ";
3782
3783 NamedDecl *Param = Params->getParam(I);
3784 if (Param->getIdentifier()) {
3785 OS << Param->getIdentifier()->getName();
3786 continue;
3787 }
3788
3789 // There is no parameter name, which makes this tricky. Try to come up
3790 // with something useful that isn't too long.
3791 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3792 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3793 else if (NonTypeTemplateParmDecl *NTTP
3794 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3795 OS << NTTP->getType().getAsString(Policy);
3796 else
3797 OS << "template<...> class";
3798 }
3799
3800 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003801 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 }
3803
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003804 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3806 // If the type was explicitly written, use that.
3807 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003808 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003809
Benjamin Kramer9170e912013-02-22 15:46:01 +00003810 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 llvm::raw_svector_ostream OS(Str);
3812 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003813 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 ClassSpec->getTemplateArgs().data(),
3815 ClassSpec->getTemplateArgs().size(),
3816 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003817 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 }
3819
3820 return clang_getCursorSpelling(C);
3821}
3822
3823CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3824 switch (Kind) {
3825 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003953 case CXCursor_ObjCSelfExpr:
3954 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004043 case CXCursor_SEHLeaveStmt:
4044 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004073 case CXCursor_PackedAttr:
4074 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004075 case CXCursor_PureAttr:
4076 return cxstring::createRef("attribute(pure)");
4077 case CXCursor_ConstAttr:
4078 return cxstring::createRef("attribute(const)");
4079 case CXCursor_NoDuplicateAttr:
4080 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004081 case CXCursor_CUDAConstantAttr:
4082 return cxstring::createRef("attribute(constant)");
4083 case CXCursor_CUDADeviceAttr:
4084 return cxstring::createRef("attribute(device)");
4085 case CXCursor_CUDAGlobalAttr:
4086 return cxstring::createRef("attribute(global)");
4087 case CXCursor_CUDAHostAttr:
4088 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004089 case CXCursor_CUDASharedAttr:
4090 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004130 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004139 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004140 return cxstring::createRef("OMPParallelDirective");
4141 case CXCursor_OMPSimdDirective:
4142 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004143 case CXCursor_OMPForDirective:
4144 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004145 case CXCursor_OMPForSimdDirective:
4146 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004147 case CXCursor_OMPSectionsDirective:
4148 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004149 case CXCursor_OMPSectionDirective:
4150 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004151 case CXCursor_OMPSingleDirective:
4152 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004153 case CXCursor_OMPMasterDirective:
4154 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004155 case CXCursor_OMPCriticalDirective:
4156 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004157 case CXCursor_OMPParallelForDirective:
4158 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004159 case CXCursor_OMPParallelSectionsDirective:
4160 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004161 case CXCursor_OMPTaskDirective:
4162 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004163 case CXCursor_OMPTaskyieldDirective:
4164 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004165 case CXCursor_OMPBarrierDirective:
4166 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004167 case CXCursor_OMPTaskwaitDirective:
4168 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004169 case CXCursor_OMPFlushDirective:
4170 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004171 case CXCursor_OMPOrderedDirective:
4172 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004173 case CXCursor_OMPAtomicDirective:
4174 return cxstring::createRef("OMPAtomicDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 }
4176
4177 llvm_unreachable("Unhandled CXCursorKind");
4178}
4179
4180struct GetCursorData {
4181 SourceLocation TokenBeginLoc;
4182 bool PointsAtMacroArgExpansion;
4183 bool VisitedObjCPropertyImplDecl;
4184 SourceLocation VisitedDeclaratorDeclStartLoc;
4185 CXCursor &BestCursor;
4186
4187 GetCursorData(SourceManager &SM,
4188 SourceLocation tokenBegin, CXCursor &outputCursor)
4189 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4190 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4191 VisitedObjCPropertyImplDecl = false;
4192 }
4193};
4194
4195static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4196 CXCursor parent,
4197 CXClientData client_data) {
4198 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4199 CXCursor *BestCursor = &Data->BestCursor;
4200
4201 // If we point inside a macro argument we should provide info of what the
4202 // token is so use the actual cursor, don't replace it with a macro expansion
4203 // cursor.
4204 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4205 return CXChildVisit_Recurse;
4206
4207 if (clang_isDeclaration(cursor.kind)) {
4208 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004209 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4211 if (MD->isImplicit())
4212 return CXChildVisit_Break;
4213
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004214 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4216 // Check that when we have multiple @class references in the same line,
4217 // that later ones do not override the previous ones.
4218 // If we have:
4219 // @class Foo, Bar;
4220 // source ranges for both start at '@', so 'Bar' will end up overriding
4221 // 'Foo' even though the cursor location was at 'Foo'.
4222 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4223 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004224 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4226 if (PrevID != ID &&
4227 !PrevID->isThisDeclarationADefinition() &&
4228 !ID->isThisDeclarationADefinition())
4229 return CXChildVisit_Break;
4230 }
4231
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004232 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4234 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4235 // Check that when we have multiple declarators in the same line,
4236 // that later ones do not override the previous ones.
4237 // If we have:
4238 // int Foo, Bar;
4239 // source ranges for both start at 'int', so 'Bar' will end up overriding
4240 // 'Foo' even though the cursor location was at 'Foo'.
4241 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4242 return CXChildVisit_Break;
4243 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4244
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004245 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4247 (void)PropImp;
4248 // Check that when we have multiple @synthesize in the same line,
4249 // that later ones do not override the previous ones.
4250 // If we have:
4251 // @synthesize Foo, Bar;
4252 // source ranges for both start at '@', so 'Bar' will end up overriding
4253 // 'Foo' even though the cursor location was at 'Foo'.
4254 if (Data->VisitedObjCPropertyImplDecl)
4255 return CXChildVisit_Break;
4256 Data->VisitedObjCPropertyImplDecl = true;
4257 }
4258 }
4259
4260 if (clang_isExpression(cursor.kind) &&
4261 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004262 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 // Avoid having the cursor of an expression replace the declaration cursor
4264 // when the expression source range overlaps the declaration range.
4265 // This can happen for C++ constructor expressions whose range generally
4266 // include the variable declaration, e.g.:
4267 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4268 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4269 D->getLocation() == Data->TokenBeginLoc)
4270 return CXChildVisit_Break;
4271 }
4272 }
4273
4274 // If our current best cursor is the construction of a temporary object,
4275 // don't replace that cursor with a type reference, because we want
4276 // clang_getCursor() to point at the constructor.
4277 if (clang_isExpression(BestCursor->kind) &&
4278 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4279 cursor.kind == CXCursor_TypeRef) {
4280 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4281 // as having the actual point on the type reference.
4282 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4283 return CXChildVisit_Recurse;
4284 }
4285
4286 *BestCursor = cursor;
4287 return CXChildVisit_Recurse;
4288}
4289
4290CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004291 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004292 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004294 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004295
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004296 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4298
4299 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4300 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4301
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004302 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 CXFile SearchFile;
4304 unsigned SearchLine, SearchColumn;
4305 CXFile ResultFile;
4306 unsigned ResultLine, ResultColumn;
4307 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4308 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4309 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004310
4311 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4312 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004313 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004314 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 SearchFileName = clang_getFileName(SearchFile);
4316 ResultFileName = clang_getFileName(ResultFile);
4317 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4318 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004319 *Log << llvm::format("(%s:%d:%d) = %s",
4320 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4321 clang_getCString(KindSpelling))
4322 << llvm::format("(%s:%d:%d):%s%s",
4323 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4324 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004325 clang_disposeString(SearchFileName);
4326 clang_disposeString(ResultFileName);
4327 clang_disposeString(KindSpelling);
4328 clang_disposeString(USR);
4329
4330 CXCursor Definition = clang_getCursorDefinition(Result);
4331 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4332 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4333 CXString DefinitionKindSpelling
4334 = clang_getCursorKindSpelling(Definition.kind);
4335 CXFile DefinitionFile;
4336 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004337 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004338 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004339 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004340 *Log << llvm::format(" -> %s(%s:%d:%d)",
4341 clang_getCString(DefinitionKindSpelling),
4342 clang_getCString(DefinitionFileName),
4343 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004344 clang_disposeString(DefinitionFileName);
4345 clang_disposeString(DefinitionKindSpelling);
4346 }
4347 }
4348
4349 return Result;
4350}
4351
4352CXCursor clang_getNullCursor(void) {
4353 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4354}
4355
4356unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004357 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4358 // can't set consistently. For example, when visiting a DeclStmt we will set
4359 // it but we don't set it on the result of clang_getCursorDefinition for
4360 // a reference of the same declaration.
4361 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4362 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4363 // to provide that kind of info.
4364 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004365 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004366 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004367 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004368
Guy Benyei11169dd2012-12-18 14:30:41 +00004369 return X == Y;
4370}
4371
4372unsigned clang_hashCursor(CXCursor C) {
4373 unsigned Index = 0;
4374 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4375 Index = 1;
4376
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004377 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004378 std::make_pair(C.kind, C.data[Index]));
4379}
4380
4381unsigned clang_isInvalid(enum CXCursorKind K) {
4382 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4383}
4384
4385unsigned clang_isDeclaration(enum CXCursorKind K) {
4386 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4387 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4388}
4389
4390unsigned clang_isReference(enum CXCursorKind K) {
4391 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4392}
4393
4394unsigned clang_isExpression(enum CXCursorKind K) {
4395 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4396}
4397
4398unsigned clang_isStatement(enum CXCursorKind K) {
4399 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4400}
4401
4402unsigned clang_isAttribute(enum CXCursorKind K) {
4403 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4404}
4405
4406unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4407 return K == CXCursor_TranslationUnit;
4408}
4409
4410unsigned clang_isPreprocessing(enum CXCursorKind K) {
4411 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4412}
4413
4414unsigned clang_isUnexposed(enum CXCursorKind K) {
4415 switch (K) {
4416 case CXCursor_UnexposedDecl:
4417 case CXCursor_UnexposedExpr:
4418 case CXCursor_UnexposedStmt:
4419 case CXCursor_UnexposedAttr:
4420 return true;
4421 default:
4422 return false;
4423 }
4424}
4425
4426CXCursorKind clang_getCursorKind(CXCursor C) {
4427 return C.kind;
4428}
4429
4430CXSourceLocation clang_getCursorLocation(CXCursor C) {
4431 if (clang_isReference(C.kind)) {
4432 switch (C.kind) {
4433 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004434 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 = getCursorObjCSuperClassRef(C);
4436 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4437 }
4438
4439 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004440 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 = getCursorObjCProtocolRef(C);
4442 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4443 }
4444
4445 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004446 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004447 = getCursorObjCClassRef(C);
4448 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4449 }
4450
4451 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004452 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4454 }
4455
4456 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004457 std::pair<const TemplateDecl *, SourceLocation> P =
4458 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4460 }
4461
4462 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004463 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4465 }
4466
4467 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004468 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004469 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4470 }
4471
4472 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004473 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4475 }
4476
4477 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004478 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 if (!BaseSpec)
4480 return clang_getNullLocation();
4481
4482 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4483 return cxloc::translateSourceLocation(getCursorContext(C),
4484 TSInfo->getTypeLoc().getBeginLoc());
4485
4486 return cxloc::translateSourceLocation(getCursorContext(C),
4487 BaseSpec->getLocStart());
4488 }
4489
4490 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004491 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004492 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4493 }
4494
4495 case CXCursor_OverloadedDeclRef:
4496 return cxloc::translateSourceLocation(getCursorContext(C),
4497 getCursorOverloadedDeclRef(C).second);
4498
4499 default:
4500 // FIXME: Need a way to enumerate all non-reference cases.
4501 llvm_unreachable("Missed a reference kind");
4502 }
4503 }
4504
4505 if (clang_isExpression(C.kind))
4506 return cxloc::translateSourceLocation(getCursorContext(C),
4507 getLocationFromExpr(getCursorExpr(C)));
4508
4509 if (clang_isStatement(C.kind))
4510 return cxloc::translateSourceLocation(getCursorContext(C),
4511 getCursorStmt(C)->getLocStart());
4512
4513 if (C.kind == CXCursor_PreprocessingDirective) {
4514 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4515 return cxloc::translateSourceLocation(getCursorContext(C), L);
4516 }
4517
4518 if (C.kind == CXCursor_MacroExpansion) {
4519 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004520 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 return cxloc::translateSourceLocation(getCursorContext(C), L);
4522 }
4523
4524 if (C.kind == CXCursor_MacroDefinition) {
4525 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4526 return cxloc::translateSourceLocation(getCursorContext(C), L);
4527 }
4528
4529 if (C.kind == CXCursor_InclusionDirective) {
4530 SourceLocation L
4531 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4532 return cxloc::translateSourceLocation(getCursorContext(C), L);
4533 }
4534
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004535 if (clang_isAttribute(C.kind)) {
4536 SourceLocation L
4537 = cxcursor::getCursorAttr(C)->getLocation();
4538 return cxloc::translateSourceLocation(getCursorContext(C), L);
4539 }
4540
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 if (!clang_isDeclaration(C.kind))
4542 return clang_getNullLocation();
4543
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004544 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 if (!D)
4546 return clang_getNullLocation();
4547
4548 SourceLocation Loc = D->getLocation();
4549 // FIXME: Multiple variables declared in a single declaration
4550 // currently lack the information needed to correctly determine their
4551 // ranges when accounting for the type-specifier. We use context
4552 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4553 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004554 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 if (!cxcursor::isFirstInDeclGroup(C))
4556 Loc = VD->getLocation();
4557 }
4558
4559 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004560 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 Loc = MD->getSelectorStartLoc();
4562
4563 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4564}
4565
4566} // end extern "C"
4567
4568CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4569 assert(TU);
4570
4571 // Guard against an invalid SourceLocation, or we may assert in one
4572 // of the following calls.
4573 if (SLoc.isInvalid())
4574 return clang_getNullCursor();
4575
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004576 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004577
4578 // Translate the given source location to make it point at the beginning of
4579 // the token under the cursor.
4580 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4581 CXXUnit->getASTContext().getLangOpts());
4582
4583 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4584 if (SLoc.isValid()) {
4585 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4586 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4587 /*VisitPreprocessorLast=*/true,
4588 /*VisitIncludedEntities=*/false,
4589 SourceLocation(SLoc));
4590 CursorVis.visitFileRegion();
4591 }
4592
4593 return Result;
4594}
4595
4596static SourceRange getRawCursorExtent(CXCursor C) {
4597 if (clang_isReference(C.kind)) {
4598 switch (C.kind) {
4599 case CXCursor_ObjCSuperClassRef:
4600 return getCursorObjCSuperClassRef(C).second;
4601
4602 case CXCursor_ObjCProtocolRef:
4603 return getCursorObjCProtocolRef(C).second;
4604
4605 case CXCursor_ObjCClassRef:
4606 return getCursorObjCClassRef(C).second;
4607
4608 case CXCursor_TypeRef:
4609 return getCursorTypeRef(C).second;
4610
4611 case CXCursor_TemplateRef:
4612 return getCursorTemplateRef(C).second;
4613
4614 case CXCursor_NamespaceRef:
4615 return getCursorNamespaceRef(C).second;
4616
4617 case CXCursor_MemberRef:
4618 return getCursorMemberRef(C).second;
4619
4620 case CXCursor_CXXBaseSpecifier:
4621 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4622
4623 case CXCursor_LabelRef:
4624 return getCursorLabelRef(C).second;
4625
4626 case CXCursor_OverloadedDeclRef:
4627 return getCursorOverloadedDeclRef(C).second;
4628
4629 case CXCursor_VariableRef:
4630 return getCursorVariableRef(C).second;
4631
4632 default:
4633 // FIXME: Need a way to enumerate all non-reference cases.
4634 llvm_unreachable("Missed a reference kind");
4635 }
4636 }
4637
4638 if (clang_isExpression(C.kind))
4639 return getCursorExpr(C)->getSourceRange();
4640
4641 if (clang_isStatement(C.kind))
4642 return getCursorStmt(C)->getSourceRange();
4643
4644 if (clang_isAttribute(C.kind))
4645 return getCursorAttr(C)->getRange();
4646
4647 if (C.kind == CXCursor_PreprocessingDirective)
4648 return cxcursor::getCursorPreprocessingDirective(C);
4649
4650 if (C.kind == CXCursor_MacroExpansion) {
4651 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004652 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 return TU->mapRangeFromPreamble(Range);
4654 }
4655
4656 if (C.kind == CXCursor_MacroDefinition) {
4657 ASTUnit *TU = getCursorASTUnit(C);
4658 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4659 return TU->mapRangeFromPreamble(Range);
4660 }
4661
4662 if (C.kind == CXCursor_InclusionDirective) {
4663 ASTUnit *TU = getCursorASTUnit(C);
4664 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4665 return TU->mapRangeFromPreamble(Range);
4666 }
4667
4668 if (C.kind == CXCursor_TranslationUnit) {
4669 ASTUnit *TU = getCursorASTUnit(C);
4670 FileID MainID = TU->getSourceManager().getMainFileID();
4671 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4672 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4673 return SourceRange(Start, End);
4674 }
4675
4676 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004677 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004678 if (!D)
4679 return SourceRange();
4680
4681 SourceRange R = D->getSourceRange();
4682 // FIXME: Multiple variables declared in a single declaration
4683 // currently lack the information needed to correctly determine their
4684 // ranges when accounting for the type-specifier. We use context
4685 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4686 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004687 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 if (!cxcursor::isFirstInDeclGroup(C))
4689 R.setBegin(VD->getLocation());
4690 }
4691 return R;
4692 }
4693 return SourceRange();
4694}
4695
4696/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4697/// the decl-specifier-seq for declarations.
4698static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4699 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004700 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 if (!D)
4702 return SourceRange();
4703
4704 SourceRange R = D->getSourceRange();
4705
4706 // Adjust the start of the location for declarations preceded by
4707 // declaration specifiers.
4708 SourceLocation StartLoc;
4709 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4710 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4711 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004712 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4714 StartLoc = TI->getTypeLoc().getLocStart();
4715 }
4716
4717 if (StartLoc.isValid() && R.getBegin().isValid() &&
4718 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4719 R.setBegin(StartLoc);
4720
4721 // FIXME: Multiple variables declared in a single declaration
4722 // currently lack the information needed to correctly determine their
4723 // ranges when accounting for the type-specifier. We use context
4724 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4725 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004726 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 if (!cxcursor::isFirstInDeclGroup(C))
4728 R.setBegin(VD->getLocation());
4729 }
4730
4731 return R;
4732 }
4733
4734 return getRawCursorExtent(C);
4735}
4736
4737extern "C" {
4738
4739CXSourceRange clang_getCursorExtent(CXCursor C) {
4740 SourceRange R = getRawCursorExtent(C);
4741 if (R.isInvalid())
4742 return clang_getNullRange();
4743
4744 return cxloc::translateSourceRange(getCursorContext(C), R);
4745}
4746
4747CXCursor clang_getCursorReferenced(CXCursor C) {
4748 if (clang_isInvalid(C.kind))
4749 return clang_getNullCursor();
4750
4751 CXTranslationUnit tu = getCursorTU(C);
4752 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004753 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 if (!D)
4755 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004756 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004758 if (const ObjCPropertyImplDecl *PropImpl =
4759 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4761 return MakeCXCursor(Property, tu);
4762
4763 return C;
4764 }
4765
4766 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004767 const Expr *E = getCursorExpr(C);
4768 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 if (D) {
4770 CXCursor declCursor = MakeCXCursor(D, tu);
4771 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4772 declCursor);
4773 return declCursor;
4774 }
4775
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004776 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 return MakeCursorOverloadedDeclRef(Ovl, tu);
4778
4779 return clang_getNullCursor();
4780 }
4781
4782 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004783 const Stmt *S = getCursorStmt(C);
4784 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 if (LabelDecl *label = Goto->getLabel())
4786 if (LabelStmt *labelS = label->getStmt())
4787 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4788
4789 return clang_getNullCursor();
4790 }
4791
4792 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004793 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 return MakeMacroDefinitionCursor(Def, tu);
4795 }
4796
4797 if (!clang_isReference(C.kind))
4798 return clang_getNullCursor();
4799
4800 switch (C.kind) {
4801 case CXCursor_ObjCSuperClassRef:
4802 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4803
4804 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004805 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4806 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 return MakeCXCursor(Def, tu);
4808
4809 return MakeCXCursor(Prot, tu);
4810 }
4811
4812 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004813 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4814 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004815 return MakeCXCursor(Def, tu);
4816
4817 return MakeCXCursor(Class, tu);
4818 }
4819
4820 case CXCursor_TypeRef:
4821 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4822
4823 case CXCursor_TemplateRef:
4824 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4825
4826 case CXCursor_NamespaceRef:
4827 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4828
4829 case CXCursor_MemberRef:
4830 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4831
4832 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004833 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004834 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4835 tu ));
4836 }
4837
4838 case CXCursor_LabelRef:
4839 // FIXME: We end up faking the "parent" declaration here because we
4840 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004841 return MakeCXCursor(getCursorLabelRef(C).first,
4842 cxtu::getASTUnit(tu)->getASTContext()
4843 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 tu);
4845
4846 case CXCursor_OverloadedDeclRef:
4847 return C;
4848
4849 case CXCursor_VariableRef:
4850 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4851
4852 default:
4853 // We would prefer to enumerate all non-reference cursor kinds here.
4854 llvm_unreachable("Unhandled reference cursor kind");
4855 }
4856}
4857
4858CXCursor clang_getCursorDefinition(CXCursor C) {
4859 if (clang_isInvalid(C.kind))
4860 return clang_getNullCursor();
4861
4862 CXTranslationUnit TU = getCursorTU(C);
4863
4864 bool WasReference = false;
4865 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4866 C = clang_getCursorReferenced(C);
4867 WasReference = true;
4868 }
4869
4870 if (C.kind == CXCursor_MacroExpansion)
4871 return clang_getCursorReferenced(C);
4872
4873 if (!clang_isDeclaration(C.kind))
4874 return clang_getNullCursor();
4875
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004876 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 if (!D)
4878 return clang_getNullCursor();
4879
4880 switch (D->getKind()) {
4881 // Declaration kinds that don't really separate the notions of
4882 // declaration and definition.
4883 case Decl::Namespace:
4884 case Decl::Typedef:
4885 case Decl::TypeAlias:
4886 case Decl::TypeAliasTemplate:
4887 case Decl::TemplateTypeParm:
4888 case Decl::EnumConstant:
4889 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004890 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004891 case Decl::IndirectField:
4892 case Decl::ObjCIvar:
4893 case Decl::ObjCAtDefsField:
4894 case Decl::ImplicitParam:
4895 case Decl::ParmVar:
4896 case Decl::NonTypeTemplateParm:
4897 case Decl::TemplateTemplateParm:
4898 case Decl::ObjCCategoryImpl:
4899 case Decl::ObjCImplementation:
4900 case Decl::AccessSpec:
4901 case Decl::LinkageSpec:
4902 case Decl::ObjCPropertyImpl:
4903 case Decl::FileScopeAsm:
4904 case Decl::StaticAssert:
4905 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004906 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004907 case Decl::Label: // FIXME: Is this right??
4908 case Decl::ClassScopeFunctionSpecialization:
4909 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004910 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004911 return C;
4912
4913 // Declaration kinds that don't make any sense here, but are
4914 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004915 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004916 case Decl::TranslationUnit:
4917 break;
4918
4919 // Declaration kinds for which the definition is not resolvable.
4920 case Decl::UnresolvedUsingTypename:
4921 case Decl::UnresolvedUsingValue:
4922 break;
4923
4924 case Decl::UsingDirective:
4925 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4926 TU);
4927
4928 case Decl::NamespaceAlias:
4929 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4930
4931 case Decl::Enum:
4932 case Decl::Record:
4933 case Decl::CXXRecord:
4934 case Decl::ClassTemplateSpecialization:
4935 case Decl::ClassTemplatePartialSpecialization:
4936 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4937 return MakeCXCursor(Def, TU);
4938 return clang_getNullCursor();
4939
4940 case Decl::Function:
4941 case Decl::CXXMethod:
4942 case Decl::CXXConstructor:
4943 case Decl::CXXDestructor:
4944 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004945 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004946 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004947 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004948 return clang_getNullCursor();
4949 }
4950
Larisse Voufo39a1e502013-08-06 01:03:05 +00004951 case Decl::Var:
4952 case Decl::VarTemplateSpecialization:
4953 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004954 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004955 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004956 return MakeCXCursor(Def, TU);
4957 return clang_getNullCursor();
4958 }
4959
4960 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004961 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004962 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4963 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4964 return clang_getNullCursor();
4965 }
4966
4967 case Decl::ClassTemplate: {
4968 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4969 ->getDefinition())
4970 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4971 TU);
4972 return clang_getNullCursor();
4973 }
4974
Larisse Voufo39a1e502013-08-06 01:03:05 +00004975 case Decl::VarTemplate: {
4976 if (VarDecl *Def =
4977 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4978 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4979 return clang_getNullCursor();
4980 }
4981
Guy Benyei11169dd2012-12-18 14:30:41 +00004982 case Decl::Using:
4983 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4984 D->getLocation(), TU);
4985
4986 case Decl::UsingShadow:
4987 return clang_getCursorDefinition(
4988 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4989 TU));
4990
4991 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004992 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 if (Method->isThisDeclarationADefinition())
4994 return C;
4995
4996 // Dig out the method definition in the associated
4997 // @implementation, if we have it.
4998 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004999 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5001 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5002 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5003 Method->isInstanceMethod()))
5004 if (Def->isThisDeclarationADefinition())
5005 return MakeCXCursor(Def, TU);
5006
5007 return clang_getNullCursor();
5008 }
5009
5010 case Decl::ObjCCategory:
5011 if (ObjCCategoryImplDecl *Impl
5012 = cast<ObjCCategoryDecl>(D)->getImplementation())
5013 return MakeCXCursor(Impl, TU);
5014 return clang_getNullCursor();
5015
5016 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005017 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 return MakeCXCursor(Def, TU);
5019 return clang_getNullCursor();
5020
5021 case Decl::ObjCInterface: {
5022 // There are two notions of a "definition" for an Objective-C
5023 // class: the interface and its implementation. When we resolved a
5024 // reference to an Objective-C class, produce the @interface as
5025 // the definition; when we were provided with the interface,
5026 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005027 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005029 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005030 return MakeCXCursor(Def, TU);
5031 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5032 return MakeCXCursor(Impl, TU);
5033 return clang_getNullCursor();
5034 }
5035
5036 case Decl::ObjCProperty:
5037 // FIXME: We don't really know where to find the
5038 // ObjCPropertyImplDecls that implement this property.
5039 return clang_getNullCursor();
5040
5041 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005042 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005043 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005044 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 return MakeCXCursor(Def, TU);
5046
5047 return clang_getNullCursor();
5048
5049 case Decl::Friend:
5050 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5051 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5052 return clang_getNullCursor();
5053
5054 case Decl::FriendTemplate:
5055 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5056 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5057 return clang_getNullCursor();
5058 }
5059
5060 return clang_getNullCursor();
5061}
5062
5063unsigned clang_isCursorDefinition(CXCursor C) {
5064 if (!clang_isDeclaration(C.kind))
5065 return 0;
5066
5067 return clang_getCursorDefinition(C) == C;
5068}
5069
5070CXCursor clang_getCanonicalCursor(CXCursor C) {
5071 if (!clang_isDeclaration(C.kind))
5072 return C;
5073
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005074 if (const Decl *D = getCursorDecl(C)) {
5075 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5077 return MakeCXCursor(CatD, getCursorTU(C));
5078
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005079 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5080 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 return MakeCXCursor(IFD, getCursorTU(C));
5082
5083 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5084 }
5085
5086 return C;
5087}
5088
5089int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5090 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5091}
5092
5093unsigned clang_getNumOverloadedDecls(CXCursor C) {
5094 if (C.kind != CXCursor_OverloadedDeclRef)
5095 return 0;
5096
5097 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005098 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 return E->getNumDecls();
5100
5101 if (OverloadedTemplateStorage *S
5102 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5103 return S->size();
5104
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005105 const Decl *D = Storage.get<const Decl *>();
5106 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005107 return Using->shadow_size();
5108
5109 return 0;
5110}
5111
5112CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5113 if (cursor.kind != CXCursor_OverloadedDeclRef)
5114 return clang_getNullCursor();
5115
5116 if (index >= clang_getNumOverloadedDecls(cursor))
5117 return clang_getNullCursor();
5118
5119 CXTranslationUnit TU = getCursorTU(cursor);
5120 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005121 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 return MakeCXCursor(E->decls_begin()[index], TU);
5123
5124 if (OverloadedTemplateStorage *S
5125 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5126 return MakeCXCursor(S->begin()[index], TU);
5127
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005128 const Decl *D = Storage.get<const Decl *>();
5129 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 // FIXME: This is, unfortunately, linear time.
5131 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5132 std::advance(Pos, index);
5133 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5134 }
5135
5136 return clang_getNullCursor();
5137}
5138
5139void clang_getDefinitionSpellingAndExtent(CXCursor C,
5140 const char **startBuf,
5141 const char **endBuf,
5142 unsigned *startLine,
5143 unsigned *startColumn,
5144 unsigned *endLine,
5145 unsigned *endColumn) {
5146 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005147 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5149
5150 SourceManager &SM = FD->getASTContext().getSourceManager();
5151 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5152 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5153 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5154 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5155 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5156 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5157}
5158
5159
5160CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5161 unsigned PieceIndex) {
5162 RefNamePieces Pieces;
5163
5164 switch (C.kind) {
5165 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005166 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005167 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5168 E->getQualifierLoc().getSourceRange());
5169 break;
5170
5171 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005172 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005173 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5174 E->getQualifierLoc().getSourceRange(),
5175 E->getOptionalExplicitTemplateArgs());
5176 break;
5177
5178 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005179 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005181 const Expr *Callee = OCE->getCallee();
5182 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005183 Callee = ICE->getSubExpr();
5184
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005185 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5187 DRE->getQualifierLoc().getSourceRange());
5188 }
5189 break;
5190
5191 default:
5192 break;
5193 }
5194
5195 if (Pieces.empty()) {
5196 if (PieceIndex == 0)
5197 return clang_getCursorExtent(C);
5198 } else if (PieceIndex < Pieces.size()) {
5199 SourceRange R = Pieces[PieceIndex];
5200 if (R.isValid())
5201 return cxloc::translateSourceRange(getCursorContext(C), R);
5202 }
5203
5204 return clang_getNullRange();
5205}
5206
5207void clang_enableStackTraces(void) {
5208 llvm::sys::PrintStackTraceOnErrorSignal();
5209}
5210
5211void clang_executeOnThread(void (*fn)(void*), void *user_data,
5212 unsigned stack_size) {
5213 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5214}
5215
5216} // end: extern "C"
5217
5218//===----------------------------------------------------------------------===//
5219// Token-based Operations.
5220//===----------------------------------------------------------------------===//
5221
5222/* CXToken layout:
5223 * int_data[0]: a CXTokenKind
5224 * int_data[1]: starting token location
5225 * int_data[2]: token length
5226 * int_data[3]: reserved
5227 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5228 * otherwise unused.
5229 */
5230extern "C" {
5231
5232CXTokenKind clang_getTokenKind(CXToken CXTok) {
5233 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5234}
5235
5236CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5237 switch (clang_getTokenKind(CXTok)) {
5238 case CXToken_Identifier:
5239 case CXToken_Keyword:
5240 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005241 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 ->getNameStart());
5243
5244 case CXToken_Literal: {
5245 // We have stashed the starting pointer in the ptr_data field. Use it.
5246 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005247 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 }
5249
5250 case CXToken_Punctuation:
5251 case CXToken_Comment:
5252 break;
5253 }
5254
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005255 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005256 LOG_BAD_TU(TU);
5257 return cxstring::createEmpty();
5258 }
5259
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 // We have to find the starting buffer pointer the hard way, by
5261 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005262 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005263 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005264 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005265
5266 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5267 std::pair<FileID, unsigned> LocInfo
5268 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5269 bool Invalid = false;
5270 StringRef Buffer
5271 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5272 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005273 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005274
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005275 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005276}
5277
5278CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005279 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005280 LOG_BAD_TU(TU);
5281 return clang_getNullLocation();
5282 }
5283
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005284 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 if (!CXXUnit)
5286 return clang_getNullLocation();
5287
5288 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5289 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5290}
5291
5292CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005293 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005294 LOG_BAD_TU(TU);
5295 return clang_getNullRange();
5296 }
5297
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005298 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005299 if (!CXXUnit)
5300 return clang_getNullRange();
5301
5302 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5303 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5304}
5305
5306static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5307 SmallVectorImpl<CXToken> &CXTokens) {
5308 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5309 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005310 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005311 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005312 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005313
5314 // Cannot tokenize across files.
5315 if (BeginLocInfo.first != EndLocInfo.first)
5316 return;
5317
5318 // Create a lexer
5319 bool Invalid = false;
5320 StringRef Buffer
5321 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5322 if (Invalid)
5323 return;
5324
5325 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5326 CXXUnit->getASTContext().getLangOpts(),
5327 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5328 Lex.SetCommentRetentionState(true);
5329
5330 // Lex tokens until we hit the end of the range.
5331 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5332 Token Tok;
5333 bool previousWasAt = false;
5334 do {
5335 // Lex the next token
5336 Lex.LexFromRawLexer(Tok);
5337 if (Tok.is(tok::eof))
5338 break;
5339
5340 // Initialize the CXToken.
5341 CXToken CXTok;
5342
5343 // - Common fields
5344 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5345 CXTok.int_data[2] = Tok.getLength();
5346 CXTok.int_data[3] = 0;
5347
5348 // - Kind-specific fields
5349 if (Tok.isLiteral()) {
5350 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005351 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 } else if (Tok.is(tok::raw_identifier)) {
5353 // Lookup the identifier to determine whether we have a keyword.
5354 IdentifierInfo *II
5355 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5356
5357 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5358 CXTok.int_data[0] = CXToken_Keyword;
5359 }
5360 else {
5361 CXTok.int_data[0] = Tok.is(tok::identifier)
5362 ? CXToken_Identifier
5363 : CXToken_Keyword;
5364 }
5365 CXTok.ptr_data = II;
5366 } else if (Tok.is(tok::comment)) {
5367 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005368 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005369 } else {
5370 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005371 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 }
5373 CXTokens.push_back(CXTok);
5374 previousWasAt = Tok.is(tok::at);
5375 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5376}
5377
5378void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5379 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005380 LOG_FUNC_SECTION {
5381 *Log << TU << ' ' << Range;
5382 }
5383
Guy Benyei11169dd2012-12-18 14:30:41 +00005384 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005385 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005386 if (NumTokens)
5387 *NumTokens = 0;
5388
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005389 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005390 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005391 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005392 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005393
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005394 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 if (!CXXUnit || !Tokens || !NumTokens)
5396 return;
5397
5398 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5399
5400 SourceRange R = cxloc::translateCXSourceRange(Range);
5401 if (R.isInvalid())
5402 return;
5403
5404 SmallVector<CXToken, 32> CXTokens;
5405 getTokens(CXXUnit, R, CXTokens);
5406
5407 if (CXTokens.empty())
5408 return;
5409
5410 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5411 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5412 *NumTokens = CXTokens.size();
5413}
5414
5415void clang_disposeTokens(CXTranslationUnit TU,
5416 CXToken *Tokens, unsigned NumTokens) {
5417 free(Tokens);
5418}
5419
5420} // end: extern "C"
5421
5422//===----------------------------------------------------------------------===//
5423// Token annotation APIs.
5424//===----------------------------------------------------------------------===//
5425
Guy Benyei11169dd2012-12-18 14:30:41 +00005426static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5427 CXCursor parent,
5428 CXClientData client_data);
5429static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5430 CXClientData client_data);
5431
5432namespace {
5433class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005434 CXToken *Tokens;
5435 CXCursor *Cursors;
5436 unsigned NumTokens;
5437 unsigned TokIdx;
5438 unsigned PreprocessingTokIdx;
5439 CursorVisitor AnnotateVis;
5440 SourceManager &SrcMgr;
5441 bool HasContextSensitiveKeywords;
5442
5443 struct PostChildrenInfo {
5444 CXCursor Cursor;
5445 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005446 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 unsigned BeforeChildrenTokenIdx;
5448 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005449 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005450
5451 CXToken &getTok(unsigned Idx) {
5452 assert(Idx < NumTokens);
5453 return Tokens[Idx];
5454 }
5455 const CXToken &getTok(unsigned Idx) const {
5456 assert(Idx < NumTokens);
5457 return Tokens[Idx];
5458 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 bool MoreTokens() const { return TokIdx < NumTokens; }
5460 unsigned NextToken() const { return TokIdx; }
5461 void AdvanceToken() { ++TokIdx; }
5462 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005463 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 }
5465 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005466 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 }
5468 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005469 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005470 }
5471
5472 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005473 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 SourceRange);
5475
5476public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005477 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005478 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005479 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005480 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005481 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 AnnotateTokensVisitor, this,
5483 /*VisitPreprocessorLast=*/true,
5484 /*VisitIncludedEntities=*/false,
5485 RegionOfInterest,
5486 /*VisitDeclsOnly=*/false,
5487 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005488 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 HasContextSensitiveKeywords(false) { }
5490
5491 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5492 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5493 bool postVisitChildren(CXCursor cursor);
5494 void AnnotateTokens();
5495
5496 /// \brief Determine whether the annotator saw any cursors that have
5497 /// context-sensitive keywords.
5498 bool hasContextSensitiveKeywords() const {
5499 return HasContextSensitiveKeywords;
5500 }
5501
5502 ~AnnotateTokensWorker() {
5503 assert(PostChildrenInfos.empty());
5504 }
5505};
5506}
5507
5508void AnnotateTokensWorker::AnnotateTokens() {
5509 // Walk the AST within the region of interest, annotating tokens
5510 // along the way.
5511 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005512}
Guy Benyei11169dd2012-12-18 14:30:41 +00005513
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005514static inline void updateCursorAnnotation(CXCursor &Cursor,
5515 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005516 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005518 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005519}
5520
5521/// \brief It annotates and advances tokens with a cursor until the comparison
5522//// between the cursor location and the source range is the same as
5523/// \arg compResult.
5524///
5525/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5526/// Pass RangeOverlap to annotate tokens inside a range.
5527void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5528 RangeComparisonResult compResult,
5529 SourceRange range) {
5530 while (MoreTokens()) {
5531 const unsigned I = NextToken();
5532 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005533 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5534 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005535
5536 SourceLocation TokLoc = GetTokenLoc(I);
5537 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005538 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005539 AdvanceToken();
5540 continue;
5541 }
5542 break;
5543 }
5544}
5545
5546/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005547/// \returns true if it advanced beyond all macro tokens, false otherwise.
5548bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005549 CXCursor updateC,
5550 RangeComparisonResult compResult,
5551 SourceRange range) {
5552 assert(MoreTokens());
5553 assert(isFunctionMacroToken(NextToken()) &&
5554 "Should be called only for macro arg tokens");
5555
5556 // This works differently than annotateAndAdvanceTokens; because expanded
5557 // macro arguments can have arbitrary translation-unit source order, we do not
5558 // advance the token index one by one until a token fails the range test.
5559 // We only advance once past all of the macro arg tokens if all of them
5560 // pass the range test. If one of them fails we keep the token index pointing
5561 // at the start of the macro arg tokens so that the failing token will be
5562 // annotated by a subsequent annotation try.
5563
5564 bool atLeastOneCompFail = false;
5565
5566 unsigned I = NextToken();
5567 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5568 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5569 if (TokLoc.isFileID())
5570 continue; // not macro arg token, it's parens or comma.
5571 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5572 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5573 Cursors[I] = updateC;
5574 } else
5575 atLeastOneCompFail = true;
5576 }
5577
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005578 if (atLeastOneCompFail)
5579 return false;
5580
5581 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5582 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005583}
5584
5585enum CXChildVisitResult
5586AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005587 SourceRange cursorRange = getRawCursorExtent(cursor);
5588 if (cursorRange.isInvalid())
5589 return CXChildVisit_Recurse;
5590
5591 if (!HasContextSensitiveKeywords) {
5592 // Objective-C properties can have context-sensitive keywords.
5593 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005594 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5596 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5597 }
5598 // Objective-C methods can have context-sensitive keywords.
5599 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5600 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005601 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005602 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5603 if (Method->getObjCDeclQualifier())
5604 HasContextSensitiveKeywords = true;
5605 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005606 for (const auto *P : Method->params()) {
5607 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005608 HasContextSensitiveKeywords = true;
5609 break;
5610 }
5611 }
5612 }
5613 }
5614 }
5615 // C++ methods can have context-sensitive keywords.
5616 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005617 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005618 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5619 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5620 HasContextSensitiveKeywords = true;
5621 }
5622 }
5623 // C++ classes can have context-sensitive keywords.
5624 else if (cursor.kind == CXCursor_StructDecl ||
5625 cursor.kind == CXCursor_ClassDecl ||
5626 cursor.kind == CXCursor_ClassTemplate ||
5627 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005628 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005629 if (D->hasAttr<FinalAttr>())
5630 HasContextSensitiveKeywords = true;
5631 }
5632 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005633
5634 // Don't override a property annotation with its getter/setter method.
5635 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5636 parent.kind == CXCursor_ObjCPropertyDecl)
5637 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005638
5639 if (clang_isPreprocessing(cursor.kind)) {
5640 // Items in the preprocessing record are kept separate from items in
5641 // declarations, so we keep a separate token index.
5642 unsigned SavedTokIdx = TokIdx;
5643 TokIdx = PreprocessingTokIdx;
5644
5645 // Skip tokens up until we catch up to the beginning of the preprocessing
5646 // entry.
5647 while (MoreTokens()) {
5648 const unsigned I = NextToken();
5649 SourceLocation TokLoc = GetTokenLoc(I);
5650 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5651 case RangeBefore:
5652 AdvanceToken();
5653 continue;
5654 case RangeAfter:
5655 case RangeOverlap:
5656 break;
5657 }
5658 break;
5659 }
5660
5661 // Look at all of the tokens within this range.
5662 while (MoreTokens()) {
5663 const unsigned I = NextToken();
5664 SourceLocation TokLoc = GetTokenLoc(I);
5665 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5666 case RangeBefore:
5667 llvm_unreachable("Infeasible");
5668 case RangeAfter:
5669 break;
5670 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005671 // For macro expansions, just note where the beginning of the macro
5672 // expansion occurs.
5673 if (cursor.kind == CXCursor_MacroExpansion) {
5674 if (TokLoc == cursorRange.getBegin())
5675 Cursors[I] = cursor;
5676 AdvanceToken();
5677 break;
5678 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005679 // We may have already annotated macro names inside macro definitions.
5680 if (Cursors[I].kind != CXCursor_MacroExpansion)
5681 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005682 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005683 continue;
5684 }
5685 break;
5686 }
5687
5688 // Save the preprocessing token index; restore the non-preprocessing
5689 // token index.
5690 PreprocessingTokIdx = TokIdx;
5691 TokIdx = SavedTokIdx;
5692 return CXChildVisit_Recurse;
5693 }
5694
5695 if (cursorRange.isInvalid())
5696 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005697
5698 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005700 const enum CXCursorKind K = clang_getCursorKind(parent);
5701 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005702 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5703 // Attributes are annotated out-of-order, skip tokens until we reach it.
5704 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005705 ? clang_getNullCursor() : parent;
5706
5707 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5708
5709 // Avoid having the cursor of an expression "overwrite" the annotation of the
5710 // variable declaration that it belongs to.
5711 // This can happen for C++ constructor expressions whose range generally
5712 // include the variable declaration, e.g.:
5713 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005714 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005715 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005716 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005717 const unsigned I = NextToken();
5718 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5719 E->getLocStart() == D->getLocation() &&
5720 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005721 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 AdvanceToken();
5723 }
5724 }
5725 }
5726
5727 // Before recursing into the children keep some state that we are going
5728 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5729 // extra work after the child nodes are visited.
5730 // Note that we don't call VisitChildren here to avoid traversing statements
5731 // code-recursively which can blow the stack.
5732
5733 PostChildrenInfo Info;
5734 Info.Cursor = cursor;
5735 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005736 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005737 Info.BeforeChildrenTokenIdx = NextToken();
5738 PostChildrenInfos.push_back(Info);
5739
5740 return CXChildVisit_Recurse;
5741}
5742
5743bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5744 if (PostChildrenInfos.empty())
5745 return false;
5746 const PostChildrenInfo &Info = PostChildrenInfos.back();
5747 if (!clang_equalCursors(Info.Cursor, cursor))
5748 return false;
5749
5750 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5751 const unsigned AfterChildren = NextToken();
5752 SourceRange cursorRange = Info.CursorRange;
5753
5754 // Scan the tokens that are at the end of the cursor, but are not captured
5755 // but the child cursors.
5756 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5757
5758 // Scan the tokens that are at the beginning of the cursor, but are not
5759 // capture by the child cursors.
5760 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5761 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5762 break;
5763
5764 Cursors[I] = cursor;
5765 }
5766
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005767 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5768 // encountered the attribute cursor.
5769 if (clang_isAttribute(cursor.kind))
5770 TokIdx = Info.BeforeReachingCursorIdx;
5771
Guy Benyei11169dd2012-12-18 14:30:41 +00005772 PostChildrenInfos.pop_back();
5773 return false;
5774}
5775
5776static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5777 CXCursor parent,
5778 CXClientData client_data) {
5779 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5780}
5781
5782static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5783 CXClientData client_data) {
5784 return static_cast<AnnotateTokensWorker*>(client_data)->
5785 postVisitChildren(cursor);
5786}
5787
5788namespace {
5789
5790/// \brief Uses the macro expansions in the preprocessing record to find
5791/// and mark tokens that are macro arguments. This info is used by the
5792/// AnnotateTokensWorker.
5793class MarkMacroArgTokensVisitor {
5794 SourceManager &SM;
5795 CXToken *Tokens;
5796 unsigned NumTokens;
5797 unsigned CurIdx;
5798
5799public:
5800 MarkMacroArgTokensVisitor(SourceManager &SM,
5801 CXToken *tokens, unsigned numTokens)
5802 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5803
5804 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5805 if (cursor.kind != CXCursor_MacroExpansion)
5806 return CXChildVisit_Continue;
5807
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005808 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005809 if (macroRange.getBegin() == macroRange.getEnd())
5810 return CXChildVisit_Continue; // it's not a function macro.
5811
5812 for (; CurIdx < NumTokens; ++CurIdx) {
5813 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5814 macroRange.getBegin()))
5815 break;
5816 }
5817
5818 if (CurIdx == NumTokens)
5819 return CXChildVisit_Break;
5820
5821 for (; CurIdx < NumTokens; ++CurIdx) {
5822 SourceLocation tokLoc = getTokenLoc(CurIdx);
5823 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5824 break;
5825
5826 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5827 }
5828
5829 if (CurIdx == NumTokens)
5830 return CXChildVisit_Break;
5831
5832 return CXChildVisit_Continue;
5833 }
5834
5835private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005836 CXToken &getTok(unsigned Idx) {
5837 assert(Idx < NumTokens);
5838 return Tokens[Idx];
5839 }
5840 const CXToken &getTok(unsigned Idx) const {
5841 assert(Idx < NumTokens);
5842 return Tokens[Idx];
5843 }
5844
Guy Benyei11169dd2012-12-18 14:30:41 +00005845 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005846 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005847 }
5848
5849 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5850 // The third field is reserved and currently not used. Use it here
5851 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005852 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005853 }
5854};
5855
5856} // end anonymous namespace
5857
5858static CXChildVisitResult
5859MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5860 CXClientData client_data) {
5861 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5862 parent);
5863}
5864
5865namespace {
5866 struct clang_annotateTokens_Data {
5867 CXTranslationUnit TU;
5868 ASTUnit *CXXUnit;
5869 CXToken *Tokens;
5870 unsigned NumTokens;
5871 CXCursor *Cursors;
5872 };
5873}
5874
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005875/// \brief Used by \c annotatePreprocessorTokens.
5876/// \returns true if lexing was finished, false otherwise.
5877static bool lexNext(Lexer &Lex, Token &Tok,
5878 unsigned &NextIdx, unsigned NumTokens) {
5879 if (NextIdx >= NumTokens)
5880 return true;
5881
5882 ++NextIdx;
5883 Lex.LexFromRawLexer(Tok);
5884 if (Tok.is(tok::eof))
5885 return true;
5886
5887 return false;
5888}
5889
Guy Benyei11169dd2012-12-18 14:30:41 +00005890static void annotatePreprocessorTokens(CXTranslationUnit TU,
5891 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005892 CXCursor *Cursors,
5893 CXToken *Tokens,
5894 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005895 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005896
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005897 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5899 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005900 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005902 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005903
5904 if (BeginLocInfo.first != EndLocInfo.first)
5905 return;
5906
5907 StringRef Buffer;
5908 bool Invalid = false;
5909 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5910 if (Buffer.empty() || Invalid)
5911 return;
5912
5913 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5914 CXXUnit->getASTContext().getLangOpts(),
5915 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5916 Buffer.end());
5917 Lex.SetCommentRetentionState(true);
5918
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005919 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005920 // Lex tokens in raw mode until we hit the end of the range, to avoid
5921 // entering #includes or expanding macros.
5922 while (true) {
5923 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005924 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5925 break;
5926 unsigned TokIdx = NextIdx-1;
5927 assert(Tok.getLocation() ==
5928 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005929
5930 reprocess:
5931 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005932 // We have found a preprocessing directive. Annotate the tokens
5933 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005934 //
5935 // FIXME: Some simple tests here could identify macro definitions and
5936 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005937
5938 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005939 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5940 break;
5941
Craig Topper69186e72014-06-08 08:38:04 +00005942 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005943 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005944 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5945 break;
5946
5947 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005948 IdentifierInfo &II =
5949 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005950 SourceLocation MappedTokLoc =
5951 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5952 MI = getMacroInfo(II, MappedTokLoc, TU);
5953 }
5954 }
5955
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005956 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005957 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005958 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5959 finished = true;
5960 break;
5961 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005962 // If we are in a macro definition, check if the token was ever a
5963 // macro name and annotate it if that's the case.
5964 if (MI) {
5965 SourceLocation SaveLoc = Tok.getLocation();
5966 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5967 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5968 Tok.setLocation(SaveLoc);
5969 if (MacroDef)
5970 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5971 Tok.getLocation(), TU);
5972 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005973 } while (!Tok.isAtStartOfLine());
5974
5975 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5976 assert(TokIdx <= LastIdx);
5977 SourceLocation EndLoc =
5978 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5979 CXCursor Cursor =
5980 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5981
5982 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005983 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005984
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005985 if (finished)
5986 break;
5987 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005988 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005989 }
5990}
5991
5992// This gets run a separate thread to avoid stack blowout.
5993static void clang_annotateTokensImpl(void *UserData) {
5994 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5995 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5996 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5997 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5998 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5999
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006000 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006001 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6002 setThreadBackgroundPriority();
6003
6004 // Determine the region of interest, which contains all of the tokens.
6005 SourceRange RegionOfInterest;
6006 RegionOfInterest.setBegin(
6007 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6008 RegionOfInterest.setEnd(
6009 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6010 Tokens[NumTokens-1])));
6011
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 // Relex the tokens within the source range to look for preprocessing
6013 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006014 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006015
6016 // If begin location points inside a macro argument, set it to the expansion
6017 // location so we can have the full context when annotating semantically.
6018 {
6019 SourceManager &SM = CXXUnit->getSourceManager();
6020 SourceLocation Loc =
6021 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6022 if (Loc.isMacroID())
6023 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6024 }
6025
Guy Benyei11169dd2012-12-18 14:30:41 +00006026 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6027 // Search and mark tokens that are macro argument expansions.
6028 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6029 Tokens, NumTokens);
6030 CursorVisitor MacroArgMarker(TU,
6031 MarkMacroArgTokensVisitorDelegate, &Visitor,
6032 /*VisitPreprocessorLast=*/true,
6033 /*VisitIncludedEntities=*/false,
6034 RegionOfInterest);
6035 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6036 }
6037
6038 // Annotate all of the source locations in the region of interest that map to
6039 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006040 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006041
6042 // FIXME: We use a ridiculous stack size here because the data-recursion
6043 // algorithm uses a large stack frame than the non-data recursive version,
6044 // and AnnotationTokensWorker currently transforms the data-recursion
6045 // algorithm back into a traditional recursion by explicitly calling
6046 // VisitChildren(). We will need to remove this explicit recursive call.
6047 W.AnnotateTokens();
6048
6049 // If we ran into any entities that involve context-sensitive keywords,
6050 // take another pass through the tokens to mark them as such.
6051 if (W.hasContextSensitiveKeywords()) {
6052 for (unsigned I = 0; I != NumTokens; ++I) {
6053 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6054 continue;
6055
6056 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6057 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006058 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006059 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6060 if (Property->getPropertyAttributesAsWritten() != 0 &&
6061 llvm::StringSwitch<bool>(II->getName())
6062 .Case("readonly", true)
6063 .Case("assign", true)
6064 .Case("unsafe_unretained", true)
6065 .Case("readwrite", true)
6066 .Case("retain", true)
6067 .Case("copy", true)
6068 .Case("nonatomic", true)
6069 .Case("atomic", true)
6070 .Case("getter", true)
6071 .Case("setter", true)
6072 .Case("strong", true)
6073 .Case("weak", true)
6074 .Default(false))
6075 Tokens[I].int_data[0] = CXToken_Keyword;
6076 }
6077 continue;
6078 }
6079
6080 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6081 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6082 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6083 if (llvm::StringSwitch<bool>(II->getName())
6084 .Case("in", true)
6085 .Case("out", true)
6086 .Case("inout", true)
6087 .Case("oneway", true)
6088 .Case("bycopy", true)
6089 .Case("byref", true)
6090 .Default(false))
6091 Tokens[I].int_data[0] = CXToken_Keyword;
6092 continue;
6093 }
6094
6095 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6096 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6097 Tokens[I].int_data[0] = CXToken_Keyword;
6098 continue;
6099 }
6100 }
6101 }
6102}
6103
6104extern "C" {
6105
6106void clang_annotateTokens(CXTranslationUnit TU,
6107 CXToken *Tokens, unsigned NumTokens,
6108 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006109 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006110 LOG_BAD_TU(TU);
6111 return;
6112 }
6113 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006114 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006115 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006116 }
6117
6118 LOG_FUNC_SECTION {
6119 *Log << TU << ' ';
6120 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6121 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6122 *Log << clang_getRange(bloc, eloc);
6123 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006124
6125 // Any token we don't specifically annotate will have a NULL cursor.
6126 CXCursor C = clang_getNullCursor();
6127 for (unsigned I = 0; I != NumTokens; ++I)
6128 Cursors[I] = C;
6129
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006130 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006131 if (!CXXUnit)
6132 return;
6133
6134 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6135
6136 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6137 llvm::CrashRecoveryContext CRC;
6138 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6139 GetSafetyThreadStackSize() * 2)) {
6140 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6141 }
6142}
6143
6144} // end: extern "C"
6145
6146//===----------------------------------------------------------------------===//
6147// Operations for querying linkage of a cursor.
6148//===----------------------------------------------------------------------===//
6149
6150extern "C" {
6151CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6152 if (!clang_isDeclaration(cursor.kind))
6153 return CXLinkage_Invalid;
6154
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006155 const Decl *D = cxcursor::getCursorDecl(cursor);
6156 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006157 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006158 case NoLinkage:
6159 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006160 case InternalLinkage: return CXLinkage_Internal;
6161 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6162 case ExternalLinkage: return CXLinkage_External;
6163 };
6164
6165 return CXLinkage_Invalid;
6166}
6167} // end: extern "C"
6168
6169//===----------------------------------------------------------------------===//
6170// Operations for querying language of a cursor.
6171//===----------------------------------------------------------------------===//
6172
6173static CXLanguageKind getDeclLanguage(const Decl *D) {
6174 if (!D)
6175 return CXLanguage_C;
6176
6177 switch (D->getKind()) {
6178 default:
6179 break;
6180 case Decl::ImplicitParam:
6181 case Decl::ObjCAtDefsField:
6182 case Decl::ObjCCategory:
6183 case Decl::ObjCCategoryImpl:
6184 case Decl::ObjCCompatibleAlias:
6185 case Decl::ObjCImplementation:
6186 case Decl::ObjCInterface:
6187 case Decl::ObjCIvar:
6188 case Decl::ObjCMethod:
6189 case Decl::ObjCProperty:
6190 case Decl::ObjCPropertyImpl:
6191 case Decl::ObjCProtocol:
6192 return CXLanguage_ObjC;
6193 case Decl::CXXConstructor:
6194 case Decl::CXXConversion:
6195 case Decl::CXXDestructor:
6196 case Decl::CXXMethod:
6197 case Decl::CXXRecord:
6198 case Decl::ClassTemplate:
6199 case Decl::ClassTemplatePartialSpecialization:
6200 case Decl::ClassTemplateSpecialization:
6201 case Decl::Friend:
6202 case Decl::FriendTemplate:
6203 case Decl::FunctionTemplate:
6204 case Decl::LinkageSpec:
6205 case Decl::Namespace:
6206 case Decl::NamespaceAlias:
6207 case Decl::NonTypeTemplateParm:
6208 case Decl::StaticAssert:
6209 case Decl::TemplateTemplateParm:
6210 case Decl::TemplateTypeParm:
6211 case Decl::UnresolvedUsingTypename:
6212 case Decl::UnresolvedUsingValue:
6213 case Decl::Using:
6214 case Decl::UsingDirective:
6215 case Decl::UsingShadow:
6216 return CXLanguage_CPlusPlus;
6217 }
6218
6219 return CXLanguage_C;
6220}
6221
6222extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006223
6224static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6225 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6226 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006227
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006228 switch (D->getAvailability()) {
6229 case AR_Available:
6230 case AR_NotYetIntroduced:
6231 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006232 return getCursorAvailabilityForDecl(
6233 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006234 return CXAvailability_Available;
6235
6236 case AR_Deprecated:
6237 return CXAvailability_Deprecated;
6238
6239 case AR_Unavailable:
6240 return CXAvailability_NotAvailable;
6241 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006242
6243 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006244}
6245
Guy Benyei11169dd2012-12-18 14:30:41 +00006246enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6247 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006248 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6249 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006250
6251 return CXAvailability_Available;
6252}
6253
6254static CXVersion convertVersion(VersionTuple In) {
6255 CXVersion Out = { -1, -1, -1 };
6256 if (In.empty())
6257 return Out;
6258
6259 Out.Major = In.getMajor();
6260
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006261 Optional<unsigned> Minor = In.getMinor();
6262 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006263 Out.Minor = *Minor;
6264 else
6265 return Out;
6266
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006267 Optional<unsigned> Subminor = In.getSubminor();
6268 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006269 Out.Subminor = *Subminor;
6270
6271 return Out;
6272}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006273
6274static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6275 int *always_deprecated,
6276 CXString *deprecated_message,
6277 int *always_unavailable,
6278 CXString *unavailable_message,
6279 CXPlatformAvailability *availability,
6280 int availability_size) {
6281 bool HadAvailAttr = false;
6282 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006283 for (auto A : D->attrs()) {
6284 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006285 HadAvailAttr = true;
6286 if (always_deprecated)
6287 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006288 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006289 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006290 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006291 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006292 continue;
6293 }
6294
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006295 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006296 HadAvailAttr = true;
6297 if (always_unavailable)
6298 *always_unavailable = 1;
6299 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006300 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006301 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6302 }
6303 continue;
6304 }
6305
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006306 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006307 HadAvailAttr = true;
6308 if (N < availability_size) {
6309 availability[N].Platform
6310 = cxstring::createDup(Avail->getPlatform()->getName());
6311 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6312 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6313 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6314 availability[N].Unavailable = Avail->getUnavailable();
6315 availability[N].Message = cxstring::createDup(Avail->getMessage());
6316 }
6317 ++N;
6318 }
6319 }
6320
6321 if (!HadAvailAttr)
6322 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6323 return getCursorPlatformAvailabilityForDecl(
6324 cast<Decl>(EnumConst->getDeclContext()),
6325 always_deprecated,
6326 deprecated_message,
6327 always_unavailable,
6328 unavailable_message,
6329 availability,
6330 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006331
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006332 return N;
6333}
6334
Guy Benyei11169dd2012-12-18 14:30:41 +00006335int clang_getCursorPlatformAvailability(CXCursor cursor,
6336 int *always_deprecated,
6337 CXString *deprecated_message,
6338 int *always_unavailable,
6339 CXString *unavailable_message,
6340 CXPlatformAvailability *availability,
6341 int availability_size) {
6342 if (always_deprecated)
6343 *always_deprecated = 0;
6344 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006345 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006346 if (always_unavailable)
6347 *always_unavailable = 0;
6348 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006349 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006350
Guy Benyei11169dd2012-12-18 14:30:41 +00006351 if (!clang_isDeclaration(cursor.kind))
6352 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006353
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006354 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006355 if (!D)
6356 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006357
6358 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6359 deprecated_message,
6360 always_unavailable,
6361 unavailable_message,
6362 availability,
6363 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006364}
6365
6366void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6367 clang_disposeString(availability->Platform);
6368 clang_disposeString(availability->Message);
6369}
6370
6371CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6372 if (clang_isDeclaration(cursor.kind))
6373 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6374
6375 return CXLanguage_Invalid;
6376}
6377
6378 /// \brief If the given cursor is the "templated" declaration
6379 /// descibing a class or function template, return the class or
6380 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006381static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006383 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006384
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006385 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006386 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6387 return FunTmpl;
6388
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006389 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006390 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6391 return ClassTmpl;
6392
6393 return D;
6394}
6395
6396CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6397 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006398 if (const Decl *D = getCursorDecl(cursor)) {
6399 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006400 if (!DC)
6401 return clang_getNullCursor();
6402
6403 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6404 getCursorTU(cursor));
6405 }
6406 }
6407
6408 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006409 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006410 return MakeCXCursor(D, getCursorTU(cursor));
6411 }
6412
6413 return clang_getNullCursor();
6414}
6415
6416CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6417 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006418 if (const Decl *D = getCursorDecl(cursor)) {
6419 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006420 if (!DC)
6421 return clang_getNullCursor();
6422
6423 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6424 getCursorTU(cursor));
6425 }
6426 }
6427
6428 // FIXME: Note that we can't easily compute the lexical context of a
6429 // statement or expression, so we return nothing.
6430 return clang_getNullCursor();
6431}
6432
6433CXFile clang_getIncludedFile(CXCursor cursor) {
6434 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006435 return nullptr;
6436
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006437 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006438 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006439}
6440
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006441unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6442 if (C.kind != CXCursor_ObjCPropertyDecl)
6443 return CXObjCPropertyAttr_noattr;
6444
6445 unsigned Result = CXObjCPropertyAttr_noattr;
6446 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6447 ObjCPropertyDecl::PropertyAttributeKind Attr =
6448 PD->getPropertyAttributesAsWritten();
6449
6450#define SET_CXOBJCPROP_ATTR(A) \
6451 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6452 Result |= CXObjCPropertyAttr_##A
6453 SET_CXOBJCPROP_ATTR(readonly);
6454 SET_CXOBJCPROP_ATTR(getter);
6455 SET_CXOBJCPROP_ATTR(assign);
6456 SET_CXOBJCPROP_ATTR(readwrite);
6457 SET_CXOBJCPROP_ATTR(retain);
6458 SET_CXOBJCPROP_ATTR(copy);
6459 SET_CXOBJCPROP_ATTR(nonatomic);
6460 SET_CXOBJCPROP_ATTR(setter);
6461 SET_CXOBJCPROP_ATTR(atomic);
6462 SET_CXOBJCPROP_ATTR(weak);
6463 SET_CXOBJCPROP_ATTR(strong);
6464 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6465#undef SET_CXOBJCPROP_ATTR
6466
6467 return Result;
6468}
6469
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006470unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6471 if (!clang_isDeclaration(C.kind))
6472 return CXObjCDeclQualifier_None;
6473
6474 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6475 const Decl *D = getCursorDecl(C);
6476 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6477 QT = MD->getObjCDeclQualifier();
6478 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6479 QT = PD->getObjCDeclQualifier();
6480 if (QT == Decl::OBJC_TQ_None)
6481 return CXObjCDeclQualifier_None;
6482
6483 unsigned Result = CXObjCDeclQualifier_None;
6484 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6485 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6486 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6487 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6488 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6489 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6490
6491 return Result;
6492}
6493
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006494unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6495 if (!clang_isDeclaration(C.kind))
6496 return 0;
6497
6498 const Decl *D = getCursorDecl(C);
6499 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6500 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6501 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6502 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6503
6504 return 0;
6505}
6506
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006507unsigned clang_Cursor_isVariadic(CXCursor C) {
6508 if (!clang_isDeclaration(C.kind))
6509 return 0;
6510
6511 const Decl *D = getCursorDecl(C);
6512 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6513 return FD->isVariadic();
6514 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6515 return MD->isVariadic();
6516
6517 return 0;
6518}
6519
Guy Benyei11169dd2012-12-18 14:30:41 +00006520CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6521 if (!clang_isDeclaration(C.kind))
6522 return clang_getNullRange();
6523
6524 const Decl *D = getCursorDecl(C);
6525 ASTContext &Context = getCursorContext(C);
6526 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6527 if (!RC)
6528 return clang_getNullRange();
6529
6530 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6531}
6532
6533CXString clang_Cursor_getRawCommentText(CXCursor C) {
6534 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006535 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006536
6537 const Decl *D = getCursorDecl(C);
6538 ASTContext &Context = getCursorContext(C);
6539 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6540 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6541 StringRef();
6542
6543 // Don't duplicate the string because RawText points directly into source
6544 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006545 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006546}
6547
6548CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6549 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006550 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006551
6552 const Decl *D = getCursorDecl(C);
6553 const ASTContext &Context = getCursorContext(C);
6554 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6555
6556 if (RC) {
6557 StringRef BriefText = RC->getBriefText(Context);
6558
6559 // Don't duplicate the string because RawComment ensures that this memory
6560 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006561 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006562 }
6563
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006564 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006565}
6566
Guy Benyei11169dd2012-12-18 14:30:41 +00006567CXModule clang_Cursor_getModule(CXCursor C) {
6568 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006569 if (const ImportDecl *ImportD =
6570 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 return ImportD->getImportedModule();
6572 }
6573
Craig Topper69186e72014-06-08 08:38:04 +00006574 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006575}
6576
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006577CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6578 if (isNotUsableTU(TU)) {
6579 LOG_BAD_TU(TU);
6580 return nullptr;
6581 }
6582 if (!File)
6583 return nullptr;
6584 FileEntry *FE = static_cast<FileEntry *>(File);
6585
6586 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6587 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6588 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6589
6590 if (Module *Mod = Header.getModule()) {
6591 if (Header.getRole() != ModuleMap::ExcludedHeader)
6592 return Mod;
6593 }
6594 return nullptr;
6595}
6596
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006597CXFile clang_Module_getASTFile(CXModule CXMod) {
6598 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006599 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006600 Module *Mod = static_cast<Module*>(CXMod);
6601 return const_cast<FileEntry *>(Mod->getASTFile());
6602}
6603
Guy Benyei11169dd2012-12-18 14:30:41 +00006604CXModule clang_Module_getParent(CXModule CXMod) {
6605 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006606 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006607 Module *Mod = static_cast<Module*>(CXMod);
6608 return Mod->Parent;
6609}
6610
6611CXString clang_Module_getName(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->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006616}
6617
6618CXString clang_Module_getFullName(CXModule CXMod) {
6619 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006620 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006621 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006622 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006623}
6624
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006625int clang_Module_isSystem(CXModule CXMod) {
6626 if (!CXMod)
6627 return 0;
6628 Module *Mod = static_cast<Module*>(CXMod);
6629 return Mod->IsSystem;
6630}
6631
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006632unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6633 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006634 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006635 LOG_BAD_TU(TU);
6636 return 0;
6637 }
6638 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006639 return 0;
6640 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006641 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6642 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6643 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006644}
6645
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006646CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6647 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006648 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006649 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006650 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006651 }
6652 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006653 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006654 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006655 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006656
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006657 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6658 if (Index < TopHeaders.size())
6659 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006660
Craig Topper69186e72014-06-08 08:38:04 +00006661 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006662}
6663
6664} // end: extern "C"
6665
6666//===----------------------------------------------------------------------===//
6667// C++ AST instrospection.
6668//===----------------------------------------------------------------------===//
6669
6670extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006671unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6672 if (!clang_isDeclaration(C.kind))
6673 return 0;
6674
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006675 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006676 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006677 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006678 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6679}
6680
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006681unsigned clang_CXXMethod_isConst(CXCursor C) {
6682 if (!clang_isDeclaration(C.kind))
6683 return 0;
6684
6685 const Decl *D = cxcursor::getCursorDecl(C);
6686 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006687 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006688 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6689}
6690
Guy Benyei11169dd2012-12-18 14:30:41 +00006691unsigned clang_CXXMethod_isStatic(CXCursor C) {
6692 if (!clang_isDeclaration(C.kind))
6693 return 0;
6694
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006695 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006696 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006697 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006698 return (Method && Method->isStatic()) ? 1 : 0;
6699}
6700
6701unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6702 if (!clang_isDeclaration(C.kind))
6703 return 0;
6704
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006705 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006706 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006707 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006708 return (Method && Method->isVirtual()) ? 1 : 0;
6709}
6710} // end: extern "C"
6711
6712//===----------------------------------------------------------------------===//
6713// Attribute introspection.
6714//===----------------------------------------------------------------------===//
6715
6716extern "C" {
6717CXType clang_getIBOutletCollectionType(CXCursor C) {
6718 if (C.kind != CXCursor_IBOutletCollectionAttr)
6719 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6720
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006721 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006722 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6723
6724 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6725}
6726} // end: extern "C"
6727
6728//===----------------------------------------------------------------------===//
6729// Inspecting memory usage.
6730//===----------------------------------------------------------------------===//
6731
6732typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6733
6734static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6735 enum CXTUResourceUsageKind k,
6736 unsigned long amount) {
6737 CXTUResourceUsageEntry entry = { k, amount };
6738 entries.push_back(entry);
6739}
6740
6741extern "C" {
6742
6743const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6744 const char *str = "";
6745 switch (kind) {
6746 case CXTUResourceUsage_AST:
6747 str = "ASTContext: expressions, declarations, and types";
6748 break;
6749 case CXTUResourceUsage_Identifiers:
6750 str = "ASTContext: identifiers";
6751 break;
6752 case CXTUResourceUsage_Selectors:
6753 str = "ASTContext: selectors";
6754 break;
6755 case CXTUResourceUsage_GlobalCompletionResults:
6756 str = "Code completion: cached global results";
6757 break;
6758 case CXTUResourceUsage_SourceManagerContentCache:
6759 str = "SourceManager: content cache allocator";
6760 break;
6761 case CXTUResourceUsage_AST_SideTables:
6762 str = "ASTContext: side tables";
6763 break;
6764 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6765 str = "SourceManager: malloc'ed memory buffers";
6766 break;
6767 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6768 str = "SourceManager: mmap'ed memory buffers";
6769 break;
6770 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6771 str = "ExternalASTSource: malloc'ed memory buffers";
6772 break;
6773 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6774 str = "ExternalASTSource: mmap'ed memory buffers";
6775 break;
6776 case CXTUResourceUsage_Preprocessor:
6777 str = "Preprocessor: malloc'ed memory";
6778 break;
6779 case CXTUResourceUsage_PreprocessingRecord:
6780 str = "Preprocessor: PreprocessingRecord";
6781 break;
6782 case CXTUResourceUsage_SourceManager_DataStructures:
6783 str = "SourceManager: data structures and tables";
6784 break;
6785 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6786 str = "Preprocessor: header search tables";
6787 break;
6788 }
6789 return str;
6790}
6791
6792CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006793 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006794 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006795 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006796 return usage;
6797 }
6798
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006799 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006800 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006801 ASTContext &astContext = astUnit->getASTContext();
6802
6803 // How much memory is used by AST nodes and types?
6804 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6805 (unsigned long) astContext.getASTAllocatedMemory());
6806
6807 // How much memory is used by identifiers?
6808 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6809 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6810
6811 // How much memory is used for selectors?
6812 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6813 (unsigned long) astContext.Selectors.getTotalMemory());
6814
6815 // How much memory is used by ASTContext's side tables?
6816 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6817 (unsigned long) astContext.getSideTableAllocatedMemory());
6818
6819 // How much memory is used for caching global code completion results?
6820 unsigned long completionBytes = 0;
6821 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006822 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006823 completionBytes = completionAllocator->getTotalMemory();
6824 }
6825 createCXTUResourceUsageEntry(*entries,
6826 CXTUResourceUsage_GlobalCompletionResults,
6827 completionBytes);
6828
6829 // How much memory is being used by SourceManager's content cache?
6830 createCXTUResourceUsageEntry(*entries,
6831 CXTUResourceUsage_SourceManagerContentCache,
6832 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6833
6834 // How much memory is being used by the MemoryBuffer's in SourceManager?
6835 const SourceManager::MemoryBufferSizes &srcBufs =
6836 astUnit->getSourceManager().getMemoryBufferSizes();
6837
6838 createCXTUResourceUsageEntry(*entries,
6839 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6840 (unsigned long) srcBufs.malloc_bytes);
6841 createCXTUResourceUsageEntry(*entries,
6842 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6843 (unsigned long) srcBufs.mmap_bytes);
6844 createCXTUResourceUsageEntry(*entries,
6845 CXTUResourceUsage_SourceManager_DataStructures,
6846 (unsigned long) astContext.getSourceManager()
6847 .getDataStructureSizes());
6848
6849 // How much memory is being used by the ExternalASTSource?
6850 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6851 const ExternalASTSource::MemoryBufferSizes &sizes =
6852 esrc->getMemoryBufferSizes();
6853
6854 createCXTUResourceUsageEntry(*entries,
6855 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6856 (unsigned long) sizes.malloc_bytes);
6857 createCXTUResourceUsageEntry(*entries,
6858 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6859 (unsigned long) sizes.mmap_bytes);
6860 }
6861
6862 // How much memory is being used by the Preprocessor?
6863 Preprocessor &pp = astUnit->getPreprocessor();
6864 createCXTUResourceUsageEntry(*entries,
6865 CXTUResourceUsage_Preprocessor,
6866 pp.getTotalMemory());
6867
6868 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6869 createCXTUResourceUsageEntry(*entries,
6870 CXTUResourceUsage_PreprocessingRecord,
6871 pRec->getTotalMemory());
6872 }
6873
6874 createCXTUResourceUsageEntry(*entries,
6875 CXTUResourceUsage_Preprocessor_HeaderSearch,
6876 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006877
Guy Benyei11169dd2012-12-18 14:30:41 +00006878 CXTUResourceUsage usage = { (void*) entries.get(),
6879 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006880 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006881 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006882 return usage;
6883}
6884
6885void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6886 if (usage.data)
6887 delete (MemUsageEntries*) usage.data;
6888}
6889
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006890CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6891 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006892 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006893 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006894
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006895 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006896 LOG_BAD_TU(TU);
6897 return skipped;
6898 }
6899
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006900 if (!file)
6901 return skipped;
6902
6903 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6904 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6905 if (!ppRec)
6906 return skipped;
6907
6908 ASTContext &Ctx = astUnit->getASTContext();
6909 SourceManager &sm = Ctx.getSourceManager();
6910 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6911 FileID wantedFileID = sm.translateFile(fileEntry);
6912
6913 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6914 std::vector<SourceRange> wantedRanges;
6915 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6916 i != ei; ++i) {
6917 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6918 wantedRanges.push_back(*i);
6919 }
6920
6921 skipped->count = wantedRanges.size();
6922 skipped->ranges = new CXSourceRange[skipped->count];
6923 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6924 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6925
6926 return skipped;
6927}
6928
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006929void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6930 if (ranges) {
6931 delete[] ranges->ranges;
6932 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006933 }
6934}
6935
Guy Benyei11169dd2012-12-18 14:30:41 +00006936} // end extern "C"
6937
6938void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6939 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6940 for (unsigned I = 0; I != Usage.numEntries; ++I)
6941 fprintf(stderr, " %s: %lu\n",
6942 clang_getTUResourceUsageName(Usage.entries[I].kind),
6943 Usage.entries[I].amount);
6944
6945 clang_disposeCXTUResourceUsage(Usage);
6946}
6947
6948//===----------------------------------------------------------------------===//
6949// Misc. utility functions.
6950//===----------------------------------------------------------------------===//
6951
6952/// Default to using an 8 MB stack size on "safety" threads.
6953static unsigned SafetyStackThreadSize = 8 << 20;
6954
6955namespace clang {
6956
6957bool RunSafely(llvm::CrashRecoveryContext &CRC,
6958 void (*Fn)(void*), void *UserData,
6959 unsigned Size) {
6960 if (!Size)
6961 Size = GetSafetyThreadStackSize();
6962 if (Size)
6963 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6964 return CRC.RunSafely(Fn, UserData);
6965}
6966
6967unsigned GetSafetyThreadStackSize() {
6968 return SafetyStackThreadSize;
6969}
6970
6971void SetSafetyThreadStackSize(unsigned Value) {
6972 SafetyStackThreadSize = Value;
6973}
6974
6975}
6976
6977void clang::setThreadBackgroundPriority() {
6978 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6979 return;
6980
Alp Toker1a86ad22014-07-06 06:24:00 +00006981#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006982 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6983#endif
6984}
6985
6986void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6987 if (!Unit)
6988 return;
6989
6990 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6991 DEnd = Unit->stored_diag_end();
6992 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006993 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006994 CXString Msg = clang_formatDiagnostic(&Diag,
6995 clang_defaultDiagnosticDisplayOptions());
6996 fprintf(stderr, "%s\n", clang_getCString(Msg));
6997 clang_disposeString(Msg);
6998 }
6999#ifdef LLVM_ON_WIN32
7000 // On Windows, force a flush, since there may be multiple copies of
7001 // stderr and stdout in the file system, all with different buffers
7002 // but writing to the same device.
7003 fflush(stderr);
7004#endif
7005}
7006
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007007MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7008 SourceLocation MacroDefLoc,
7009 CXTranslationUnit TU){
7010 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007011 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007012 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007013 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007014
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007015 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007016 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007017 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007018 if (MD) {
7019 for (MacroDirective::DefInfo
7020 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7021 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7022 return Def.getMacroInfo();
7023 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007024 }
7025
Craig Topper69186e72014-06-08 08:38:04 +00007026 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007027}
7028
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007029const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7030 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007031 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007032 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007033 const IdentifierInfo *II = MacroDef->getName();
7034 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007035 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007036
7037 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7038}
7039
7040MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7041 const Token &Tok,
7042 CXTranslationUnit TU) {
7043 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007044 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007045 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007046 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007047
7048 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007049 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007050 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7051 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007052 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007053
7054 // Check that the token is inside the definition and not its argument list.
7055 SourceManager &SM = Unit->getSourceManager();
7056 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007057 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007058 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007059 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007060
7061 Preprocessor &PP = Unit->getPreprocessor();
7062 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7063 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007064 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007065
Alp Toker2d57cea2014-05-17 04:53:25 +00007066 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007067 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007068 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007069
7070 // Check that the identifier is not one of the macro arguments.
7071 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007072 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007073
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007074 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7075 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007076 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007077
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007078 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007079}
7080
7081MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7082 SourceLocation Loc,
7083 CXTranslationUnit TU) {
7084 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007085 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007086
7087 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007088 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007089 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007090 Preprocessor &PP = Unit->getPreprocessor();
7091 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007092 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007093 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7094 Token Tok;
7095 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007096 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007097
7098 return checkForMacroInMacroDefinition(MI, Tok, TU);
7099}
7100
Guy Benyei11169dd2012-12-18 14:30:41 +00007101extern "C" {
7102
7103CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007104 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007105}
7106
7107} // end: extern "C"
7108
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007109Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7110 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007111 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007112 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007113 if (Unit->isMainFileAST())
7114 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007115 return *this;
7116 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007117 } else {
7118 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007119 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007120 return *this;
7121}
7122
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007123Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7124 *this << FE->getName();
7125 return *this;
7126}
7127
7128Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7129 CXString cursorName = clang_getCursorDisplayName(cursor);
7130 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7131 clang_disposeString(cursorName);
7132 return *this;
7133}
7134
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007135Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7136 CXFile File;
7137 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007138 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007139 CXString FileName = clang_getFileName(File);
7140 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7141 clang_disposeString(FileName);
7142 return *this;
7143}
7144
7145Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7146 CXSourceLocation BLoc = clang_getRangeStart(range);
7147 CXSourceLocation ELoc = clang_getRangeEnd(range);
7148
7149 CXFile BFile;
7150 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007151 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007152
7153 CXFile EFile;
7154 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007155 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007156
7157 CXString BFileName = clang_getFileName(BFile);
7158 if (BFile == EFile) {
7159 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7160 BLine, BColumn, ELine, EColumn);
7161 } else {
7162 CXString EFileName = clang_getFileName(EFile);
7163 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7164 BLine, BColumn)
7165 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7166 ELine, EColumn);
7167 clang_disposeString(EFileName);
7168 }
7169 clang_disposeString(BFileName);
7170 return *this;
7171}
7172
7173Logger &cxindex::Logger::operator<<(CXString Str) {
7174 *this << clang_getCString(Str);
7175 return *this;
7176}
7177
7178Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7179 LogOS << Fmt;
7180 return *this;
7181}
7182
Chandler Carruth37ad2582014-06-27 15:14:39 +00007183static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7184
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007185cxindex::Logger::~Logger() {
7186 LogOS.flush();
7187
Chandler Carruth37ad2582014-06-27 15:14:39 +00007188 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007189
7190 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7191
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007192 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007193 OS << "[libclang:" << Name << ':';
7194
Alp Toker1a86ad22014-07-06 06:24:00 +00007195#ifdef USE_DARWIN_THREADS
7196 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007197 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7198 OS << tid << ':';
7199#endif
7200
7201 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7202 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7203 OS << Msg.str() << '\n';
7204
7205 if (Trace) {
7206 llvm::sys::PrintStackTrace(stderr);
7207 OS << "--------------------------------------------------\n";
7208 }
7209}