blob: 97a27591cf7b608cae97dcdda1630e8163d581de [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);
1863 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001864 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001865 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001866 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001867 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001868 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001869 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001870 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001871 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001872 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001873 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001874 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001875 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001876 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001877 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001878 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001879 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001880
Guy Benyei11169dd2012-12-18 14:30:41 +00001881private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001882 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001883 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1884 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1886 void AddStmt(const Stmt *S);
1887 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001888 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001890 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001891};
1892} // end anonyous namespace
1893
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 // 'S' should always be non-null, since it comes from the
1896 // statement we are visiting.
1897 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1898}
1899
1900void
1901EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1902 if (Qualifier)
1903 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1904}
1905
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 if (S)
1908 WL.push_back(StmtVisit(S, Parent));
1909}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001910void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001911 if (D)
1912 WL.push_back(DeclVisit(D, Parent, isFirst));
1913}
1914void EnqueueVisitor::
1915 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1916 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001918}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001919void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001920 if (D)
1921 WL.push_back(MemberRefVisit(D, L, Parent));
1922}
1923void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1924 if (TI)
1925 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1926 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001927void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001928 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001929 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001930 AddStmt(*Child);
1931 }
1932 if (size == WL.size())
1933 return;
1934 // Now reverse the entries we just added. This will match the DFS
1935 // ordering performed by the worklist.
1936 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1937 std::reverse(I, E);
1938}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001939namespace {
1940class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1941 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001942 /// \brief Process clauses with list of variables.
1943 template <typename T>
1944 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945public:
1946 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1947#define OPENMP_CLAUSE(Name, Class) \
1948 void Visit##Class(const Class *C);
1949#include "clang/Basic/OpenMPKinds.def"
1950};
1951
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001952void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1953 Visitor->AddStmt(C->getCondition());
1954}
1955
Alexey Bataev3778b602014-07-17 07:32:53 +00001956void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1957 Visitor->AddStmt(C->getCondition());
1958}
1959
Alexey Bataev568a8332014-03-06 06:15:19 +00001960void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1961 Visitor->AddStmt(C->getNumThreads());
1962}
1963
Alexey Bataev62c87d22014-03-21 04:51:18 +00001964void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1965 Visitor->AddStmt(C->getSafelen());
1966}
1967
Alexander Musman8bd31e62014-05-27 15:12:19 +00001968void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1969 Visitor->AddStmt(C->getNumForLoops());
1970}
1971
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001972void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001973
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001974void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1975
Alexey Bataev56dafe82014-06-20 07:16:17 +00001976void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1977 Visitor->AddStmt(C->getChunkSize());
1978}
1979
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001980void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1981
Alexey Bataev236070f2014-06-20 11:19:47 +00001982void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1983
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001984void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1985
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001986void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1987
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001988void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1989
Alexey Bataevdea47612014-07-23 07:46:59 +00001990void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1991
Alexey Bataev67a4f222014-07-23 10:25:33 +00001992void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
1993
Alexey Bataev459dec02014-07-24 06:46:57 +00001994void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
1995
Alexey Bataev82bad8b2014-07-24 08:55:34 +00001996void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
1997
Alexey Bataev756c1962013-09-24 03:17:45 +00001998template<typename T>
1999void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002000 for (const auto *I : Node->varlists())
2001 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00002002}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002003
2004void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002005 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002006}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002007void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2008 const OMPFirstprivateClause *C) {
2009 VisitOMPClauseList(C);
2010}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002011void OMPClauseEnqueue::VisitOMPLastprivateClause(
2012 const OMPLastprivateClause *C) {
2013 VisitOMPClauseList(C);
2014}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002015void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002016 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002017}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002018void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2019 VisitOMPClauseList(C);
2020}
Alexander Musman8dba6642014-04-22 13:09:42 +00002021void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2022 VisitOMPClauseList(C);
2023 Visitor->AddStmt(C->getStep());
2024}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002025void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2026 VisitOMPClauseList(C);
2027 Visitor->AddStmt(C->getAlignment());
2028}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002029void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2030 VisitOMPClauseList(C);
2031}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002032void
2033OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2034 VisitOMPClauseList(C);
2035}
Alexey Bataev6125da92014-07-21 11:26:11 +00002036void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2037 VisitOMPClauseList(C);
2038}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002039}
Alexey Bataev756c1962013-09-24 03:17:45 +00002040
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002041void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2042 unsigned size = WL.size();
2043 OMPClauseEnqueue Visitor(this);
2044 Visitor.Visit(S);
2045 if (size == WL.size())
2046 return;
2047 // Now reverse the entries we just added. This will match the DFS
2048 // ordering performed by the worklist.
2049 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2050 std::reverse(I, E);
2051}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002053 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2054}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 AddDecl(B->getBlockDecl());
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002059 EnqueueChildren(E);
2060 AddTypeLoc(E->getTypeSourceInfo());
2061}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2063 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002064 E = S->body_rend(); I != E; ++I) {
2065 AddStmt(*I);
2066 }
2067}
2068void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 AddStmt(S->getSubStmt());
2071 AddDeclarationNameInfo(S);
2072 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2073 AddNestedNameSpecifierLoc(QualifierLoc);
2074}
2075
2076void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2079 AddDeclarationNameInfo(E);
2080 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2081 AddNestedNameSpecifierLoc(QualifierLoc);
2082 if (!E->isImplicitAccess())
2083 AddStmt(E->getBase());
2084}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002085void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002086 // Enqueue the initializer , if any.
2087 AddStmt(E->getInitializer());
2088 // Enqueue the array size, if any.
2089 AddStmt(E->getArraySize());
2090 // Enqueue the allocated type.
2091 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2092 // Enqueue the placement arguments.
2093 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2094 AddStmt(E->getPlacementArg(I-1));
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2098 AddStmt(CE->getArg(I-1));
2099 AddStmt(CE->getCallee());
2100 AddStmt(CE->getArg(0));
2101}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2103 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002104 // Visit the name of the type being destroyed.
2105 AddTypeLoc(E->getDestroyedTypeInfo());
2106 // Visit the scope type that looks disturbingly like the nested-name-specifier
2107 // but isn't.
2108 AddTypeLoc(E->getScopeTypeInfo());
2109 // Visit the nested-name-specifier.
2110 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2111 AddNestedNameSpecifierLoc(QualifierLoc);
2112 // Visit base expression.
2113 AddStmt(E->getBase());
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2116 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 AddTypeLoc(E->getTypeSourceInfo());
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2120 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 EnqueueChildren(E);
2122 AddTypeLoc(E->getTypeSourceInfo());
2123}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 EnqueueChildren(E);
2126 if (E->isTypeOperand())
2127 AddTypeLoc(E->getTypeOperandSourceInfo());
2128}
2129
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2131 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 EnqueueChildren(E);
2133 AddTypeLoc(E->getTypeSourceInfo());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 EnqueueChildren(E);
2137 if (E->isTypeOperand())
2138 AddTypeLoc(E->getTypeOperandSourceInfo());
2139}
2140
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 EnqueueChildren(S);
2143 AddDecl(S->getExceptionDecl());
2144}
2145
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 if (DR->hasExplicitTemplateArgs()) {
2148 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2149 }
2150 WL.push_back(DeclRefExprParts(DR, Parent));
2151}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2153 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2155 AddDeclarationNameInfo(E);
2156 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 unsigned size = WL.size();
2160 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002161 for (const auto *D : S->decls()) {
2162 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002163 isFirst = false;
2164 }
2165 if (size == WL.size())
2166 return;
2167 // Now reverse the entries we just added. This will match the DFS
2168 // ordering performed by the worklist.
2169 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2170 std::reverse(I, E);
2171}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002172void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002173 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 D = E->designators_rbegin(), DEnd = E->designators_rend();
2176 D != DEnd; ++D) {
2177 if (D->isFieldDesignator()) {
2178 if (FieldDecl *Field = D->getField())
2179 AddMemberRef(Field, D->getFieldLoc());
2180 continue;
2181 }
2182 if (D->isArrayDesignator()) {
2183 AddStmt(E->getArrayIndex(*D));
2184 continue;
2185 }
2186 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2187 AddStmt(E->getArrayRangeEnd(*D));
2188 AddStmt(E->getArrayRangeStart(*D));
2189 }
2190}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 EnqueueChildren(E);
2193 AddTypeLoc(E->getTypeInfoAsWritten());
2194}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002196 AddStmt(FS->getBody());
2197 AddStmt(FS->getInc());
2198 AddStmt(FS->getCond());
2199 AddDecl(FS->getConditionVariable());
2200 AddStmt(FS->getInit());
2201}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddStmt(If->getElse());
2207 AddStmt(If->getThen());
2208 AddStmt(If->getCond());
2209 AddDecl(If->getConditionVariable());
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 // We care about the syntactic form of the initializer list, only.
2213 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2214 IE = Syntactic;
2215 EnqueueChildren(IE);
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 WL.push_back(MemberExprParts(M, Parent));
2219
2220 // If the base of the member access expression is an implicit 'this', don't
2221 // visit it.
2222 // FIXME: If we ever want to show these implicit accesses, this will be
2223 // unfortunate. However, clang_getCursor() relies on this behavior.
2224 if (!M->isImplicitAccess())
2225 AddStmt(M->getBase());
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 AddTypeLoc(E->getEncodedTypeSourceInfo());
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 EnqueueChildren(M);
2232 AddTypeLoc(M->getClassReceiverTypeInfo());
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 // Visit the components of the offsetof expression.
2236 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2237 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2238 const OffsetOfNode &Node = E->getComponent(I-1);
2239 switch (Node.getKind()) {
2240 case OffsetOfNode::Array:
2241 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2242 break;
2243 case OffsetOfNode::Field:
2244 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2245 break;
2246 case OffsetOfNode::Identifier:
2247 case OffsetOfNode::Base:
2248 continue;
2249 }
2250 }
2251 // Visit the type into which we're computing the offset.
2252 AddTypeLoc(E->getTypeSourceInfo());
2253}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002254void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002255 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2256 WL.push_back(OverloadExprParts(E, Parent));
2257}
2258void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 EnqueueChildren(E);
2261 if (E->isArgumentType())
2262 AddTypeLoc(E->getArgumentTypeInfo());
2263}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 EnqueueChildren(S);
2266}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 AddStmt(S->getBody());
2269 AddStmt(S->getCond());
2270 AddDecl(S->getConditionVariable());
2271}
2272
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 AddStmt(W->getBody());
2275 AddStmt(W->getCond());
2276 AddDecl(W->getConditionVariable());
2277}
2278
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 for (unsigned I = E->getNumArgs(); I > 0; --I)
2281 AddTypeLoc(E->getArg(I-1));
2282}
2283
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 AddTypeLoc(E->getQueriedTypeSourceInfo());
2286}
2287
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 EnqueueChildren(E);
2290}
2291
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 VisitOverloadExpr(U);
2294 if (!U->isImplicitAccess())
2295 AddStmt(U->getBase());
2296}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002298 AddStmt(E->getSubExpr());
2299 AddTypeLoc(E->getWrittenTypeInfo());
2300}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002301void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002302 WL.push_back(SizeOfPackExprParts(E, Parent));
2303}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002304void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002305 // If the opaque value has a source expression, just transparently
2306 // visit that. This is useful for (e.g.) pseudo-object expressions.
2307 if (Expr *SourceExpr = E->getSourceExpr())
2308 return Visit(SourceExpr);
2309}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 AddStmt(E->getBody());
2312 WL.push_back(LambdaExprParts(E, Parent));
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 // Treat the expression like its syntactic form.
2316 Visit(E->getSyntacticForm());
2317}
2318
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002319void EnqueueVisitor::VisitOMPExecutableDirective(
2320 const OMPExecutableDirective *D) {
2321 EnqueueChildren(D);
2322 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2323 E = D->clauses().end();
2324 I != E; ++I)
2325 EnqueueChildren(*I);
2326}
2327
2328void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2329 VisitOMPExecutableDirective(D);
2330}
2331
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002332void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2333 VisitOMPExecutableDirective(D);
2334}
2335
Alexey Bataevf29276e2014-06-18 04:14:57 +00002336void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2337 VisitOMPExecutableDirective(D);
2338}
2339
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002340void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2341 VisitOMPExecutableDirective(D);
2342}
2343
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002344void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2345 VisitOMPExecutableDirective(D);
2346}
2347
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002348void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2349 VisitOMPExecutableDirective(D);
2350}
2351
Alexander Musman80c22892014-07-17 08:54:58 +00002352void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2353 VisitOMPExecutableDirective(D);
2354}
2355
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002356void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2357 VisitOMPExecutableDirective(D);
2358 AddDeclarationNameInfo(D);
2359}
2360
Alexey Bataev4acb8592014-07-07 13:01:15 +00002361void
2362EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2363 VisitOMPExecutableDirective(D);
2364}
2365
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002366void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2367 const OMPParallelSectionsDirective *D) {
2368 VisitOMPExecutableDirective(D);
2369}
2370
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002371void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2372 VisitOMPExecutableDirective(D);
2373}
2374
Alexey Bataev68446b72014-07-18 07:47:19 +00002375void
2376EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2377 VisitOMPExecutableDirective(D);
2378}
2379
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002380void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2381 VisitOMPExecutableDirective(D);
2382}
2383
Alexey Bataev2df347a2014-07-18 10:17:07 +00002384void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2385 VisitOMPExecutableDirective(D);
2386}
2387
Alexey Bataev6125da92014-07-21 11:26:11 +00002388void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2389 VisitOMPExecutableDirective(D);
2390}
2391
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002392void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2393 VisitOMPExecutableDirective(D);
2394}
2395
Alexey Bataev0162e452014-07-22 10:10:35 +00002396void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2397 VisitOMPExecutableDirective(D);
2398}
2399
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002400void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002401 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2402}
2403
2404bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2405 if (RegionOfInterest.isValid()) {
2406 SourceRange Range = getRawCursorExtent(C);
2407 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2408 return false;
2409 }
2410 return true;
2411}
2412
2413bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2414 while (!WL.empty()) {
2415 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002416 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002417
2418 // Set the Parent field, then back to its old value once we're done.
2419 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2420
2421 switch (LI.getKind()) {
2422 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002423 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002424 if (!D)
2425 continue;
2426
2427 // For now, perform default visitation for Decls.
2428 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2429 cast<DeclVisit>(&LI)->isFirst())))
2430 return true;
2431
2432 continue;
2433 }
2434 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2435 const ASTTemplateArgumentListInfo *ArgList =
2436 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2437 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2438 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2439 Arg != ArgEnd; ++Arg) {
2440 if (VisitTemplateArgumentLoc(*Arg))
2441 return true;
2442 }
2443 continue;
2444 }
2445 case VisitorJob::TypeLocVisitKind: {
2446 // Perform default visitation for TypeLocs.
2447 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2448 return true;
2449 continue;
2450 }
2451 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002452 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002453 if (LabelStmt *stmt = LS->getStmt()) {
2454 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2455 TU))) {
2456 return true;
2457 }
2458 }
2459 continue;
2460 }
2461
2462 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2463 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2464 if (VisitNestedNameSpecifierLoc(V->get()))
2465 return true;
2466 continue;
2467 }
2468
2469 case VisitorJob::DeclarationNameInfoVisitKind: {
2470 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2471 ->get()))
2472 return true;
2473 continue;
2474 }
2475 case VisitorJob::MemberRefVisitKind: {
2476 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2477 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2478 return true;
2479 continue;
2480 }
2481 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002482 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002483 if (!S)
2484 continue;
2485
2486 // Update the current cursor.
2487 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2488 if (!IsInRegionOfInterest(Cursor))
2489 continue;
2490 switch (Visitor(Cursor, Parent, ClientData)) {
2491 case CXChildVisit_Break: return true;
2492 case CXChildVisit_Continue: break;
2493 case CXChildVisit_Recurse:
2494 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002495 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002496 EnqueueWorkList(WL, S);
2497 break;
2498 }
2499 continue;
2500 }
2501 case VisitorJob::MemberExprPartsKind: {
2502 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002503 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002504
2505 // Visit the nested-name-specifier
2506 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2507 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2508 return true;
2509
2510 // Visit the declaration name.
2511 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2512 return true;
2513
2514 // Visit the explicitly-specified template arguments, if any.
2515 if (M->hasExplicitTemplateArgs()) {
2516 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2517 *ArgEnd = Arg + M->getNumTemplateArgs();
2518 Arg != ArgEnd; ++Arg) {
2519 if (VisitTemplateArgumentLoc(*Arg))
2520 return true;
2521 }
2522 }
2523 continue;
2524 }
2525 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002526 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002527 // Visit nested-name-specifier, if present.
2528 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2529 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2530 return true;
2531 // Visit declaration name.
2532 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2533 return true;
2534 continue;
2535 }
2536 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002537 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002538 // Visit the nested-name-specifier.
2539 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2540 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2541 return true;
2542 // Visit the declaration name.
2543 if (VisitDeclarationNameInfo(O->getNameInfo()))
2544 return true;
2545 // Visit the overloaded declaration reference.
2546 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2547 return true;
2548 continue;
2549 }
2550 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002551 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002552 NamedDecl *Pack = E->getPack();
2553 if (isa<TemplateTypeParmDecl>(Pack)) {
2554 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2555 E->getPackLoc(), TU)))
2556 return true;
2557
2558 continue;
2559 }
2560
2561 if (isa<TemplateTemplateParmDecl>(Pack)) {
2562 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2563 E->getPackLoc(), TU)))
2564 return true;
2565
2566 continue;
2567 }
2568
2569 // Non-type template parameter packs and function parameter packs are
2570 // treated like DeclRefExpr cursors.
2571 continue;
2572 }
2573
2574 case VisitorJob::LambdaExprPartsKind: {
2575 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002576 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002577 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2578 CEnd = E->explicit_capture_end();
2579 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002580 // FIXME: Lambda init-captures.
2581 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002582 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002583
Guy Benyei11169dd2012-12-18 14:30:41 +00002584 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2585 C->getLocation(),
2586 TU)))
2587 return true;
2588 }
2589
2590 // Visit parameters and return type, if present.
2591 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2592 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2593 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2594 // Visit the whole type.
2595 if (Visit(TL))
2596 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002597 } else if (FunctionProtoTypeLoc Proto =
2598 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002599 if (E->hasExplicitParameters()) {
2600 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002601 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2602 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002603 return true;
2604 } else {
2605 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002606 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002607 return true;
2608 }
2609 }
2610 }
2611 break;
2612 }
2613
2614 case VisitorJob::PostChildrenVisitKind:
2615 if (PostChildrenVisitor(Parent, ClientData))
2616 return true;
2617 break;
2618 }
2619 }
2620 return false;
2621}
2622
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002623bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002624 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002625 if (!WorkListFreeList.empty()) {
2626 WL = WorkListFreeList.back();
2627 WL->clear();
2628 WorkListFreeList.pop_back();
2629 }
2630 else {
2631 WL = new VisitorWorkList();
2632 WorkListCache.push_back(WL);
2633 }
2634 EnqueueWorkList(*WL, S);
2635 bool result = RunVisitorWorkList(*WL);
2636 WorkListFreeList.push_back(WL);
2637 return result;
2638}
2639
2640namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002641typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002642RefNamePieces
2643buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2644 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2645 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002646 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2647 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2648 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2649
2650 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2651
2652 RefNamePieces Pieces;
2653
2654 if (WantQualifier && QLoc.isValid())
2655 Pieces.push_back(QLoc);
2656
2657 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2658 Pieces.push_back(NI.getLoc());
2659
2660 if (WantTemplateArgs && TemplateArgs)
2661 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2662 TemplateArgs->RAngleLoc));
2663
2664 if (Kind == DeclarationName::CXXOperatorName) {
2665 Pieces.push_back(SourceLocation::getFromRawEncoding(
2666 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2667 Pieces.push_back(SourceLocation::getFromRawEncoding(
2668 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2669 }
2670
2671 if (WantSinglePiece) {
2672 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2673 Pieces.clear();
2674 Pieces.push_back(R);
2675 }
2676
2677 return Pieces;
2678}
2679}
2680
2681//===----------------------------------------------------------------------===//
2682// Misc. API hooks.
2683//===----------------------------------------------------------------------===//
2684
Chad Rosier05c71aa2013-03-27 18:28:23 +00002685static void fatal_error_handler(void *user_data, const std::string& reason,
2686 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002687 // Write the result out to stderr avoiding errs() because raw_ostreams can
2688 // call report_fatal_error.
2689 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2690 ::abort();
2691}
2692
Chandler Carruth66660742014-06-27 16:37:27 +00002693namespace {
2694struct RegisterFatalErrorHandler {
2695 RegisterFatalErrorHandler() {
2696 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2697 }
2698};
2699}
2700
2701static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2702
Guy Benyei11169dd2012-12-18 14:30:41 +00002703extern "C" {
2704CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2705 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 // We use crash recovery to make some of our APIs more reliable, implicitly
2707 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002708 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2709 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002710
Chandler Carruth66660742014-06-27 16:37:27 +00002711 // Look through the managed static to trigger construction of the managed
2712 // static which registers our fatal error handler. This ensures it is only
2713 // registered once.
2714 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002715
2716 CIndexer *CIdxr = new CIndexer();
2717 if (excludeDeclarationsFromPCH)
2718 CIdxr->setOnlyLocalDecls();
2719 if (displayDiagnostics)
2720 CIdxr->setDisplayDiagnostics();
2721
2722 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2723 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2724 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2725 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2726 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2727 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2728
2729 return CIdxr;
2730}
2731
2732void clang_disposeIndex(CXIndex CIdx) {
2733 if (CIdx)
2734 delete static_cast<CIndexer *>(CIdx);
2735}
2736
2737void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2738 if (CIdx)
2739 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2740}
2741
2742unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2743 if (CIdx)
2744 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2745 return 0;
2746}
2747
2748void clang_toggleCrashRecovery(unsigned isEnabled) {
2749 if (isEnabled)
2750 llvm::CrashRecoveryContext::Enable();
2751 else
2752 llvm::CrashRecoveryContext::Disable();
2753}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002754
Guy Benyei11169dd2012-12-18 14:30:41 +00002755CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2756 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002757 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002758 enum CXErrorCode Result =
2759 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002760 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002761 assert((TU && Result == CXError_Success) ||
2762 (!TU && Result != CXError_Success));
2763 return TU;
2764}
2765
2766enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2767 const char *ast_filename,
2768 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002769 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002770 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002771
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002772 if (!CIdx || !ast_filename || !out_TU)
2773 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002774
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002775 LOG_FUNC_SECTION {
2776 *Log << ast_filename;
2777 }
2778
Guy Benyei11169dd2012-12-18 14:30:41 +00002779 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2780 FileSystemOptions FileSystemOpts;
2781
2782 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
David Blaikie6f7382d2014-08-10 19:08:04 +00002783 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2784 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2785 /*CaptureDiagnostics=*/true,
2786 /*AllowPCHWithCompilerErrors=*/true,
2787 /*UserFilesAreVolatile=*/true);
2788 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002789 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002790}
2791
2792unsigned clang_defaultEditingTranslationUnitOptions() {
2793 return CXTranslationUnit_PrecompiledPreamble |
2794 CXTranslationUnit_CacheCompletionResults;
2795}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002796
Guy Benyei11169dd2012-12-18 14:30:41 +00002797CXTranslationUnit
2798clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2799 const char *source_filename,
2800 int num_command_line_args,
2801 const char * const *command_line_args,
2802 unsigned num_unsaved_files,
2803 struct CXUnsavedFile *unsaved_files) {
2804 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2805 return clang_parseTranslationUnit(CIdx, source_filename,
2806 command_line_args, num_command_line_args,
2807 unsaved_files, num_unsaved_files,
2808 Options);
2809}
2810
2811struct ParseTranslationUnitInfo {
2812 CXIndex CIdx;
2813 const char *source_filename;
2814 const char *const *command_line_args;
2815 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002816 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002817 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002818 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002819 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002820};
2821static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002822 const ParseTranslationUnitInfo *PTUI =
2823 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002824 CXIndex CIdx = PTUI->CIdx;
2825 const char *source_filename = PTUI->source_filename;
2826 const char * const *command_line_args = PTUI->command_line_args;
2827 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002828 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002829 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002830
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002831 // Set up the initial return values.
2832 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002833 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002834
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002835 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002836 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002837 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002838 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002839 }
2840
Guy Benyei11169dd2012-12-18 14:30:41 +00002841 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2842
2843 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2844 setThreadBackgroundPriority();
2845
2846 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2847 // FIXME: Add a flag for modules.
2848 TranslationUnitKind TUKind
2849 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002850 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002851 = options & CXTranslationUnit_CacheCompletionResults;
2852 bool IncludeBriefCommentsInCodeCompletion
2853 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2854 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2855 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2856
2857 // Configure the diagnostics.
2858 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002859 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002860
2861 // Recover resources if we crash before exiting this function.
2862 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2863 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002864 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002865
Ahmed Charlesb8984322014-03-07 20:03:18 +00002866 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2867 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002868
2869 // Recover resources if we crash before exiting this function.
2870 llvm::CrashRecoveryContextCleanupRegistrar<
2871 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2872
Alp Toker9d85b182014-07-07 01:23:14 +00002873 for (auto &UF : PTUI->unsaved_files) {
2874 llvm::MemoryBuffer *MB =
2875 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2876 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002877 }
2878
Ahmed Charlesb8984322014-03-07 20:03:18 +00002879 std::unique_ptr<std::vector<const char *>> Args(
2880 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002881
2882 // Recover resources if we crash before exiting this method.
2883 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2884 ArgsCleanup(Args.get());
2885
2886 // Since the Clang C library is primarily used by batch tools dealing with
2887 // (often very broken) source code, where spell-checking can have a
2888 // significant negative impact on performance (particularly when
2889 // precompiled headers are involved), we disable it by default.
2890 // Only do this if we haven't found a spell-checking-related argument.
2891 bool FoundSpellCheckingArgument = false;
2892 for (int I = 0; I != num_command_line_args; ++I) {
2893 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2894 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2895 FoundSpellCheckingArgument = true;
2896 break;
2897 }
2898 }
2899 if (!FoundSpellCheckingArgument)
2900 Args->push_back("-fno-spell-checking");
2901
2902 Args->insert(Args->end(), command_line_args,
2903 command_line_args + num_command_line_args);
2904
2905 // The 'source_filename' argument is optional. If the caller does not
2906 // specify it then it is assumed that the source file is specified
2907 // in the actual argument list.
2908 // Put the source file after command_line_args otherwise if '-x' flag is
2909 // present it will be unused.
2910 if (source_filename)
2911 Args->push_back(source_filename);
2912
2913 // Do we need the detailed preprocessing record?
2914 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2915 Args->push_back("-Xclang");
2916 Args->push_back("-detailed-preprocessing-record");
2917 }
2918
2919 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002920 std::unique_ptr<ASTUnit> ErrUnit;
2921 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002922 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002923 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2924 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2925 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2926 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2927 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2928 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002929
2930 if (NumErrors != Diags->getClient()->getNumErrors()) {
2931 // Make sure to check that 'Unit' is non-NULL.
2932 if (CXXIdx->getDisplayDiagnostics())
2933 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2934 }
2935
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002936 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2937 PTUI->result = CXError_ASTReadError;
2938 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002939 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002940 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2941 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002942}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002943
2944CXTranslationUnit
2945clang_parseTranslationUnit(CXIndex CIdx,
2946 const char *source_filename,
2947 const char *const *command_line_args,
2948 int num_command_line_args,
2949 struct CXUnsavedFile *unsaved_files,
2950 unsigned num_unsaved_files,
2951 unsigned options) {
2952 CXTranslationUnit TU;
2953 enum CXErrorCode Result = clang_parseTranslationUnit2(
2954 CIdx, source_filename, command_line_args, num_command_line_args,
2955 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002956 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002957 assert((TU && Result == CXError_Success) ||
2958 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002959 return TU;
2960}
2961
2962enum CXErrorCode clang_parseTranslationUnit2(
2963 CXIndex CIdx,
2964 const char *source_filename,
2965 const char *const *command_line_args,
2966 int num_command_line_args,
2967 struct CXUnsavedFile *unsaved_files,
2968 unsigned num_unsaved_files,
2969 unsigned options,
2970 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002971 LOG_FUNC_SECTION {
2972 *Log << source_filename << ": ";
2973 for (int i = 0; i != num_command_line_args; ++i)
2974 *Log << command_line_args[i] << " ";
2975 }
2976
Alp Toker9d85b182014-07-07 01:23:14 +00002977 if (num_unsaved_files && !unsaved_files)
2978 return CXError_InvalidArguments;
2979
Alp Toker5c532982014-07-07 22:42:03 +00002980 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002981 ParseTranslationUnitInfo PTUI = {
2982 CIdx,
2983 source_filename,
2984 command_line_args,
2985 num_command_line_args,
2986 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2987 options,
2988 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002989 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002990 llvm::CrashRecoveryContext CRC;
2991
2992 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2993 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2994 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2995 fprintf(stderr, " 'command_line_args' : [");
2996 for (int i = 0; i != num_command_line_args; ++i) {
2997 if (i)
2998 fprintf(stderr, ", ");
2999 fprintf(stderr, "'%s'", command_line_args[i]);
3000 }
3001 fprintf(stderr, "],\n");
3002 fprintf(stderr, " 'unsaved_files' : [");
3003 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3004 if (i)
3005 fprintf(stderr, ", ");
3006 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3007 unsaved_files[i].Length);
3008 }
3009 fprintf(stderr, "],\n");
3010 fprintf(stderr, " 'options' : %d,\n", options);
3011 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003012
3013 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003014 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003015 if (CXTranslationUnit *TU = PTUI.out_TU)
3016 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003017 }
Alp Toker5c532982014-07-07 22:42:03 +00003018
3019 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003020}
3021
3022unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3023 return CXSaveTranslationUnit_None;
3024}
3025
3026namespace {
3027
3028struct SaveTranslationUnitInfo {
3029 CXTranslationUnit TU;
3030 const char *FileName;
3031 unsigned options;
3032 CXSaveError result;
3033};
3034
3035}
3036
3037static void clang_saveTranslationUnit_Impl(void *UserData) {
3038 SaveTranslationUnitInfo *STUI =
3039 static_cast<SaveTranslationUnitInfo*>(UserData);
3040
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003041 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003042 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3043 setThreadBackgroundPriority();
3044
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003045 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003046 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3047}
3048
3049int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3050 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003051 LOG_FUNC_SECTION {
3052 *Log << TU << ' ' << FileName;
3053 }
3054
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003055 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003056 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003057 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003058 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003059
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003060 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003061 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3062 if (!CXXUnit->hasSema())
3063 return CXSaveError_InvalidTU;
3064
3065 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3066
3067 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3068 getenv("LIBCLANG_NOTHREADS")) {
3069 clang_saveTranslationUnit_Impl(&STUI);
3070
3071 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3072 PrintLibclangResourceUsage(TU);
3073
3074 return STUI.result;
3075 }
3076
3077 // We have an AST that has invalid nodes due to compiler errors.
3078 // Use a crash recovery thread for protection.
3079
3080 llvm::CrashRecoveryContext CRC;
3081
3082 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3083 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3084 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3085 fprintf(stderr, " 'options' : %d,\n", options);
3086 fprintf(stderr, "}\n");
3087
3088 return CXSaveError_Unknown;
3089
3090 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3091 PrintLibclangResourceUsage(TU);
3092 }
3093
3094 return STUI.result;
3095}
3096
3097void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3098 if (CTUnit) {
3099 // If the translation unit has been marked as unsafe to free, just discard
3100 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003101 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3102 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 return;
3104
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003105 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003106 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3108 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003109 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003110 delete CTUnit;
3111 }
3112}
3113
3114unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3115 return CXReparse_None;
3116}
3117
3118struct ReparseTranslationUnitInfo {
3119 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003120 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003122 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003123};
3124
3125static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003126 const ReparseTranslationUnitInfo *RTUI =
3127 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003129 unsigned options = RTUI->options;
3130 (void) options;
3131
3132 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003133 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003134 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003135 RTUI->result = CXError_InvalidArguments;
3136 return;
3137 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003138
3139 // Reset the associated diagnostics.
3140 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003141 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003142
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003143 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003144 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3145 setThreadBackgroundPriority();
3146
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003147 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003148 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003149
3150 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3151 new std::vector<ASTUnit::RemappedFile>());
3152
Guy Benyei11169dd2012-12-18 14:30:41 +00003153 // Recover resources if we crash before exiting this function.
3154 llvm::CrashRecoveryContextCleanupRegistrar<
3155 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003156
3157 for (auto &UF : RTUI->unsaved_files) {
3158 llvm::MemoryBuffer *MB =
3159 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3160 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003162
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003163 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003164 RTUI->result = CXError_Success;
3165 else if (isASTReadError(CXXUnit))
3166 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003167}
3168
3169int clang_reparseTranslationUnit(CXTranslationUnit TU,
3170 unsigned num_unsaved_files,
3171 struct CXUnsavedFile *unsaved_files,
3172 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003173 LOG_FUNC_SECTION {
3174 *Log << TU;
3175 }
3176
Alp Toker9d85b182014-07-07 01:23:14 +00003177 if (num_unsaved_files && !unsaved_files)
3178 return CXError_InvalidArguments;
3179
Alp Toker5c532982014-07-07 22:42:03 +00003180 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003181 ReparseTranslationUnitInfo RTUI = {
3182 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003183 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003184
3185 if (getenv("LIBCLANG_NOTHREADS")) {
3186 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003187 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 }
3189
3190 llvm::CrashRecoveryContext CRC;
3191
3192 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3193 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003194 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003195 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3197 PrintLibclangResourceUsage(TU);
3198
Alp Toker5c532982014-07-07 22:42:03 +00003199 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003200}
3201
3202
3203CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003204 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003205 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003206 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003207 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003208
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003209 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003210 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003211}
3212
3213CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003214 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003215 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003216 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003217 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003218
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003219 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3221}
3222
3223} // end: extern "C"
3224
3225//===----------------------------------------------------------------------===//
3226// CXFile Operations.
3227//===----------------------------------------------------------------------===//
3228
3229extern "C" {
3230CXString clang_getFileName(CXFile SFile) {
3231 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003232 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003233
3234 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003235 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003236}
3237
3238time_t clang_getFileTime(CXFile SFile) {
3239 if (!SFile)
3240 return 0;
3241
3242 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3243 return FEnt->getModificationTime();
3244}
3245
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003246CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003247 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003248 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003249 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003250 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003251
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003252 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003253
3254 FileManager &FMgr = CXXUnit->getFileManager();
3255 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3256}
3257
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003258unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3259 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003260 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003261 LOG_BAD_TU(TU);
3262 return 0;
3263 }
3264
3265 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 return 0;
3267
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003268 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 FileEntry *FEnt = static_cast<FileEntry *>(file);
3270 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3271 .isFileMultipleIncludeGuarded(FEnt);
3272}
3273
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003274int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3275 if (!file || !outID)
3276 return 1;
3277
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003278 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003279 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3280 outID->data[0] = ID.getDevice();
3281 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003282 outID->data[2] = FEnt->getModificationTime();
3283 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003284}
3285
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003286int clang_File_isEqual(CXFile file1, CXFile file2) {
3287 if (file1 == file2)
3288 return true;
3289
3290 if (!file1 || !file2)
3291 return false;
3292
3293 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3294 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3295 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3296}
3297
Guy Benyei11169dd2012-12-18 14:30:41 +00003298} // end: extern "C"
3299
3300//===----------------------------------------------------------------------===//
3301// CXCursor Operations.
3302//===----------------------------------------------------------------------===//
3303
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003304static const Decl *getDeclFromExpr(const Stmt *E) {
3305 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 return getDeclFromExpr(CE->getSubExpr());
3307
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003308 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003310 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003312 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003314 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 if (PRE->isExplicitProperty())
3316 return PRE->getExplicitProperty();
3317 // It could be messaging both getter and setter as in:
3318 // ++myobj.myprop;
3319 // in which case prefer to associate the setter since it is less obvious
3320 // from inspecting the source that the setter is going to get called.
3321 if (PRE->isMessagingSetter())
3322 return PRE->getImplicitPropertySetter();
3323 return PRE->getImplicitPropertyGetter();
3324 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003325 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003327 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 if (Expr *Src = OVE->getSourceExpr())
3329 return getDeclFromExpr(Src);
3330
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003331 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003333 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 if (!CE->isElidable())
3335 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003336 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 return OME->getMethodDecl();
3338
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003339 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003341 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3343 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003344 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3346 isa<ParmVarDecl>(SizeOfPack->getPack()))
3347 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003348
3349 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003350}
3351
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003352static SourceLocation getLocationFromExpr(const Expr *E) {
3353 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 return getLocationFromExpr(CE->getSubExpr());
3355
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003356 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003358 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003360 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003362 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003364 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003366 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 return PropRef->getLocation();
3368
3369 return E->getLocStart();
3370}
3371
3372extern "C" {
3373
3374unsigned clang_visitChildren(CXCursor parent,
3375 CXCursorVisitor visitor,
3376 CXClientData client_data) {
3377 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3378 /*VisitPreprocessorLast=*/false);
3379 return CursorVis.VisitChildren(parent);
3380}
3381
3382#ifndef __has_feature
3383#define __has_feature(x) 0
3384#endif
3385#if __has_feature(blocks)
3386typedef enum CXChildVisitResult
3387 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3388
3389static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3390 CXClientData client_data) {
3391 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3392 return block(cursor, parent);
3393}
3394#else
3395// If we are compiled with a compiler that doesn't have native blocks support,
3396// define and call the block manually, so the
3397typedef struct _CXChildVisitResult
3398{
3399 void *isa;
3400 int flags;
3401 int reserved;
3402 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3403 CXCursor);
3404} *CXCursorVisitorBlock;
3405
3406static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3407 CXClientData client_data) {
3408 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3409 return block->invoke(block, cursor, parent);
3410}
3411#endif
3412
3413
3414unsigned clang_visitChildrenWithBlock(CXCursor parent,
3415 CXCursorVisitorBlock block) {
3416 return clang_visitChildren(parent, visitWithBlock, block);
3417}
3418
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003419static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003421 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003423 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003425 if (const ObjCPropertyImplDecl *PropImpl =
3426 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003428 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003429
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003430 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003432 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003433
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003434 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 }
3436
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003437 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003438 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003439
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003440 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3442 // and returns different names. NamedDecl returns the class name and
3443 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003444 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003445
3446 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003447 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003448
3449 SmallString<1024> S;
3450 llvm::raw_svector_ostream os(S);
3451 ND->printName(os);
3452
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003453 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003454}
3455
3456CXString clang_getCursorSpelling(CXCursor C) {
3457 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003458 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003459
3460 if (clang_isReference(C.kind)) {
3461 switch (C.kind) {
3462 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003463 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003464 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 }
3466 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003467 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003468 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 }
3470 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003471 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003473 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 }
3475 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003476 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003477 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 }
3479 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003480 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 assert(Type && "Missing type decl");
3482
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003483 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 getAsString());
3485 }
3486 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003487 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 assert(Template && "Missing template decl");
3489
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003490 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 }
3492
3493 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003494 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 assert(NS && "Missing namespace decl");
3496
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003497 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 }
3499
3500 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003501 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 assert(Field && "Missing member decl");
3503
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003504 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 }
3506
3507 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003508 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 assert(Label && "Missing label");
3510
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003511 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 }
3513
3514 case CXCursor_OverloadedDeclRef: {
3515 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003516 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3517 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003518 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003519 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003521 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003522 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 OverloadedTemplateStorage *Ovl
3524 = Storage.get<OverloadedTemplateStorage*>();
3525 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003526 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003527 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 }
3529
3530 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003531 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 assert(Var && "Missing variable decl");
3533
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003534 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 }
3536
3537 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003538 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 }
3540 }
3541
3542 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003543 const Expr *E = getCursorExpr(C);
3544
3545 if (C.kind == CXCursor_ObjCStringLiteral ||
3546 C.kind == CXCursor_StringLiteral) {
3547 const StringLiteral *SLit;
3548 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3549 SLit = OSL->getString();
3550 } else {
3551 SLit = cast<StringLiteral>(E);
3552 }
3553 SmallString<256> Buf;
3554 llvm::raw_svector_ostream OS(Buf);
3555 SLit->outputString(OS);
3556 return cxstring::createDup(OS.str());
3557 }
3558
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003559 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 if (D)
3561 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003562 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 }
3564
3565 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003566 const Stmt *S = getCursorStmt(C);
3567 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003568 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003569
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003570 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 }
3572
3573 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003574 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 ->getNameStart());
3576
3577 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003578 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 ->getNameStart());
3580
3581 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003582 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003583
3584 if (clang_isDeclaration(C.kind))
3585 return getDeclSpelling(getCursorDecl(C));
3586
3587 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003588 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003589 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 }
3591
3592 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003593 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003594 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 }
3596
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003597 if (C.kind == CXCursor_PackedAttr) {
3598 return cxstring::createRef("packed");
3599 }
3600
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003601 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003602}
3603
3604CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3605 unsigned pieceIndex,
3606 unsigned options) {
3607 if (clang_Cursor_isNull(C))
3608 return clang_getNullRange();
3609
3610 ASTContext &Ctx = getCursorContext(C);
3611
3612 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003613 const Stmt *S = getCursorStmt(C);
3614 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 if (pieceIndex > 0)
3616 return clang_getNullRange();
3617 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3618 }
3619
3620 return clang_getNullRange();
3621 }
3622
3623 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003624 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3626 if (pieceIndex >= ME->getNumSelectorLocs())
3627 return clang_getNullRange();
3628 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3629 }
3630 }
3631
3632 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3633 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003634 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3636 if (pieceIndex >= MD->getNumSelectorLocs())
3637 return clang_getNullRange();
3638 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3639 }
3640 }
3641
3642 if (C.kind == CXCursor_ObjCCategoryDecl ||
3643 C.kind == CXCursor_ObjCCategoryImplDecl) {
3644 if (pieceIndex > 0)
3645 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003646 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3648 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003649 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3651 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3652 }
3653
3654 if (C.kind == CXCursor_ModuleImportDecl) {
3655 if (pieceIndex > 0)
3656 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003657 if (const ImportDecl *ImportD =
3658 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3660 if (!Locs.empty())
3661 return cxloc::translateSourceRange(Ctx,
3662 SourceRange(Locs.front(), Locs.back()));
3663 }
3664 return clang_getNullRange();
3665 }
3666
3667 // FIXME: A CXCursor_InclusionDirective should give the location of the
3668 // filename, but we don't keep track of this.
3669
3670 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3671 // but we don't keep track of this.
3672
3673 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3674 // but we don't keep track of this.
3675
3676 // Default handling, give the location of the cursor.
3677
3678 if (pieceIndex > 0)
3679 return clang_getNullRange();
3680
3681 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3682 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3683 return cxloc::translateSourceRange(Ctx, Loc);
3684}
3685
Eli Bendersky44a206f2014-07-31 18:04:56 +00003686CXString clang_Cursor_getMangling(CXCursor C) {
3687 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3688 return cxstring::createEmpty();
3689
Eli Bendersky44a206f2014-07-31 18:04:56 +00003690 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003691 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003692 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3693 return cxstring::createEmpty();
3694
Eli Bendersky79759592014-08-01 15:01:10 +00003695 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003696 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003697 ASTContext &Ctx = ND->getASTContext();
3698 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003699
Eli Bendersky79759592014-08-01 15:01:10 +00003700 std::string FrontendBuf;
3701 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3702 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003703
Eli Bendersky79759592014-08-01 15:01:10 +00003704 // Now apply backend mangling.
3705 std::unique_ptr<llvm::DataLayout> DL(
3706 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3707 llvm::Mangler BackendMangler(DL.get());
3708
3709 std::string FinalBuf;
3710 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3711 BackendMangler.getNameWithPrefix(FinalBufOS,
3712 llvm::Twine(FrontendBufOS.str()));
3713
3714 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003715}
3716
Guy Benyei11169dd2012-12-18 14:30:41 +00003717CXString clang_getCursorDisplayName(CXCursor C) {
3718 if (!clang_isDeclaration(C.kind))
3719 return clang_getCursorSpelling(C);
3720
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003721 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003723 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003724
3725 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003726 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 D = FunTmpl->getTemplatedDecl();
3728
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003729 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 SmallString<64> Str;
3731 llvm::raw_svector_ostream OS(Str);
3732 OS << *Function;
3733 if (Function->getPrimaryTemplate())
3734 OS << "<>";
3735 OS << "(";
3736 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3737 if (I)
3738 OS << ", ";
3739 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3740 }
3741
3742 if (Function->isVariadic()) {
3743 if (Function->getNumParams())
3744 OS << ", ";
3745 OS << "...";
3746 }
3747 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003748 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 }
3750
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003751 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 SmallString<64> Str;
3753 llvm::raw_svector_ostream OS(Str);
3754 OS << *ClassTemplate;
3755 OS << "<";
3756 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3757 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3758 if (I)
3759 OS << ", ";
3760
3761 NamedDecl *Param = Params->getParam(I);
3762 if (Param->getIdentifier()) {
3763 OS << Param->getIdentifier()->getName();
3764 continue;
3765 }
3766
3767 // There is no parameter name, which makes this tricky. Try to come up
3768 // with something useful that isn't too long.
3769 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3770 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3771 else if (NonTypeTemplateParmDecl *NTTP
3772 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3773 OS << NTTP->getType().getAsString(Policy);
3774 else
3775 OS << "template<...> class";
3776 }
3777
3778 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003779 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 }
3781
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003782 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3784 // If the type was explicitly written, use that.
3785 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003786 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003787
Benjamin Kramer9170e912013-02-22 15:46:01 +00003788 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 llvm::raw_svector_ostream OS(Str);
3790 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003791 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 ClassSpec->getTemplateArgs().data(),
3793 ClassSpec->getTemplateArgs().size(),
3794 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003795 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 }
3797
3798 return clang_getCursorSpelling(C);
3799}
3800
3801CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3802 switch (Kind) {
3803 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003931 case CXCursor_ObjCSelfExpr:
3932 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004021 case CXCursor_SEHLeaveStmt:
4022 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004051 case CXCursor_PackedAttr:
4052 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004053 case CXCursor_PureAttr:
4054 return cxstring::createRef("attribute(pure)");
4055 case CXCursor_ConstAttr:
4056 return cxstring::createRef("attribute(const)");
4057 case CXCursor_NoDuplicateAttr:
4058 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004059 case CXCursor_CUDAConstantAttr:
4060 return cxstring::createRef("attribute(constant)");
4061 case CXCursor_CUDADeviceAttr:
4062 return cxstring::createRef("attribute(device)");
4063 case CXCursor_CUDAGlobalAttr:
4064 return cxstring::createRef("attribute(global)");
4065 case CXCursor_CUDAHostAttr:
4066 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004067 case CXCursor_CUDASharedAttr:
4068 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004117 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004118 return cxstring::createRef("OMPParallelDirective");
4119 case CXCursor_OMPSimdDirective:
4120 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004121 case CXCursor_OMPForDirective:
4122 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004123 case CXCursor_OMPSectionsDirective:
4124 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004125 case CXCursor_OMPSectionDirective:
4126 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004127 case CXCursor_OMPSingleDirective:
4128 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004129 case CXCursor_OMPMasterDirective:
4130 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004131 case CXCursor_OMPCriticalDirective:
4132 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004133 case CXCursor_OMPParallelForDirective:
4134 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004135 case CXCursor_OMPParallelSectionsDirective:
4136 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004137 case CXCursor_OMPTaskDirective:
4138 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004139 case CXCursor_OMPTaskyieldDirective:
4140 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004141 case CXCursor_OMPBarrierDirective:
4142 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004143 case CXCursor_OMPTaskwaitDirective:
4144 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004145 case CXCursor_OMPFlushDirective:
4146 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004147 case CXCursor_OMPOrderedDirective:
4148 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004149 case CXCursor_OMPAtomicDirective:
4150 return cxstring::createRef("OMPAtomicDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 }
4152
4153 llvm_unreachable("Unhandled CXCursorKind");
4154}
4155
4156struct GetCursorData {
4157 SourceLocation TokenBeginLoc;
4158 bool PointsAtMacroArgExpansion;
4159 bool VisitedObjCPropertyImplDecl;
4160 SourceLocation VisitedDeclaratorDeclStartLoc;
4161 CXCursor &BestCursor;
4162
4163 GetCursorData(SourceManager &SM,
4164 SourceLocation tokenBegin, CXCursor &outputCursor)
4165 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4166 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4167 VisitedObjCPropertyImplDecl = false;
4168 }
4169};
4170
4171static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4172 CXCursor parent,
4173 CXClientData client_data) {
4174 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4175 CXCursor *BestCursor = &Data->BestCursor;
4176
4177 // If we point inside a macro argument we should provide info of what the
4178 // token is so use the actual cursor, don't replace it with a macro expansion
4179 // cursor.
4180 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4181 return CXChildVisit_Recurse;
4182
4183 if (clang_isDeclaration(cursor.kind)) {
4184 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004185 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4187 if (MD->isImplicit())
4188 return CXChildVisit_Break;
4189
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004190 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4192 // Check that when we have multiple @class references in the same line,
4193 // that later ones do not override the previous ones.
4194 // If we have:
4195 // @class Foo, Bar;
4196 // source ranges for both start at '@', so 'Bar' will end up overriding
4197 // 'Foo' even though the cursor location was at 'Foo'.
4198 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4199 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004200 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4202 if (PrevID != ID &&
4203 !PrevID->isThisDeclarationADefinition() &&
4204 !ID->isThisDeclarationADefinition())
4205 return CXChildVisit_Break;
4206 }
4207
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004208 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4210 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4211 // Check that when we have multiple declarators in the same line,
4212 // that later ones do not override the previous ones.
4213 // If we have:
4214 // int Foo, Bar;
4215 // source ranges for both start at 'int', so 'Bar' will end up overriding
4216 // 'Foo' even though the cursor location was at 'Foo'.
4217 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4218 return CXChildVisit_Break;
4219 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4220
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004221 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4223 (void)PropImp;
4224 // Check that when we have multiple @synthesize in the same line,
4225 // that later ones do not override the previous ones.
4226 // If we have:
4227 // @synthesize Foo, Bar;
4228 // source ranges for both start at '@', so 'Bar' will end up overriding
4229 // 'Foo' even though the cursor location was at 'Foo'.
4230 if (Data->VisitedObjCPropertyImplDecl)
4231 return CXChildVisit_Break;
4232 Data->VisitedObjCPropertyImplDecl = true;
4233 }
4234 }
4235
4236 if (clang_isExpression(cursor.kind) &&
4237 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004238 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 // Avoid having the cursor of an expression replace the declaration cursor
4240 // when the expression source range overlaps the declaration range.
4241 // This can happen for C++ constructor expressions whose range generally
4242 // include the variable declaration, e.g.:
4243 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4244 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4245 D->getLocation() == Data->TokenBeginLoc)
4246 return CXChildVisit_Break;
4247 }
4248 }
4249
4250 // If our current best cursor is the construction of a temporary object,
4251 // don't replace that cursor with a type reference, because we want
4252 // clang_getCursor() to point at the constructor.
4253 if (clang_isExpression(BestCursor->kind) &&
4254 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4255 cursor.kind == CXCursor_TypeRef) {
4256 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4257 // as having the actual point on the type reference.
4258 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4259 return CXChildVisit_Recurse;
4260 }
4261
4262 *BestCursor = cursor;
4263 return CXChildVisit_Recurse;
4264}
4265
4266CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004267 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004268 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004270 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004271
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004272 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4274
4275 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4276 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4277
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004278 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 CXFile SearchFile;
4280 unsigned SearchLine, SearchColumn;
4281 CXFile ResultFile;
4282 unsigned ResultLine, ResultColumn;
4283 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4284 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4285 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004286
4287 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4288 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004289 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004290 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 SearchFileName = clang_getFileName(SearchFile);
4292 ResultFileName = clang_getFileName(ResultFile);
4293 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4294 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004295 *Log << llvm::format("(%s:%d:%d) = %s",
4296 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4297 clang_getCString(KindSpelling))
4298 << llvm::format("(%s:%d:%d):%s%s",
4299 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4300 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 clang_disposeString(SearchFileName);
4302 clang_disposeString(ResultFileName);
4303 clang_disposeString(KindSpelling);
4304 clang_disposeString(USR);
4305
4306 CXCursor Definition = clang_getCursorDefinition(Result);
4307 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4308 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4309 CXString DefinitionKindSpelling
4310 = clang_getCursorKindSpelling(Definition.kind);
4311 CXFile DefinitionFile;
4312 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004313 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004314 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004316 *Log << llvm::format(" -> %s(%s:%d:%d)",
4317 clang_getCString(DefinitionKindSpelling),
4318 clang_getCString(DefinitionFileName),
4319 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 clang_disposeString(DefinitionFileName);
4321 clang_disposeString(DefinitionKindSpelling);
4322 }
4323 }
4324
4325 return Result;
4326}
4327
4328CXCursor clang_getNullCursor(void) {
4329 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4330}
4331
4332unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004333 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4334 // can't set consistently. For example, when visiting a DeclStmt we will set
4335 // it but we don't set it on the result of clang_getCursorDefinition for
4336 // a reference of the same declaration.
4337 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4338 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4339 // to provide that kind of info.
4340 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004341 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004342 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004343 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004344
Guy Benyei11169dd2012-12-18 14:30:41 +00004345 return X == Y;
4346}
4347
4348unsigned clang_hashCursor(CXCursor C) {
4349 unsigned Index = 0;
4350 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4351 Index = 1;
4352
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004353 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 std::make_pair(C.kind, C.data[Index]));
4355}
4356
4357unsigned clang_isInvalid(enum CXCursorKind K) {
4358 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4359}
4360
4361unsigned clang_isDeclaration(enum CXCursorKind K) {
4362 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4363 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4364}
4365
4366unsigned clang_isReference(enum CXCursorKind K) {
4367 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4368}
4369
4370unsigned clang_isExpression(enum CXCursorKind K) {
4371 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4372}
4373
4374unsigned clang_isStatement(enum CXCursorKind K) {
4375 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4376}
4377
4378unsigned clang_isAttribute(enum CXCursorKind K) {
4379 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4380}
4381
4382unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4383 return K == CXCursor_TranslationUnit;
4384}
4385
4386unsigned clang_isPreprocessing(enum CXCursorKind K) {
4387 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4388}
4389
4390unsigned clang_isUnexposed(enum CXCursorKind K) {
4391 switch (K) {
4392 case CXCursor_UnexposedDecl:
4393 case CXCursor_UnexposedExpr:
4394 case CXCursor_UnexposedStmt:
4395 case CXCursor_UnexposedAttr:
4396 return true;
4397 default:
4398 return false;
4399 }
4400}
4401
4402CXCursorKind clang_getCursorKind(CXCursor C) {
4403 return C.kind;
4404}
4405
4406CXSourceLocation clang_getCursorLocation(CXCursor C) {
4407 if (clang_isReference(C.kind)) {
4408 switch (C.kind) {
4409 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004410 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004411 = getCursorObjCSuperClassRef(C);
4412 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4413 }
4414
4415 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004416 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004417 = getCursorObjCProtocolRef(C);
4418 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4419 }
4420
4421 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004422 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004423 = getCursorObjCClassRef(C);
4424 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4425 }
4426
4427 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004428 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004429 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4430 }
4431
4432 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004433 std::pair<const TemplateDecl *, SourceLocation> P =
4434 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4436 }
4437
4438 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004439 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4441 }
4442
4443 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004444 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004445 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4446 }
4447
4448 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004449 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004450 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4451 }
4452
4453 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004454 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 if (!BaseSpec)
4456 return clang_getNullLocation();
4457
4458 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4459 return cxloc::translateSourceLocation(getCursorContext(C),
4460 TSInfo->getTypeLoc().getBeginLoc());
4461
4462 return cxloc::translateSourceLocation(getCursorContext(C),
4463 BaseSpec->getLocStart());
4464 }
4465
4466 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004467 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4469 }
4470
4471 case CXCursor_OverloadedDeclRef:
4472 return cxloc::translateSourceLocation(getCursorContext(C),
4473 getCursorOverloadedDeclRef(C).second);
4474
4475 default:
4476 // FIXME: Need a way to enumerate all non-reference cases.
4477 llvm_unreachable("Missed a reference kind");
4478 }
4479 }
4480
4481 if (clang_isExpression(C.kind))
4482 return cxloc::translateSourceLocation(getCursorContext(C),
4483 getLocationFromExpr(getCursorExpr(C)));
4484
4485 if (clang_isStatement(C.kind))
4486 return cxloc::translateSourceLocation(getCursorContext(C),
4487 getCursorStmt(C)->getLocStart());
4488
4489 if (C.kind == CXCursor_PreprocessingDirective) {
4490 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4491 return cxloc::translateSourceLocation(getCursorContext(C), L);
4492 }
4493
4494 if (C.kind == CXCursor_MacroExpansion) {
4495 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004496 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 return cxloc::translateSourceLocation(getCursorContext(C), L);
4498 }
4499
4500 if (C.kind == CXCursor_MacroDefinition) {
4501 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4502 return cxloc::translateSourceLocation(getCursorContext(C), L);
4503 }
4504
4505 if (C.kind == CXCursor_InclusionDirective) {
4506 SourceLocation L
4507 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4508 return cxloc::translateSourceLocation(getCursorContext(C), L);
4509 }
4510
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004511 if (clang_isAttribute(C.kind)) {
4512 SourceLocation L
4513 = cxcursor::getCursorAttr(C)->getLocation();
4514 return cxloc::translateSourceLocation(getCursorContext(C), L);
4515 }
4516
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 if (!clang_isDeclaration(C.kind))
4518 return clang_getNullLocation();
4519
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004520 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 if (!D)
4522 return clang_getNullLocation();
4523
4524 SourceLocation Loc = D->getLocation();
4525 // FIXME: Multiple variables declared in a single declaration
4526 // currently lack the information needed to correctly determine their
4527 // ranges when accounting for the type-specifier. We use context
4528 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4529 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004530 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 if (!cxcursor::isFirstInDeclGroup(C))
4532 Loc = VD->getLocation();
4533 }
4534
4535 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004536 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 Loc = MD->getSelectorStartLoc();
4538
4539 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4540}
4541
4542} // end extern "C"
4543
4544CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4545 assert(TU);
4546
4547 // Guard against an invalid SourceLocation, or we may assert in one
4548 // of the following calls.
4549 if (SLoc.isInvalid())
4550 return clang_getNullCursor();
4551
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004552 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004553
4554 // Translate the given source location to make it point at the beginning of
4555 // the token under the cursor.
4556 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4557 CXXUnit->getASTContext().getLangOpts());
4558
4559 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4560 if (SLoc.isValid()) {
4561 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4562 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4563 /*VisitPreprocessorLast=*/true,
4564 /*VisitIncludedEntities=*/false,
4565 SourceLocation(SLoc));
4566 CursorVis.visitFileRegion();
4567 }
4568
4569 return Result;
4570}
4571
4572static SourceRange getRawCursorExtent(CXCursor C) {
4573 if (clang_isReference(C.kind)) {
4574 switch (C.kind) {
4575 case CXCursor_ObjCSuperClassRef:
4576 return getCursorObjCSuperClassRef(C).second;
4577
4578 case CXCursor_ObjCProtocolRef:
4579 return getCursorObjCProtocolRef(C).second;
4580
4581 case CXCursor_ObjCClassRef:
4582 return getCursorObjCClassRef(C).second;
4583
4584 case CXCursor_TypeRef:
4585 return getCursorTypeRef(C).second;
4586
4587 case CXCursor_TemplateRef:
4588 return getCursorTemplateRef(C).second;
4589
4590 case CXCursor_NamespaceRef:
4591 return getCursorNamespaceRef(C).second;
4592
4593 case CXCursor_MemberRef:
4594 return getCursorMemberRef(C).second;
4595
4596 case CXCursor_CXXBaseSpecifier:
4597 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4598
4599 case CXCursor_LabelRef:
4600 return getCursorLabelRef(C).second;
4601
4602 case CXCursor_OverloadedDeclRef:
4603 return getCursorOverloadedDeclRef(C).second;
4604
4605 case CXCursor_VariableRef:
4606 return getCursorVariableRef(C).second;
4607
4608 default:
4609 // FIXME: Need a way to enumerate all non-reference cases.
4610 llvm_unreachable("Missed a reference kind");
4611 }
4612 }
4613
4614 if (clang_isExpression(C.kind))
4615 return getCursorExpr(C)->getSourceRange();
4616
4617 if (clang_isStatement(C.kind))
4618 return getCursorStmt(C)->getSourceRange();
4619
4620 if (clang_isAttribute(C.kind))
4621 return getCursorAttr(C)->getRange();
4622
4623 if (C.kind == CXCursor_PreprocessingDirective)
4624 return cxcursor::getCursorPreprocessingDirective(C);
4625
4626 if (C.kind == CXCursor_MacroExpansion) {
4627 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004628 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 return TU->mapRangeFromPreamble(Range);
4630 }
4631
4632 if (C.kind == CXCursor_MacroDefinition) {
4633 ASTUnit *TU = getCursorASTUnit(C);
4634 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4635 return TU->mapRangeFromPreamble(Range);
4636 }
4637
4638 if (C.kind == CXCursor_InclusionDirective) {
4639 ASTUnit *TU = getCursorASTUnit(C);
4640 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4641 return TU->mapRangeFromPreamble(Range);
4642 }
4643
4644 if (C.kind == CXCursor_TranslationUnit) {
4645 ASTUnit *TU = getCursorASTUnit(C);
4646 FileID MainID = TU->getSourceManager().getMainFileID();
4647 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4648 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4649 return SourceRange(Start, End);
4650 }
4651
4652 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004653 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 if (!D)
4655 return SourceRange();
4656
4657 SourceRange R = D->getSourceRange();
4658 // FIXME: Multiple variables declared in a single declaration
4659 // currently lack the information needed to correctly determine their
4660 // ranges when accounting for the type-specifier. We use context
4661 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4662 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004663 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 if (!cxcursor::isFirstInDeclGroup(C))
4665 R.setBegin(VD->getLocation());
4666 }
4667 return R;
4668 }
4669 return SourceRange();
4670}
4671
4672/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4673/// the decl-specifier-seq for declarations.
4674static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4675 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004676 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 if (!D)
4678 return SourceRange();
4679
4680 SourceRange R = D->getSourceRange();
4681
4682 // Adjust the start of the location for declarations preceded by
4683 // declaration specifiers.
4684 SourceLocation StartLoc;
4685 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4686 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4687 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004688 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4690 StartLoc = TI->getTypeLoc().getLocStart();
4691 }
4692
4693 if (StartLoc.isValid() && R.getBegin().isValid() &&
4694 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4695 R.setBegin(StartLoc);
4696
4697 // FIXME: Multiple variables declared in a single declaration
4698 // currently lack the information needed to correctly determine their
4699 // ranges when accounting for the type-specifier. We use context
4700 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4701 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004702 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 if (!cxcursor::isFirstInDeclGroup(C))
4704 R.setBegin(VD->getLocation());
4705 }
4706
4707 return R;
4708 }
4709
4710 return getRawCursorExtent(C);
4711}
4712
4713extern "C" {
4714
4715CXSourceRange clang_getCursorExtent(CXCursor C) {
4716 SourceRange R = getRawCursorExtent(C);
4717 if (R.isInvalid())
4718 return clang_getNullRange();
4719
4720 return cxloc::translateSourceRange(getCursorContext(C), R);
4721}
4722
4723CXCursor clang_getCursorReferenced(CXCursor C) {
4724 if (clang_isInvalid(C.kind))
4725 return clang_getNullCursor();
4726
4727 CXTranslationUnit tu = getCursorTU(C);
4728 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004729 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 if (!D)
4731 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004732 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004734 if (const ObjCPropertyImplDecl *PropImpl =
4735 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4737 return MakeCXCursor(Property, tu);
4738
4739 return C;
4740 }
4741
4742 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004743 const Expr *E = getCursorExpr(C);
4744 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 if (D) {
4746 CXCursor declCursor = MakeCXCursor(D, tu);
4747 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4748 declCursor);
4749 return declCursor;
4750 }
4751
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004752 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 return MakeCursorOverloadedDeclRef(Ovl, tu);
4754
4755 return clang_getNullCursor();
4756 }
4757
4758 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004759 const Stmt *S = getCursorStmt(C);
4760 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 if (LabelDecl *label = Goto->getLabel())
4762 if (LabelStmt *labelS = label->getStmt())
4763 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4764
4765 return clang_getNullCursor();
4766 }
4767
4768 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004769 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 return MakeMacroDefinitionCursor(Def, tu);
4771 }
4772
4773 if (!clang_isReference(C.kind))
4774 return clang_getNullCursor();
4775
4776 switch (C.kind) {
4777 case CXCursor_ObjCSuperClassRef:
4778 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4779
4780 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004781 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4782 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 return MakeCXCursor(Def, tu);
4784
4785 return MakeCXCursor(Prot, tu);
4786 }
4787
4788 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004789 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4790 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 return MakeCXCursor(Def, tu);
4792
4793 return MakeCXCursor(Class, tu);
4794 }
4795
4796 case CXCursor_TypeRef:
4797 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4798
4799 case CXCursor_TemplateRef:
4800 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4801
4802 case CXCursor_NamespaceRef:
4803 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4804
4805 case CXCursor_MemberRef:
4806 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4807
4808 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004809 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004810 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4811 tu ));
4812 }
4813
4814 case CXCursor_LabelRef:
4815 // FIXME: We end up faking the "parent" declaration here because we
4816 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004817 return MakeCXCursor(getCursorLabelRef(C).first,
4818 cxtu::getASTUnit(tu)->getASTContext()
4819 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004820 tu);
4821
4822 case CXCursor_OverloadedDeclRef:
4823 return C;
4824
4825 case CXCursor_VariableRef:
4826 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4827
4828 default:
4829 // We would prefer to enumerate all non-reference cursor kinds here.
4830 llvm_unreachable("Unhandled reference cursor kind");
4831 }
4832}
4833
4834CXCursor clang_getCursorDefinition(CXCursor C) {
4835 if (clang_isInvalid(C.kind))
4836 return clang_getNullCursor();
4837
4838 CXTranslationUnit TU = getCursorTU(C);
4839
4840 bool WasReference = false;
4841 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4842 C = clang_getCursorReferenced(C);
4843 WasReference = true;
4844 }
4845
4846 if (C.kind == CXCursor_MacroExpansion)
4847 return clang_getCursorReferenced(C);
4848
4849 if (!clang_isDeclaration(C.kind))
4850 return clang_getNullCursor();
4851
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004852 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 if (!D)
4854 return clang_getNullCursor();
4855
4856 switch (D->getKind()) {
4857 // Declaration kinds that don't really separate the notions of
4858 // declaration and definition.
4859 case Decl::Namespace:
4860 case Decl::Typedef:
4861 case Decl::TypeAlias:
4862 case Decl::TypeAliasTemplate:
4863 case Decl::TemplateTypeParm:
4864 case Decl::EnumConstant:
4865 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004866 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004867 case Decl::IndirectField:
4868 case Decl::ObjCIvar:
4869 case Decl::ObjCAtDefsField:
4870 case Decl::ImplicitParam:
4871 case Decl::ParmVar:
4872 case Decl::NonTypeTemplateParm:
4873 case Decl::TemplateTemplateParm:
4874 case Decl::ObjCCategoryImpl:
4875 case Decl::ObjCImplementation:
4876 case Decl::AccessSpec:
4877 case Decl::LinkageSpec:
4878 case Decl::ObjCPropertyImpl:
4879 case Decl::FileScopeAsm:
4880 case Decl::StaticAssert:
4881 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004882 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004883 case Decl::Label: // FIXME: Is this right??
4884 case Decl::ClassScopeFunctionSpecialization:
4885 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004886 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 return C;
4888
4889 // Declaration kinds that don't make any sense here, but are
4890 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004891 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004892 case Decl::TranslationUnit:
4893 break;
4894
4895 // Declaration kinds for which the definition is not resolvable.
4896 case Decl::UnresolvedUsingTypename:
4897 case Decl::UnresolvedUsingValue:
4898 break;
4899
4900 case Decl::UsingDirective:
4901 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4902 TU);
4903
4904 case Decl::NamespaceAlias:
4905 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4906
4907 case Decl::Enum:
4908 case Decl::Record:
4909 case Decl::CXXRecord:
4910 case Decl::ClassTemplateSpecialization:
4911 case Decl::ClassTemplatePartialSpecialization:
4912 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4913 return MakeCXCursor(Def, TU);
4914 return clang_getNullCursor();
4915
4916 case Decl::Function:
4917 case Decl::CXXMethod:
4918 case Decl::CXXConstructor:
4919 case Decl::CXXDestructor:
4920 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004921 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004922 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004923 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 return clang_getNullCursor();
4925 }
4926
Larisse Voufo39a1e502013-08-06 01:03:05 +00004927 case Decl::Var:
4928 case Decl::VarTemplateSpecialization:
4929 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004930 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004931 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004932 return MakeCXCursor(Def, TU);
4933 return clang_getNullCursor();
4934 }
4935
4936 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004937 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004938 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4939 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4940 return clang_getNullCursor();
4941 }
4942
4943 case Decl::ClassTemplate: {
4944 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4945 ->getDefinition())
4946 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4947 TU);
4948 return clang_getNullCursor();
4949 }
4950
Larisse Voufo39a1e502013-08-06 01:03:05 +00004951 case Decl::VarTemplate: {
4952 if (VarDecl *Def =
4953 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4954 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4955 return clang_getNullCursor();
4956 }
4957
Guy Benyei11169dd2012-12-18 14:30:41 +00004958 case Decl::Using:
4959 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4960 D->getLocation(), TU);
4961
4962 case Decl::UsingShadow:
4963 return clang_getCursorDefinition(
4964 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4965 TU));
4966
4967 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004968 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004969 if (Method->isThisDeclarationADefinition())
4970 return C;
4971
4972 // Dig out the method definition in the associated
4973 // @implementation, if we have it.
4974 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004975 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004976 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4977 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4978 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4979 Method->isInstanceMethod()))
4980 if (Def->isThisDeclarationADefinition())
4981 return MakeCXCursor(Def, TU);
4982
4983 return clang_getNullCursor();
4984 }
4985
4986 case Decl::ObjCCategory:
4987 if (ObjCCategoryImplDecl *Impl
4988 = cast<ObjCCategoryDecl>(D)->getImplementation())
4989 return MakeCXCursor(Impl, TU);
4990 return clang_getNullCursor();
4991
4992 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004993 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 return MakeCXCursor(Def, TU);
4995 return clang_getNullCursor();
4996
4997 case Decl::ObjCInterface: {
4998 // There are two notions of a "definition" for an Objective-C
4999 // class: the interface and its implementation. When we resolved a
5000 // reference to an Objective-C class, produce the @interface as
5001 // the definition; when we were provided with the interface,
5002 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005003 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005004 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005005 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 return MakeCXCursor(Def, TU);
5007 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5008 return MakeCXCursor(Impl, TU);
5009 return clang_getNullCursor();
5010 }
5011
5012 case Decl::ObjCProperty:
5013 // FIXME: We don't really know where to find the
5014 // ObjCPropertyImplDecls that implement this property.
5015 return clang_getNullCursor();
5016
5017 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005018 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005019 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005020 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005021 return MakeCXCursor(Def, TU);
5022
5023 return clang_getNullCursor();
5024
5025 case Decl::Friend:
5026 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5027 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5028 return clang_getNullCursor();
5029
5030 case Decl::FriendTemplate:
5031 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5032 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5033 return clang_getNullCursor();
5034 }
5035
5036 return clang_getNullCursor();
5037}
5038
5039unsigned clang_isCursorDefinition(CXCursor C) {
5040 if (!clang_isDeclaration(C.kind))
5041 return 0;
5042
5043 return clang_getCursorDefinition(C) == C;
5044}
5045
5046CXCursor clang_getCanonicalCursor(CXCursor C) {
5047 if (!clang_isDeclaration(C.kind))
5048 return C;
5049
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005050 if (const Decl *D = getCursorDecl(C)) {
5051 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005052 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5053 return MakeCXCursor(CatD, getCursorTU(C));
5054
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005055 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5056 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005057 return MakeCXCursor(IFD, getCursorTU(C));
5058
5059 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5060 }
5061
5062 return C;
5063}
5064
5065int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5066 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5067}
5068
5069unsigned clang_getNumOverloadedDecls(CXCursor C) {
5070 if (C.kind != CXCursor_OverloadedDeclRef)
5071 return 0;
5072
5073 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005074 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005075 return E->getNumDecls();
5076
5077 if (OverloadedTemplateStorage *S
5078 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5079 return S->size();
5080
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005081 const Decl *D = Storage.get<const Decl *>();
5082 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 return Using->shadow_size();
5084
5085 return 0;
5086}
5087
5088CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5089 if (cursor.kind != CXCursor_OverloadedDeclRef)
5090 return clang_getNullCursor();
5091
5092 if (index >= clang_getNumOverloadedDecls(cursor))
5093 return clang_getNullCursor();
5094
5095 CXTranslationUnit TU = getCursorTU(cursor);
5096 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005097 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005098 return MakeCXCursor(E->decls_begin()[index], TU);
5099
5100 if (OverloadedTemplateStorage *S
5101 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5102 return MakeCXCursor(S->begin()[index], TU);
5103
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005104 const Decl *D = Storage.get<const Decl *>();
5105 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 // FIXME: This is, unfortunately, linear time.
5107 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5108 std::advance(Pos, index);
5109 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5110 }
5111
5112 return clang_getNullCursor();
5113}
5114
5115void clang_getDefinitionSpellingAndExtent(CXCursor C,
5116 const char **startBuf,
5117 const char **endBuf,
5118 unsigned *startLine,
5119 unsigned *startColumn,
5120 unsigned *endLine,
5121 unsigned *endColumn) {
5122 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005123 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5125
5126 SourceManager &SM = FD->getASTContext().getSourceManager();
5127 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5128 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5129 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5130 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5131 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5132 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5133}
5134
5135
5136CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5137 unsigned PieceIndex) {
5138 RefNamePieces Pieces;
5139
5140 switch (C.kind) {
5141 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005142 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5144 E->getQualifierLoc().getSourceRange());
5145 break;
5146
5147 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005148 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005149 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5150 E->getQualifierLoc().getSourceRange(),
5151 E->getOptionalExplicitTemplateArgs());
5152 break;
5153
5154 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005155 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005157 const Expr *Callee = OCE->getCallee();
5158 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 Callee = ICE->getSubExpr();
5160
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005161 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5163 DRE->getQualifierLoc().getSourceRange());
5164 }
5165 break;
5166
5167 default:
5168 break;
5169 }
5170
5171 if (Pieces.empty()) {
5172 if (PieceIndex == 0)
5173 return clang_getCursorExtent(C);
5174 } else if (PieceIndex < Pieces.size()) {
5175 SourceRange R = Pieces[PieceIndex];
5176 if (R.isValid())
5177 return cxloc::translateSourceRange(getCursorContext(C), R);
5178 }
5179
5180 return clang_getNullRange();
5181}
5182
5183void clang_enableStackTraces(void) {
5184 llvm::sys::PrintStackTraceOnErrorSignal();
5185}
5186
5187void clang_executeOnThread(void (*fn)(void*), void *user_data,
5188 unsigned stack_size) {
5189 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5190}
5191
5192} // end: extern "C"
5193
5194//===----------------------------------------------------------------------===//
5195// Token-based Operations.
5196//===----------------------------------------------------------------------===//
5197
5198/* CXToken layout:
5199 * int_data[0]: a CXTokenKind
5200 * int_data[1]: starting token location
5201 * int_data[2]: token length
5202 * int_data[3]: reserved
5203 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5204 * otherwise unused.
5205 */
5206extern "C" {
5207
5208CXTokenKind clang_getTokenKind(CXToken CXTok) {
5209 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5210}
5211
5212CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5213 switch (clang_getTokenKind(CXTok)) {
5214 case CXToken_Identifier:
5215 case CXToken_Keyword:
5216 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005217 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 ->getNameStart());
5219
5220 case CXToken_Literal: {
5221 // We have stashed the starting pointer in the ptr_data field. Use it.
5222 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005223 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 }
5225
5226 case CXToken_Punctuation:
5227 case CXToken_Comment:
5228 break;
5229 }
5230
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005231 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005232 LOG_BAD_TU(TU);
5233 return cxstring::createEmpty();
5234 }
5235
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 // We have to find the starting buffer pointer the hard way, by
5237 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005238 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005239 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005240 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005241
5242 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5243 std::pair<FileID, unsigned> LocInfo
5244 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5245 bool Invalid = false;
5246 StringRef Buffer
5247 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5248 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005249 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005250
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005251 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005252}
5253
5254CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
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 clang_getNullLocation();
5258 }
5259
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005260 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005261 if (!CXXUnit)
5262 return clang_getNullLocation();
5263
5264 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5265 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5266}
5267
5268CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005269 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005270 LOG_BAD_TU(TU);
5271 return clang_getNullRange();
5272 }
5273
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005274 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 if (!CXXUnit)
5276 return clang_getNullRange();
5277
5278 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5279 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5280}
5281
5282static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5283 SmallVectorImpl<CXToken> &CXTokens) {
5284 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5285 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005286 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005287 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005288 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005289
5290 // Cannot tokenize across files.
5291 if (BeginLocInfo.first != EndLocInfo.first)
5292 return;
5293
5294 // Create a lexer
5295 bool Invalid = false;
5296 StringRef Buffer
5297 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5298 if (Invalid)
5299 return;
5300
5301 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5302 CXXUnit->getASTContext().getLangOpts(),
5303 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5304 Lex.SetCommentRetentionState(true);
5305
5306 // Lex tokens until we hit the end of the range.
5307 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5308 Token Tok;
5309 bool previousWasAt = false;
5310 do {
5311 // Lex the next token
5312 Lex.LexFromRawLexer(Tok);
5313 if (Tok.is(tok::eof))
5314 break;
5315
5316 // Initialize the CXToken.
5317 CXToken CXTok;
5318
5319 // - Common fields
5320 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5321 CXTok.int_data[2] = Tok.getLength();
5322 CXTok.int_data[3] = 0;
5323
5324 // - Kind-specific fields
5325 if (Tok.isLiteral()) {
5326 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005327 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 } else if (Tok.is(tok::raw_identifier)) {
5329 // Lookup the identifier to determine whether we have a keyword.
5330 IdentifierInfo *II
5331 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5332
5333 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5334 CXTok.int_data[0] = CXToken_Keyword;
5335 }
5336 else {
5337 CXTok.int_data[0] = Tok.is(tok::identifier)
5338 ? CXToken_Identifier
5339 : CXToken_Keyword;
5340 }
5341 CXTok.ptr_data = II;
5342 } else if (Tok.is(tok::comment)) {
5343 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005344 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005345 } else {
5346 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005347 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 }
5349 CXTokens.push_back(CXTok);
5350 previousWasAt = Tok.is(tok::at);
5351 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5352}
5353
5354void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5355 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005356 LOG_FUNC_SECTION {
5357 *Log << TU << ' ' << Range;
5358 }
5359
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005361 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 if (NumTokens)
5363 *NumTokens = 0;
5364
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005365 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005366 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005367 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005368 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005369
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005370 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005371 if (!CXXUnit || !Tokens || !NumTokens)
5372 return;
5373
5374 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5375
5376 SourceRange R = cxloc::translateCXSourceRange(Range);
5377 if (R.isInvalid())
5378 return;
5379
5380 SmallVector<CXToken, 32> CXTokens;
5381 getTokens(CXXUnit, R, CXTokens);
5382
5383 if (CXTokens.empty())
5384 return;
5385
5386 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5387 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5388 *NumTokens = CXTokens.size();
5389}
5390
5391void clang_disposeTokens(CXTranslationUnit TU,
5392 CXToken *Tokens, unsigned NumTokens) {
5393 free(Tokens);
5394}
5395
5396} // end: extern "C"
5397
5398//===----------------------------------------------------------------------===//
5399// Token annotation APIs.
5400//===----------------------------------------------------------------------===//
5401
Guy Benyei11169dd2012-12-18 14:30:41 +00005402static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5403 CXCursor parent,
5404 CXClientData client_data);
5405static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5406 CXClientData client_data);
5407
5408namespace {
5409class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005410 CXToken *Tokens;
5411 CXCursor *Cursors;
5412 unsigned NumTokens;
5413 unsigned TokIdx;
5414 unsigned PreprocessingTokIdx;
5415 CursorVisitor AnnotateVis;
5416 SourceManager &SrcMgr;
5417 bool HasContextSensitiveKeywords;
5418
5419 struct PostChildrenInfo {
5420 CXCursor Cursor;
5421 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005422 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 unsigned BeforeChildrenTokenIdx;
5424 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005425 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005426
5427 CXToken &getTok(unsigned Idx) {
5428 assert(Idx < NumTokens);
5429 return Tokens[Idx];
5430 }
5431 const CXToken &getTok(unsigned Idx) const {
5432 assert(Idx < NumTokens);
5433 return Tokens[Idx];
5434 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 bool MoreTokens() const { return TokIdx < NumTokens; }
5436 unsigned NextToken() const { return TokIdx; }
5437 void AdvanceToken() { ++TokIdx; }
5438 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005439 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005440 }
5441 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005442 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 }
5444 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005445 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005446 }
5447
5448 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005449 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005450 SourceRange);
5451
5452public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005453 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005454 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005455 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005457 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005458 AnnotateTokensVisitor, this,
5459 /*VisitPreprocessorLast=*/true,
5460 /*VisitIncludedEntities=*/false,
5461 RegionOfInterest,
5462 /*VisitDeclsOnly=*/false,
5463 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005464 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 HasContextSensitiveKeywords(false) { }
5466
5467 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5468 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5469 bool postVisitChildren(CXCursor cursor);
5470 void AnnotateTokens();
5471
5472 /// \brief Determine whether the annotator saw any cursors that have
5473 /// context-sensitive keywords.
5474 bool hasContextSensitiveKeywords() const {
5475 return HasContextSensitiveKeywords;
5476 }
5477
5478 ~AnnotateTokensWorker() {
5479 assert(PostChildrenInfos.empty());
5480 }
5481};
5482}
5483
5484void AnnotateTokensWorker::AnnotateTokens() {
5485 // Walk the AST within the region of interest, annotating tokens
5486 // along the way.
5487 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005488}
Guy Benyei11169dd2012-12-18 14:30:41 +00005489
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005490static inline void updateCursorAnnotation(CXCursor &Cursor,
5491 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005492 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005493 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005494 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005495}
5496
5497/// \brief It annotates and advances tokens with a cursor until the comparison
5498//// between the cursor location and the source range is the same as
5499/// \arg compResult.
5500///
5501/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5502/// Pass RangeOverlap to annotate tokens inside a range.
5503void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5504 RangeComparisonResult compResult,
5505 SourceRange range) {
5506 while (MoreTokens()) {
5507 const unsigned I = NextToken();
5508 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005509 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5510 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005511
5512 SourceLocation TokLoc = GetTokenLoc(I);
5513 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005514 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 AdvanceToken();
5516 continue;
5517 }
5518 break;
5519 }
5520}
5521
5522/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005523/// \returns true if it advanced beyond all macro tokens, false otherwise.
5524bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 CXCursor updateC,
5526 RangeComparisonResult compResult,
5527 SourceRange range) {
5528 assert(MoreTokens());
5529 assert(isFunctionMacroToken(NextToken()) &&
5530 "Should be called only for macro arg tokens");
5531
5532 // This works differently than annotateAndAdvanceTokens; because expanded
5533 // macro arguments can have arbitrary translation-unit source order, we do not
5534 // advance the token index one by one until a token fails the range test.
5535 // We only advance once past all of the macro arg tokens if all of them
5536 // pass the range test. If one of them fails we keep the token index pointing
5537 // at the start of the macro arg tokens so that the failing token will be
5538 // annotated by a subsequent annotation try.
5539
5540 bool atLeastOneCompFail = false;
5541
5542 unsigned I = NextToken();
5543 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5544 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5545 if (TokLoc.isFileID())
5546 continue; // not macro arg token, it's parens or comma.
5547 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5548 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5549 Cursors[I] = updateC;
5550 } else
5551 atLeastOneCompFail = true;
5552 }
5553
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005554 if (atLeastOneCompFail)
5555 return false;
5556
5557 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5558 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005559}
5560
5561enum CXChildVisitResult
5562AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005563 SourceRange cursorRange = getRawCursorExtent(cursor);
5564 if (cursorRange.isInvalid())
5565 return CXChildVisit_Recurse;
5566
5567 if (!HasContextSensitiveKeywords) {
5568 // Objective-C properties can have context-sensitive keywords.
5569 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005570 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005571 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5572 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5573 }
5574 // Objective-C methods can have context-sensitive keywords.
5575 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5576 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005577 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005578 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5579 if (Method->getObjCDeclQualifier())
5580 HasContextSensitiveKeywords = true;
5581 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005582 for (const auto *P : Method->params()) {
5583 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 HasContextSensitiveKeywords = true;
5585 break;
5586 }
5587 }
5588 }
5589 }
5590 }
5591 // C++ methods can have context-sensitive keywords.
5592 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005593 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005594 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5595 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5596 HasContextSensitiveKeywords = true;
5597 }
5598 }
5599 // C++ classes can have context-sensitive keywords.
5600 else if (cursor.kind == CXCursor_StructDecl ||
5601 cursor.kind == CXCursor_ClassDecl ||
5602 cursor.kind == CXCursor_ClassTemplate ||
5603 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005604 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005605 if (D->hasAttr<FinalAttr>())
5606 HasContextSensitiveKeywords = true;
5607 }
5608 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005609
5610 // Don't override a property annotation with its getter/setter method.
5611 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5612 parent.kind == CXCursor_ObjCPropertyDecl)
5613 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005614
5615 if (clang_isPreprocessing(cursor.kind)) {
5616 // Items in the preprocessing record are kept separate from items in
5617 // declarations, so we keep a separate token index.
5618 unsigned SavedTokIdx = TokIdx;
5619 TokIdx = PreprocessingTokIdx;
5620
5621 // Skip tokens up until we catch up to the beginning of the preprocessing
5622 // entry.
5623 while (MoreTokens()) {
5624 const unsigned I = NextToken();
5625 SourceLocation TokLoc = GetTokenLoc(I);
5626 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5627 case RangeBefore:
5628 AdvanceToken();
5629 continue;
5630 case RangeAfter:
5631 case RangeOverlap:
5632 break;
5633 }
5634 break;
5635 }
5636
5637 // Look at all of the tokens within this range.
5638 while (MoreTokens()) {
5639 const unsigned I = NextToken();
5640 SourceLocation TokLoc = GetTokenLoc(I);
5641 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5642 case RangeBefore:
5643 llvm_unreachable("Infeasible");
5644 case RangeAfter:
5645 break;
5646 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005647 // For macro expansions, just note where the beginning of the macro
5648 // expansion occurs.
5649 if (cursor.kind == CXCursor_MacroExpansion) {
5650 if (TokLoc == cursorRange.getBegin())
5651 Cursors[I] = cursor;
5652 AdvanceToken();
5653 break;
5654 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005655 // We may have already annotated macro names inside macro definitions.
5656 if (Cursors[I].kind != CXCursor_MacroExpansion)
5657 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005658 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005659 continue;
5660 }
5661 break;
5662 }
5663
5664 // Save the preprocessing token index; restore the non-preprocessing
5665 // token index.
5666 PreprocessingTokIdx = TokIdx;
5667 TokIdx = SavedTokIdx;
5668 return CXChildVisit_Recurse;
5669 }
5670
5671 if (cursorRange.isInvalid())
5672 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005673
5674 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 const enum CXCursorKind K = clang_getCursorKind(parent);
5677 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005678 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5679 // Attributes are annotated out-of-order, skip tokens until we reach it.
5680 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 ? clang_getNullCursor() : parent;
5682
5683 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5684
5685 // Avoid having the cursor of an expression "overwrite" the annotation of the
5686 // variable declaration that it belongs to.
5687 // This can happen for C++ constructor expressions whose range generally
5688 // include the variable declaration, e.g.:
5689 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005690 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005691 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005692 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005693 const unsigned I = NextToken();
5694 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5695 E->getLocStart() == D->getLocation() &&
5696 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005697 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005698 AdvanceToken();
5699 }
5700 }
5701 }
5702
5703 // Before recursing into the children keep some state that we are going
5704 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5705 // extra work after the child nodes are visited.
5706 // Note that we don't call VisitChildren here to avoid traversing statements
5707 // code-recursively which can blow the stack.
5708
5709 PostChildrenInfo Info;
5710 Info.Cursor = cursor;
5711 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005712 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005713 Info.BeforeChildrenTokenIdx = NextToken();
5714 PostChildrenInfos.push_back(Info);
5715
5716 return CXChildVisit_Recurse;
5717}
5718
5719bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5720 if (PostChildrenInfos.empty())
5721 return false;
5722 const PostChildrenInfo &Info = PostChildrenInfos.back();
5723 if (!clang_equalCursors(Info.Cursor, cursor))
5724 return false;
5725
5726 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5727 const unsigned AfterChildren = NextToken();
5728 SourceRange cursorRange = Info.CursorRange;
5729
5730 // Scan the tokens that are at the end of the cursor, but are not captured
5731 // but the child cursors.
5732 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5733
5734 // Scan the tokens that are at the beginning of the cursor, but are not
5735 // capture by the child cursors.
5736 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5737 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5738 break;
5739
5740 Cursors[I] = cursor;
5741 }
5742
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005743 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5744 // encountered the attribute cursor.
5745 if (clang_isAttribute(cursor.kind))
5746 TokIdx = Info.BeforeReachingCursorIdx;
5747
Guy Benyei11169dd2012-12-18 14:30:41 +00005748 PostChildrenInfos.pop_back();
5749 return false;
5750}
5751
5752static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5753 CXCursor parent,
5754 CXClientData client_data) {
5755 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5756}
5757
5758static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5759 CXClientData client_data) {
5760 return static_cast<AnnotateTokensWorker*>(client_data)->
5761 postVisitChildren(cursor);
5762}
5763
5764namespace {
5765
5766/// \brief Uses the macro expansions in the preprocessing record to find
5767/// and mark tokens that are macro arguments. This info is used by the
5768/// AnnotateTokensWorker.
5769class MarkMacroArgTokensVisitor {
5770 SourceManager &SM;
5771 CXToken *Tokens;
5772 unsigned NumTokens;
5773 unsigned CurIdx;
5774
5775public:
5776 MarkMacroArgTokensVisitor(SourceManager &SM,
5777 CXToken *tokens, unsigned numTokens)
5778 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5779
5780 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5781 if (cursor.kind != CXCursor_MacroExpansion)
5782 return CXChildVisit_Continue;
5783
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005784 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005785 if (macroRange.getBegin() == macroRange.getEnd())
5786 return CXChildVisit_Continue; // it's not a function macro.
5787
5788 for (; CurIdx < NumTokens; ++CurIdx) {
5789 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5790 macroRange.getBegin()))
5791 break;
5792 }
5793
5794 if (CurIdx == NumTokens)
5795 return CXChildVisit_Break;
5796
5797 for (; CurIdx < NumTokens; ++CurIdx) {
5798 SourceLocation tokLoc = getTokenLoc(CurIdx);
5799 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5800 break;
5801
5802 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5803 }
5804
5805 if (CurIdx == NumTokens)
5806 return CXChildVisit_Break;
5807
5808 return CXChildVisit_Continue;
5809 }
5810
5811private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005812 CXToken &getTok(unsigned Idx) {
5813 assert(Idx < NumTokens);
5814 return Tokens[Idx];
5815 }
5816 const CXToken &getTok(unsigned Idx) const {
5817 assert(Idx < NumTokens);
5818 return Tokens[Idx];
5819 }
5820
Guy Benyei11169dd2012-12-18 14:30:41 +00005821 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005822 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005823 }
5824
5825 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5826 // The third field is reserved and currently not used. Use it here
5827 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005828 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005829 }
5830};
5831
5832} // end anonymous namespace
5833
5834static CXChildVisitResult
5835MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5836 CXClientData client_data) {
5837 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5838 parent);
5839}
5840
5841namespace {
5842 struct clang_annotateTokens_Data {
5843 CXTranslationUnit TU;
5844 ASTUnit *CXXUnit;
5845 CXToken *Tokens;
5846 unsigned NumTokens;
5847 CXCursor *Cursors;
5848 };
5849}
5850
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005851/// \brief Used by \c annotatePreprocessorTokens.
5852/// \returns true if lexing was finished, false otherwise.
5853static bool lexNext(Lexer &Lex, Token &Tok,
5854 unsigned &NextIdx, unsigned NumTokens) {
5855 if (NextIdx >= NumTokens)
5856 return true;
5857
5858 ++NextIdx;
5859 Lex.LexFromRawLexer(Tok);
5860 if (Tok.is(tok::eof))
5861 return true;
5862
5863 return false;
5864}
5865
Guy Benyei11169dd2012-12-18 14:30:41 +00005866static void annotatePreprocessorTokens(CXTranslationUnit TU,
5867 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005868 CXCursor *Cursors,
5869 CXToken *Tokens,
5870 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005871 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005872
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005873 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005874 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5875 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005876 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005877 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005878 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005879
5880 if (BeginLocInfo.first != EndLocInfo.first)
5881 return;
5882
5883 StringRef Buffer;
5884 bool Invalid = false;
5885 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5886 if (Buffer.empty() || Invalid)
5887 return;
5888
5889 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5890 CXXUnit->getASTContext().getLangOpts(),
5891 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5892 Buffer.end());
5893 Lex.SetCommentRetentionState(true);
5894
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005895 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005896 // Lex tokens in raw mode until we hit the end of the range, to avoid
5897 // entering #includes or expanding macros.
5898 while (true) {
5899 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005900 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5901 break;
5902 unsigned TokIdx = NextIdx-1;
5903 assert(Tok.getLocation() ==
5904 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005905
5906 reprocess:
5907 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005908 // We have found a preprocessing directive. Annotate the tokens
5909 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005910 //
5911 // FIXME: Some simple tests here could identify macro definitions and
5912 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005913
5914 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005915 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5916 break;
5917
Craig Topper69186e72014-06-08 08:38:04 +00005918 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005919 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005920 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5921 break;
5922
5923 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005924 IdentifierInfo &II =
5925 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005926 SourceLocation MappedTokLoc =
5927 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5928 MI = getMacroInfo(II, MappedTokLoc, TU);
5929 }
5930 }
5931
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005932 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005933 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005934 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5935 finished = true;
5936 break;
5937 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005938 // If we are in a macro definition, check if the token was ever a
5939 // macro name and annotate it if that's the case.
5940 if (MI) {
5941 SourceLocation SaveLoc = Tok.getLocation();
5942 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5943 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5944 Tok.setLocation(SaveLoc);
5945 if (MacroDef)
5946 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5947 Tok.getLocation(), TU);
5948 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005949 } while (!Tok.isAtStartOfLine());
5950
5951 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5952 assert(TokIdx <= LastIdx);
5953 SourceLocation EndLoc =
5954 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5955 CXCursor Cursor =
5956 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5957
5958 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005959 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005960
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005961 if (finished)
5962 break;
5963 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005964 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005965 }
5966}
5967
5968// This gets run a separate thread to avoid stack blowout.
5969static void clang_annotateTokensImpl(void *UserData) {
5970 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5971 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5972 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5973 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5974 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5975
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005976 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005977 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5978 setThreadBackgroundPriority();
5979
5980 // Determine the region of interest, which contains all of the tokens.
5981 SourceRange RegionOfInterest;
5982 RegionOfInterest.setBegin(
5983 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5984 RegionOfInterest.setEnd(
5985 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5986 Tokens[NumTokens-1])));
5987
Guy Benyei11169dd2012-12-18 14:30:41 +00005988 // Relex the tokens within the source range to look for preprocessing
5989 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005990 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005991
5992 // If begin location points inside a macro argument, set it to the expansion
5993 // location so we can have the full context when annotating semantically.
5994 {
5995 SourceManager &SM = CXXUnit->getSourceManager();
5996 SourceLocation Loc =
5997 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5998 if (Loc.isMacroID())
5999 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6000 }
6001
Guy Benyei11169dd2012-12-18 14:30:41 +00006002 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6003 // Search and mark tokens that are macro argument expansions.
6004 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6005 Tokens, NumTokens);
6006 CursorVisitor MacroArgMarker(TU,
6007 MarkMacroArgTokensVisitorDelegate, &Visitor,
6008 /*VisitPreprocessorLast=*/true,
6009 /*VisitIncludedEntities=*/false,
6010 RegionOfInterest);
6011 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6012 }
6013
6014 // Annotate all of the source locations in the region of interest that map to
6015 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006016 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006017
6018 // FIXME: We use a ridiculous stack size here because the data-recursion
6019 // algorithm uses a large stack frame than the non-data recursive version,
6020 // and AnnotationTokensWorker currently transforms the data-recursion
6021 // algorithm back into a traditional recursion by explicitly calling
6022 // VisitChildren(). We will need to remove this explicit recursive call.
6023 W.AnnotateTokens();
6024
6025 // If we ran into any entities that involve context-sensitive keywords,
6026 // take another pass through the tokens to mark them as such.
6027 if (W.hasContextSensitiveKeywords()) {
6028 for (unsigned I = 0; I != NumTokens; ++I) {
6029 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6030 continue;
6031
6032 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6033 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006034 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006035 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6036 if (Property->getPropertyAttributesAsWritten() != 0 &&
6037 llvm::StringSwitch<bool>(II->getName())
6038 .Case("readonly", true)
6039 .Case("assign", true)
6040 .Case("unsafe_unretained", true)
6041 .Case("readwrite", true)
6042 .Case("retain", true)
6043 .Case("copy", true)
6044 .Case("nonatomic", true)
6045 .Case("atomic", true)
6046 .Case("getter", true)
6047 .Case("setter", true)
6048 .Case("strong", true)
6049 .Case("weak", true)
6050 .Default(false))
6051 Tokens[I].int_data[0] = CXToken_Keyword;
6052 }
6053 continue;
6054 }
6055
6056 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6057 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6058 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6059 if (llvm::StringSwitch<bool>(II->getName())
6060 .Case("in", true)
6061 .Case("out", true)
6062 .Case("inout", true)
6063 .Case("oneway", true)
6064 .Case("bycopy", true)
6065 .Case("byref", true)
6066 .Default(false))
6067 Tokens[I].int_data[0] = CXToken_Keyword;
6068 continue;
6069 }
6070
6071 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6072 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6073 Tokens[I].int_data[0] = CXToken_Keyword;
6074 continue;
6075 }
6076 }
6077 }
6078}
6079
6080extern "C" {
6081
6082void clang_annotateTokens(CXTranslationUnit TU,
6083 CXToken *Tokens, unsigned NumTokens,
6084 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006085 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006086 LOG_BAD_TU(TU);
6087 return;
6088 }
6089 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006090 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006091 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006092 }
6093
6094 LOG_FUNC_SECTION {
6095 *Log << TU << ' ';
6096 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6097 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6098 *Log << clang_getRange(bloc, eloc);
6099 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006100
6101 // Any token we don't specifically annotate will have a NULL cursor.
6102 CXCursor C = clang_getNullCursor();
6103 for (unsigned I = 0; I != NumTokens; ++I)
6104 Cursors[I] = C;
6105
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006106 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006107 if (!CXXUnit)
6108 return;
6109
6110 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6111
6112 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6113 llvm::CrashRecoveryContext CRC;
6114 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6115 GetSafetyThreadStackSize() * 2)) {
6116 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6117 }
6118}
6119
6120} // end: extern "C"
6121
6122//===----------------------------------------------------------------------===//
6123// Operations for querying linkage of a cursor.
6124//===----------------------------------------------------------------------===//
6125
6126extern "C" {
6127CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6128 if (!clang_isDeclaration(cursor.kind))
6129 return CXLinkage_Invalid;
6130
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006131 const Decl *D = cxcursor::getCursorDecl(cursor);
6132 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006133 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006134 case NoLinkage:
6135 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006136 case InternalLinkage: return CXLinkage_Internal;
6137 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6138 case ExternalLinkage: return CXLinkage_External;
6139 };
6140
6141 return CXLinkage_Invalid;
6142}
6143} // end: extern "C"
6144
6145//===----------------------------------------------------------------------===//
6146// Operations for querying language of a cursor.
6147//===----------------------------------------------------------------------===//
6148
6149static CXLanguageKind getDeclLanguage(const Decl *D) {
6150 if (!D)
6151 return CXLanguage_C;
6152
6153 switch (D->getKind()) {
6154 default:
6155 break;
6156 case Decl::ImplicitParam:
6157 case Decl::ObjCAtDefsField:
6158 case Decl::ObjCCategory:
6159 case Decl::ObjCCategoryImpl:
6160 case Decl::ObjCCompatibleAlias:
6161 case Decl::ObjCImplementation:
6162 case Decl::ObjCInterface:
6163 case Decl::ObjCIvar:
6164 case Decl::ObjCMethod:
6165 case Decl::ObjCProperty:
6166 case Decl::ObjCPropertyImpl:
6167 case Decl::ObjCProtocol:
6168 return CXLanguage_ObjC;
6169 case Decl::CXXConstructor:
6170 case Decl::CXXConversion:
6171 case Decl::CXXDestructor:
6172 case Decl::CXXMethod:
6173 case Decl::CXXRecord:
6174 case Decl::ClassTemplate:
6175 case Decl::ClassTemplatePartialSpecialization:
6176 case Decl::ClassTemplateSpecialization:
6177 case Decl::Friend:
6178 case Decl::FriendTemplate:
6179 case Decl::FunctionTemplate:
6180 case Decl::LinkageSpec:
6181 case Decl::Namespace:
6182 case Decl::NamespaceAlias:
6183 case Decl::NonTypeTemplateParm:
6184 case Decl::StaticAssert:
6185 case Decl::TemplateTemplateParm:
6186 case Decl::TemplateTypeParm:
6187 case Decl::UnresolvedUsingTypename:
6188 case Decl::UnresolvedUsingValue:
6189 case Decl::Using:
6190 case Decl::UsingDirective:
6191 case Decl::UsingShadow:
6192 return CXLanguage_CPlusPlus;
6193 }
6194
6195 return CXLanguage_C;
6196}
6197
6198extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006199
6200static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6201 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6202 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006203
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006204 switch (D->getAvailability()) {
6205 case AR_Available:
6206 case AR_NotYetIntroduced:
6207 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006208 return getCursorAvailabilityForDecl(
6209 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006210 return CXAvailability_Available;
6211
6212 case AR_Deprecated:
6213 return CXAvailability_Deprecated;
6214
6215 case AR_Unavailable:
6216 return CXAvailability_NotAvailable;
6217 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006218
6219 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006220}
6221
Guy Benyei11169dd2012-12-18 14:30:41 +00006222enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6223 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006224 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6225 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006226
6227 return CXAvailability_Available;
6228}
6229
6230static CXVersion convertVersion(VersionTuple In) {
6231 CXVersion Out = { -1, -1, -1 };
6232 if (In.empty())
6233 return Out;
6234
6235 Out.Major = In.getMajor();
6236
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006237 Optional<unsigned> Minor = In.getMinor();
6238 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006239 Out.Minor = *Minor;
6240 else
6241 return Out;
6242
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006243 Optional<unsigned> Subminor = In.getSubminor();
6244 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006245 Out.Subminor = *Subminor;
6246
6247 return Out;
6248}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006249
6250static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6251 int *always_deprecated,
6252 CXString *deprecated_message,
6253 int *always_unavailable,
6254 CXString *unavailable_message,
6255 CXPlatformAvailability *availability,
6256 int availability_size) {
6257 bool HadAvailAttr = false;
6258 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006259 for (auto A : D->attrs()) {
6260 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006261 HadAvailAttr = true;
6262 if (always_deprecated)
6263 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006264 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006265 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006266 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006267 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006268 continue;
6269 }
6270
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006271 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006272 HadAvailAttr = true;
6273 if (always_unavailable)
6274 *always_unavailable = 1;
6275 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006276 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006277 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6278 }
6279 continue;
6280 }
6281
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006282 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006283 HadAvailAttr = true;
6284 if (N < availability_size) {
6285 availability[N].Platform
6286 = cxstring::createDup(Avail->getPlatform()->getName());
6287 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6288 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6289 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6290 availability[N].Unavailable = Avail->getUnavailable();
6291 availability[N].Message = cxstring::createDup(Avail->getMessage());
6292 }
6293 ++N;
6294 }
6295 }
6296
6297 if (!HadAvailAttr)
6298 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6299 return getCursorPlatformAvailabilityForDecl(
6300 cast<Decl>(EnumConst->getDeclContext()),
6301 always_deprecated,
6302 deprecated_message,
6303 always_unavailable,
6304 unavailable_message,
6305 availability,
6306 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006307
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006308 return N;
6309}
6310
Guy Benyei11169dd2012-12-18 14:30:41 +00006311int clang_getCursorPlatformAvailability(CXCursor cursor,
6312 int *always_deprecated,
6313 CXString *deprecated_message,
6314 int *always_unavailable,
6315 CXString *unavailable_message,
6316 CXPlatformAvailability *availability,
6317 int availability_size) {
6318 if (always_deprecated)
6319 *always_deprecated = 0;
6320 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006321 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006322 if (always_unavailable)
6323 *always_unavailable = 0;
6324 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006325 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006326
Guy Benyei11169dd2012-12-18 14:30:41 +00006327 if (!clang_isDeclaration(cursor.kind))
6328 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006329
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006330 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006331 if (!D)
6332 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006333
6334 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6335 deprecated_message,
6336 always_unavailable,
6337 unavailable_message,
6338 availability,
6339 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006340}
6341
6342void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6343 clang_disposeString(availability->Platform);
6344 clang_disposeString(availability->Message);
6345}
6346
6347CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6348 if (clang_isDeclaration(cursor.kind))
6349 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6350
6351 return CXLanguage_Invalid;
6352}
6353
6354 /// \brief If the given cursor is the "templated" declaration
6355 /// descibing a class or function template, return the class or
6356 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006357static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006358 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006359 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006360
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006361 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006362 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6363 return FunTmpl;
6364
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006365 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006366 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6367 return ClassTmpl;
6368
6369 return D;
6370}
6371
6372CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6373 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006374 if (const Decl *D = getCursorDecl(cursor)) {
6375 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006376 if (!DC)
6377 return clang_getNullCursor();
6378
6379 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6380 getCursorTU(cursor));
6381 }
6382 }
6383
6384 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006385 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006386 return MakeCXCursor(D, getCursorTU(cursor));
6387 }
6388
6389 return clang_getNullCursor();
6390}
6391
6392CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6393 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006394 if (const Decl *D = getCursorDecl(cursor)) {
6395 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006396 if (!DC)
6397 return clang_getNullCursor();
6398
6399 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6400 getCursorTU(cursor));
6401 }
6402 }
6403
6404 // FIXME: Note that we can't easily compute the lexical context of a
6405 // statement or expression, so we return nothing.
6406 return clang_getNullCursor();
6407}
6408
6409CXFile clang_getIncludedFile(CXCursor cursor) {
6410 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006411 return nullptr;
6412
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006413 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006414 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006415}
6416
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006417unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6418 if (C.kind != CXCursor_ObjCPropertyDecl)
6419 return CXObjCPropertyAttr_noattr;
6420
6421 unsigned Result = CXObjCPropertyAttr_noattr;
6422 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6423 ObjCPropertyDecl::PropertyAttributeKind Attr =
6424 PD->getPropertyAttributesAsWritten();
6425
6426#define SET_CXOBJCPROP_ATTR(A) \
6427 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6428 Result |= CXObjCPropertyAttr_##A
6429 SET_CXOBJCPROP_ATTR(readonly);
6430 SET_CXOBJCPROP_ATTR(getter);
6431 SET_CXOBJCPROP_ATTR(assign);
6432 SET_CXOBJCPROP_ATTR(readwrite);
6433 SET_CXOBJCPROP_ATTR(retain);
6434 SET_CXOBJCPROP_ATTR(copy);
6435 SET_CXOBJCPROP_ATTR(nonatomic);
6436 SET_CXOBJCPROP_ATTR(setter);
6437 SET_CXOBJCPROP_ATTR(atomic);
6438 SET_CXOBJCPROP_ATTR(weak);
6439 SET_CXOBJCPROP_ATTR(strong);
6440 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6441#undef SET_CXOBJCPROP_ATTR
6442
6443 return Result;
6444}
6445
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006446unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6447 if (!clang_isDeclaration(C.kind))
6448 return CXObjCDeclQualifier_None;
6449
6450 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6451 const Decl *D = getCursorDecl(C);
6452 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6453 QT = MD->getObjCDeclQualifier();
6454 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6455 QT = PD->getObjCDeclQualifier();
6456 if (QT == Decl::OBJC_TQ_None)
6457 return CXObjCDeclQualifier_None;
6458
6459 unsigned Result = CXObjCDeclQualifier_None;
6460 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6461 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6462 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6463 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6464 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6465 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6466
6467 return Result;
6468}
6469
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006470unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6471 if (!clang_isDeclaration(C.kind))
6472 return 0;
6473
6474 const Decl *D = getCursorDecl(C);
6475 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6476 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6477 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6478 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6479
6480 return 0;
6481}
6482
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006483unsigned clang_Cursor_isVariadic(CXCursor C) {
6484 if (!clang_isDeclaration(C.kind))
6485 return 0;
6486
6487 const Decl *D = getCursorDecl(C);
6488 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6489 return FD->isVariadic();
6490 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6491 return MD->isVariadic();
6492
6493 return 0;
6494}
6495
Guy Benyei11169dd2012-12-18 14:30:41 +00006496CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6497 if (!clang_isDeclaration(C.kind))
6498 return clang_getNullRange();
6499
6500 const Decl *D = getCursorDecl(C);
6501 ASTContext &Context = getCursorContext(C);
6502 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6503 if (!RC)
6504 return clang_getNullRange();
6505
6506 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6507}
6508
6509CXString clang_Cursor_getRawCommentText(CXCursor C) {
6510 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006511 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006512
6513 const Decl *D = getCursorDecl(C);
6514 ASTContext &Context = getCursorContext(C);
6515 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6516 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6517 StringRef();
6518
6519 // Don't duplicate the string because RawText points directly into source
6520 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006521 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006522}
6523
6524CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6525 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006526 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006527
6528 const Decl *D = getCursorDecl(C);
6529 const ASTContext &Context = getCursorContext(C);
6530 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6531
6532 if (RC) {
6533 StringRef BriefText = RC->getBriefText(Context);
6534
6535 // Don't duplicate the string because RawComment ensures that this memory
6536 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006537 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006538 }
6539
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006540 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006541}
6542
Guy Benyei11169dd2012-12-18 14:30:41 +00006543CXModule clang_Cursor_getModule(CXCursor C) {
6544 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006545 if (const ImportDecl *ImportD =
6546 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006547 return ImportD->getImportedModule();
6548 }
6549
Craig Topper69186e72014-06-08 08:38:04 +00006550 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006551}
6552
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006553CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6554 if (isNotUsableTU(TU)) {
6555 LOG_BAD_TU(TU);
6556 return nullptr;
6557 }
6558 if (!File)
6559 return nullptr;
6560 FileEntry *FE = static_cast<FileEntry *>(File);
6561
6562 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6563 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6564 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6565
6566 if (Module *Mod = Header.getModule()) {
6567 if (Header.getRole() != ModuleMap::ExcludedHeader)
6568 return Mod;
6569 }
6570 return nullptr;
6571}
6572
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006573CXFile clang_Module_getASTFile(CXModule CXMod) {
6574 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006575 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006576 Module *Mod = static_cast<Module*>(CXMod);
6577 return const_cast<FileEntry *>(Mod->getASTFile());
6578}
6579
Guy Benyei11169dd2012-12-18 14:30:41 +00006580CXModule clang_Module_getParent(CXModule CXMod) {
6581 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006582 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006583 Module *Mod = static_cast<Module*>(CXMod);
6584 return Mod->Parent;
6585}
6586
6587CXString clang_Module_getName(CXModule CXMod) {
6588 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006589 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006590 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006591 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006592}
6593
6594CXString clang_Module_getFullName(CXModule CXMod) {
6595 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006596 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006597 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006598 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006599}
6600
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006601int clang_Module_isSystem(CXModule CXMod) {
6602 if (!CXMod)
6603 return 0;
6604 Module *Mod = static_cast<Module*>(CXMod);
6605 return Mod->IsSystem;
6606}
6607
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006608unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6609 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006610 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006611 LOG_BAD_TU(TU);
6612 return 0;
6613 }
6614 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006615 return 0;
6616 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006617 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6618 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6619 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006620}
6621
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006622CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6623 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006624 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006625 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006626 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006627 }
6628 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006629 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006630 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006631 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006632
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006633 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6634 if (Index < TopHeaders.size())
6635 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006636
Craig Topper69186e72014-06-08 08:38:04 +00006637 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006638}
6639
6640} // end: extern "C"
6641
6642//===----------------------------------------------------------------------===//
6643// C++ AST instrospection.
6644//===----------------------------------------------------------------------===//
6645
6646extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006647unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6648 if (!clang_isDeclaration(C.kind))
6649 return 0;
6650
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006651 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006652 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006653 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006654 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6655}
6656
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006657unsigned clang_CXXMethod_isConst(CXCursor C) {
6658 if (!clang_isDeclaration(C.kind))
6659 return 0;
6660
6661 const Decl *D = cxcursor::getCursorDecl(C);
6662 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006663 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006664 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6665}
6666
Guy Benyei11169dd2012-12-18 14:30:41 +00006667unsigned clang_CXXMethod_isStatic(CXCursor C) {
6668 if (!clang_isDeclaration(C.kind))
6669 return 0;
6670
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006671 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006672 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006673 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006674 return (Method && Method->isStatic()) ? 1 : 0;
6675}
6676
6677unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6678 if (!clang_isDeclaration(C.kind))
6679 return 0;
6680
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006681 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006682 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006683 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006684 return (Method && Method->isVirtual()) ? 1 : 0;
6685}
6686} // end: extern "C"
6687
6688//===----------------------------------------------------------------------===//
6689// Attribute introspection.
6690//===----------------------------------------------------------------------===//
6691
6692extern "C" {
6693CXType clang_getIBOutletCollectionType(CXCursor C) {
6694 if (C.kind != CXCursor_IBOutletCollectionAttr)
6695 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6696
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006697 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006698 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6699
6700 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6701}
6702} // end: extern "C"
6703
6704//===----------------------------------------------------------------------===//
6705// Inspecting memory usage.
6706//===----------------------------------------------------------------------===//
6707
6708typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6709
6710static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6711 enum CXTUResourceUsageKind k,
6712 unsigned long amount) {
6713 CXTUResourceUsageEntry entry = { k, amount };
6714 entries.push_back(entry);
6715}
6716
6717extern "C" {
6718
6719const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6720 const char *str = "";
6721 switch (kind) {
6722 case CXTUResourceUsage_AST:
6723 str = "ASTContext: expressions, declarations, and types";
6724 break;
6725 case CXTUResourceUsage_Identifiers:
6726 str = "ASTContext: identifiers";
6727 break;
6728 case CXTUResourceUsage_Selectors:
6729 str = "ASTContext: selectors";
6730 break;
6731 case CXTUResourceUsage_GlobalCompletionResults:
6732 str = "Code completion: cached global results";
6733 break;
6734 case CXTUResourceUsage_SourceManagerContentCache:
6735 str = "SourceManager: content cache allocator";
6736 break;
6737 case CXTUResourceUsage_AST_SideTables:
6738 str = "ASTContext: side tables";
6739 break;
6740 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6741 str = "SourceManager: malloc'ed memory buffers";
6742 break;
6743 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6744 str = "SourceManager: mmap'ed memory buffers";
6745 break;
6746 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6747 str = "ExternalASTSource: malloc'ed memory buffers";
6748 break;
6749 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6750 str = "ExternalASTSource: mmap'ed memory buffers";
6751 break;
6752 case CXTUResourceUsage_Preprocessor:
6753 str = "Preprocessor: malloc'ed memory";
6754 break;
6755 case CXTUResourceUsage_PreprocessingRecord:
6756 str = "Preprocessor: PreprocessingRecord";
6757 break;
6758 case CXTUResourceUsage_SourceManager_DataStructures:
6759 str = "SourceManager: data structures and tables";
6760 break;
6761 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6762 str = "Preprocessor: header search tables";
6763 break;
6764 }
6765 return str;
6766}
6767
6768CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006769 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006770 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006771 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006772 return usage;
6773 }
6774
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006775 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006776 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006777 ASTContext &astContext = astUnit->getASTContext();
6778
6779 // How much memory is used by AST nodes and types?
6780 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6781 (unsigned long) astContext.getASTAllocatedMemory());
6782
6783 // How much memory is used by identifiers?
6784 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6785 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6786
6787 // How much memory is used for selectors?
6788 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6789 (unsigned long) astContext.Selectors.getTotalMemory());
6790
6791 // How much memory is used by ASTContext's side tables?
6792 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6793 (unsigned long) astContext.getSideTableAllocatedMemory());
6794
6795 // How much memory is used for caching global code completion results?
6796 unsigned long completionBytes = 0;
6797 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006798 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006799 completionBytes = completionAllocator->getTotalMemory();
6800 }
6801 createCXTUResourceUsageEntry(*entries,
6802 CXTUResourceUsage_GlobalCompletionResults,
6803 completionBytes);
6804
6805 // How much memory is being used by SourceManager's content cache?
6806 createCXTUResourceUsageEntry(*entries,
6807 CXTUResourceUsage_SourceManagerContentCache,
6808 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6809
6810 // How much memory is being used by the MemoryBuffer's in SourceManager?
6811 const SourceManager::MemoryBufferSizes &srcBufs =
6812 astUnit->getSourceManager().getMemoryBufferSizes();
6813
6814 createCXTUResourceUsageEntry(*entries,
6815 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6816 (unsigned long) srcBufs.malloc_bytes);
6817 createCXTUResourceUsageEntry(*entries,
6818 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6819 (unsigned long) srcBufs.mmap_bytes);
6820 createCXTUResourceUsageEntry(*entries,
6821 CXTUResourceUsage_SourceManager_DataStructures,
6822 (unsigned long) astContext.getSourceManager()
6823 .getDataStructureSizes());
6824
6825 // How much memory is being used by the ExternalASTSource?
6826 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6827 const ExternalASTSource::MemoryBufferSizes &sizes =
6828 esrc->getMemoryBufferSizes();
6829
6830 createCXTUResourceUsageEntry(*entries,
6831 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6832 (unsigned long) sizes.malloc_bytes);
6833 createCXTUResourceUsageEntry(*entries,
6834 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6835 (unsigned long) sizes.mmap_bytes);
6836 }
6837
6838 // How much memory is being used by the Preprocessor?
6839 Preprocessor &pp = astUnit->getPreprocessor();
6840 createCXTUResourceUsageEntry(*entries,
6841 CXTUResourceUsage_Preprocessor,
6842 pp.getTotalMemory());
6843
6844 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6845 createCXTUResourceUsageEntry(*entries,
6846 CXTUResourceUsage_PreprocessingRecord,
6847 pRec->getTotalMemory());
6848 }
6849
6850 createCXTUResourceUsageEntry(*entries,
6851 CXTUResourceUsage_Preprocessor_HeaderSearch,
6852 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006853
Guy Benyei11169dd2012-12-18 14:30:41 +00006854 CXTUResourceUsage usage = { (void*) entries.get(),
6855 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006856 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006857 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006858 return usage;
6859}
6860
6861void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6862 if (usage.data)
6863 delete (MemUsageEntries*) usage.data;
6864}
6865
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006866CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6867 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006868 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006869 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006870
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006871 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006872 LOG_BAD_TU(TU);
6873 return skipped;
6874 }
6875
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006876 if (!file)
6877 return skipped;
6878
6879 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6880 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6881 if (!ppRec)
6882 return skipped;
6883
6884 ASTContext &Ctx = astUnit->getASTContext();
6885 SourceManager &sm = Ctx.getSourceManager();
6886 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6887 FileID wantedFileID = sm.translateFile(fileEntry);
6888
6889 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6890 std::vector<SourceRange> wantedRanges;
6891 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6892 i != ei; ++i) {
6893 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6894 wantedRanges.push_back(*i);
6895 }
6896
6897 skipped->count = wantedRanges.size();
6898 skipped->ranges = new CXSourceRange[skipped->count];
6899 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6900 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6901
6902 return skipped;
6903}
6904
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006905void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6906 if (ranges) {
6907 delete[] ranges->ranges;
6908 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006909 }
6910}
6911
Guy Benyei11169dd2012-12-18 14:30:41 +00006912} // end extern "C"
6913
6914void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6915 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6916 for (unsigned I = 0; I != Usage.numEntries; ++I)
6917 fprintf(stderr, " %s: %lu\n",
6918 clang_getTUResourceUsageName(Usage.entries[I].kind),
6919 Usage.entries[I].amount);
6920
6921 clang_disposeCXTUResourceUsage(Usage);
6922}
6923
6924//===----------------------------------------------------------------------===//
6925// Misc. utility functions.
6926//===----------------------------------------------------------------------===//
6927
6928/// Default to using an 8 MB stack size on "safety" threads.
6929static unsigned SafetyStackThreadSize = 8 << 20;
6930
6931namespace clang {
6932
6933bool RunSafely(llvm::CrashRecoveryContext &CRC,
6934 void (*Fn)(void*), void *UserData,
6935 unsigned Size) {
6936 if (!Size)
6937 Size = GetSafetyThreadStackSize();
6938 if (Size)
6939 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6940 return CRC.RunSafely(Fn, UserData);
6941}
6942
6943unsigned GetSafetyThreadStackSize() {
6944 return SafetyStackThreadSize;
6945}
6946
6947void SetSafetyThreadStackSize(unsigned Value) {
6948 SafetyStackThreadSize = Value;
6949}
6950
6951}
6952
6953void clang::setThreadBackgroundPriority() {
6954 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6955 return;
6956
Alp Toker1a86ad22014-07-06 06:24:00 +00006957#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006958 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6959#endif
6960}
6961
6962void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6963 if (!Unit)
6964 return;
6965
6966 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6967 DEnd = Unit->stored_diag_end();
6968 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006969 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006970 CXString Msg = clang_formatDiagnostic(&Diag,
6971 clang_defaultDiagnosticDisplayOptions());
6972 fprintf(stderr, "%s\n", clang_getCString(Msg));
6973 clang_disposeString(Msg);
6974 }
6975#ifdef LLVM_ON_WIN32
6976 // On Windows, force a flush, since there may be multiple copies of
6977 // stderr and stdout in the file system, all with different buffers
6978 // but writing to the same device.
6979 fflush(stderr);
6980#endif
6981}
6982
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006983MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6984 SourceLocation MacroDefLoc,
6985 CXTranslationUnit TU){
6986 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006987 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006988 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006989 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006990
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006991 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006992 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006993 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006994 if (MD) {
6995 for (MacroDirective::DefInfo
6996 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6997 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6998 return Def.getMacroInfo();
6999 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007000 }
7001
Craig Topper69186e72014-06-08 08:38:04 +00007002 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007003}
7004
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007005const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7006 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007007 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007008 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007009 const IdentifierInfo *II = MacroDef->getName();
7010 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007011 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007012
7013 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7014}
7015
7016MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7017 const Token &Tok,
7018 CXTranslationUnit TU) {
7019 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007020 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007021 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007022 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007023
7024 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007025 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007026 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7027 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007028 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007029
7030 // Check that the token is inside the definition and not its argument list.
7031 SourceManager &SM = Unit->getSourceManager();
7032 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007033 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007034 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007035 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007036
7037 Preprocessor &PP = Unit->getPreprocessor();
7038 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7039 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007040 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007041
Alp Toker2d57cea2014-05-17 04:53:25 +00007042 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007043 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007044 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007045
7046 // Check that the identifier is not one of the macro arguments.
7047 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007048 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007049
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007050 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7051 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007052 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007053
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007054 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007055}
7056
7057MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7058 SourceLocation Loc,
7059 CXTranslationUnit TU) {
7060 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007061 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007062
7063 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007064 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007065 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007066 Preprocessor &PP = Unit->getPreprocessor();
7067 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007068 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007069 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7070 Token Tok;
7071 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007072 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007073
7074 return checkForMacroInMacroDefinition(MI, Tok, TU);
7075}
7076
Guy Benyei11169dd2012-12-18 14:30:41 +00007077extern "C" {
7078
7079CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007080 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007081}
7082
7083} // end: extern "C"
7084
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007085Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7086 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007087 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007088 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007089 if (Unit->isMainFileAST())
7090 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007091 return *this;
7092 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007093 } else {
7094 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007095 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007096 return *this;
7097}
7098
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007099Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7100 *this << FE->getName();
7101 return *this;
7102}
7103
7104Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7105 CXString cursorName = clang_getCursorDisplayName(cursor);
7106 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7107 clang_disposeString(cursorName);
7108 return *this;
7109}
7110
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007111Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7112 CXFile File;
7113 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007114 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007115 CXString FileName = clang_getFileName(File);
7116 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7117 clang_disposeString(FileName);
7118 return *this;
7119}
7120
7121Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7122 CXSourceLocation BLoc = clang_getRangeStart(range);
7123 CXSourceLocation ELoc = clang_getRangeEnd(range);
7124
7125 CXFile BFile;
7126 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007127 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007128
7129 CXFile EFile;
7130 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007131 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007132
7133 CXString BFileName = clang_getFileName(BFile);
7134 if (BFile == EFile) {
7135 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7136 BLine, BColumn, ELine, EColumn);
7137 } else {
7138 CXString EFileName = clang_getFileName(EFile);
7139 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7140 BLine, BColumn)
7141 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7142 ELine, EColumn);
7143 clang_disposeString(EFileName);
7144 }
7145 clang_disposeString(BFileName);
7146 return *this;
7147}
7148
7149Logger &cxindex::Logger::operator<<(CXString Str) {
7150 *this << clang_getCString(Str);
7151 return *this;
7152}
7153
7154Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7155 LogOS << Fmt;
7156 return *this;
7157}
7158
Chandler Carruth37ad2582014-06-27 15:14:39 +00007159static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7160
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007161cxindex::Logger::~Logger() {
7162 LogOS.flush();
7163
Chandler Carruth37ad2582014-06-27 15:14:39 +00007164 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007165
7166 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7167
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007168 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007169 OS << "[libclang:" << Name << ':';
7170
Alp Toker1a86ad22014-07-06 06:24:00 +00007171#ifdef USE_DARWIN_THREADS
7172 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007173 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7174 OS << tid << ':';
7175#endif
7176
7177 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7178 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7179 OS << Msg.str() << '\n';
7180
7181 if (Trace) {
7182 llvm::sys::PrintStackTrace(stderr);
7183 OS << "--------------------------------------------------\n";
7184 }
7185}