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