blob: 716f79ac33e2c8b89bc7c62f1cb46be1ced3432b [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
56#include "llvm/Support/Threading.h"
57#include "llvm/Support/Timer.h"
58#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000079 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 return D;
85}
86
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000087bool cxtu::isASTReadError(ASTUnit *AU) {
88 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89 DEnd = AU->stored_diag_end();
90 D != DEnd; ++D) {
91 if (D->getLevel() >= DiagnosticsEngine::Error &&
92 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93 diag::DiagCat_AST_Deserialization_Issue)
94 return true;
95 }
96 return false;
97}
98
Guy Benyei11169dd2012-12-18 14:30:41 +000099cxtu::CXTUOwner::~CXTUOwner() {
100 if (TU)
101 clang_disposeTranslationUnit(TU);
102}
103
104/// \brief Compare two source ranges to determine their relative position in
105/// the translation unit.
106static RangeComparisonResult RangeCompare(SourceManager &SM,
107 SourceRange R1,
108 SourceRange R2) {
109 assert(R1.isValid() && "First range is invalid?");
110 assert(R2.isValid() && "Second range is invalid?");
111 if (R1.getEnd() != R2.getBegin() &&
112 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113 return RangeBefore;
114 if (R2.getEnd() != R1.getBegin() &&
115 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116 return RangeAfter;
117 return RangeOverlap;
118}
119
120/// \brief Determine if a source location falls within, before, or after a
121/// a given source range.
122static RangeComparisonResult LocationCompare(SourceManager &SM,
123 SourceLocation L, SourceRange R) {
124 assert(R.isValid() && "First range is invalid?");
125 assert(L.isValid() && "Second range is invalid?");
126 if (L == R.getBegin() || L == R.getEnd())
127 return RangeOverlap;
128 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129 return RangeBefore;
130 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131 return RangeAfter;
132 return RangeOverlap;
133}
134
135/// \brief Translate a Clang source range into a CIndex source range.
136///
137/// Clang internally represents ranges where the end location points to the
138/// start of the token at the end. However, for external clients it is more
139/// useful to have a CXSourceRange be a proper half-open interval. This routine
140/// does the appropriate translation.
141CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142 const LangOptions &LangOpts,
143 const CharSourceRange &R) {
144 // We want the last character in this location, so we will adjust the
145 // location accordingly.
146 SourceLocation EndLoc = R.getEnd();
147 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148 EndLoc = SM.getExpansionRange(EndLoc).second;
149 if (R.isTokenRange() && !EndLoc.isInvalid()) {
150 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151 SM, LangOpts);
152 EndLoc = EndLoc.getLocWithOffset(Length);
153 }
154
Bill Wendlingeade3622013-01-23 08:25:41 +0000155 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000156 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 R.getBegin().getRawEncoding(),
158 EndLoc.getRawEncoding()
159 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000160 return Result;
161}
162
163//===----------------------------------------------------------------------===//
164// Cursor visitor.
165//===----------------------------------------------------------------------===//
166
167static SourceRange getRawCursorExtent(CXCursor C);
168static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169
170
171RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173}
174
175/// \brief Visit the given cursor and, if requested by the visitor,
176/// its children.
177///
178/// \param Cursor the cursor to visit.
179///
180/// \param CheckedRegionOfInterest if true, then the caller already checked
181/// that this cursor is within the region of interest.
182///
183/// \returns true if the visitation should be aborted, false if it
184/// should continue.
185bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186 if (clang_isInvalid(Cursor.kind))
187 return false;
188
189 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000190 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000191 if (!D) {
192 assert(0 && "Invalid declaration cursor");
193 return true; // abort.
194 }
195
196 // Ignore implicit declarations, unless it's an objc method because
197 // currently we should report implicit methods for properties when indexing.
198 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199 return false;
200 }
201
202 // If we have a range of interest, and this cursor doesn't intersect with it,
203 // we're done.
204 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205 SourceRange Range = getRawCursorExtent(Cursor);
206 if (Range.isInvalid() || CompareRegionOfInterest(Range))
207 return false;
208 }
209
210 switch (Visitor(Cursor, Parent, ClientData)) {
211 case CXChildVisit_Break:
212 return true;
213
214 case CXChildVisit_Continue:
215 return false;
216
217 case CXChildVisit_Recurse: {
218 bool ret = VisitChildren(Cursor);
219 if (PostChildrenVisitor)
220 if (PostChildrenVisitor(Cursor, ClientData))
221 return true;
222 return ret;
223 }
224 }
225
226 llvm_unreachable("Invalid CXChildVisitResult!");
227}
228
229static bool visitPreprocessedEntitiesInRange(SourceRange R,
230 PreprocessingRecord &PPRec,
231 CursorVisitor &Visitor) {
232 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233 FileID FID;
234
235 if (!Visitor.shouldVisitIncludedEntities()) {
236 // If the begin/end of the range lie in the same FileID, do the optimization
237 // where we skip preprocessed entities that do not come from the same FileID.
238 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240 FID = FileID();
241 }
242
243 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
244 Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
458
459 continue;
460 }
461
462 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
465
466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000572 if (MacroDefinition *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
667bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669 return Visit(TSInfo->getTypeLoc());
670
671 return false;
672}
673
674bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682 return VisitDeclContext(D);
683}
684
685bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686 ClassTemplateSpecializationDecl *D) {
687 bool ShouldVisitBody = false;
688 switch (D->getSpecializationKind()) {
689 case TSK_Undeclared:
690 case TSK_ImplicitInstantiation:
691 // Nothing to visit
692 return false;
693
694 case TSK_ExplicitInstantiationDeclaration:
695 case TSK_ExplicitInstantiationDefinition:
696 break;
697
698 case TSK_ExplicitSpecialization:
699 ShouldVisitBody = true;
700 break;
701 }
702
703 // Visit the template arguments used in the specialization.
704 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000706 if (TemplateSpecializationTypeLoc TSTLoc =
707 TL.getAs<TemplateSpecializationTypeLoc>()) {
708 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000710 return true;
711 }
712 }
713
714 if (ShouldVisitBody && VisitCXXRecordDecl(D))
715 return true;
716
717 return false;
718}
719
720bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721 ClassTemplatePartialSpecializationDecl *D) {
722 // FIXME: Visit the "outer" template parameter lists on the TagDecl
723 // before visiting these template parameters.
724 if (VisitTemplateParameters(D->getTemplateParameters()))
725 return true;
726
727 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000728 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732 return true;
733
734 return VisitCXXRecordDecl(D);
735}
736
737bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738 // Visit the default argument.
739 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741 if (Visit(DefArg->getTypeLoc()))
742 return true;
743
744 return false;
745}
746
747bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748 if (Expr *Init = D->getInitExpr())
749 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750 return false;
751}
752
753bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000754 unsigned NumParamList = DD->getNumTemplateParameterLists();
755 for (unsigned i = 0; i < NumParamList; i++) {
756 TemplateParameterList* Params = DD->getTemplateParameterList(i);
757 if (VisitTemplateParameters(Params))
758 return true;
759 }
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762 if (Visit(TSInfo->getTypeLoc()))
763 return true;
764
765 // Visit the nested-name-specifier, if present.
766 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
768 return true;
769
770 return false;
771}
772
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000773/// \brief Compare two base or member initializers based on their source order.
774static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775 CXXCtorInitializer *const *Y) {
776 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777}
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 unsigned NumParamList = ND->getNumTemplateParameterLists();
781 for (unsigned i = 0; i < NumParamList; i++) {
782 TemplateParameterList* Params = ND->getTemplateParameterList(i);
783 if (VisitTemplateParameters(Params))
784 return true;
785 }
786
Guy Benyei11169dd2012-12-18 14:30:41 +0000787 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788 // Visit the function declaration's syntactic components in the order
789 // written. This requires a bit of work.
790 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000791 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000792
793 // If we have a function declared directly (without the use of a typedef),
794 // visit just the return type. Otherwise, just visit the function's type
795 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000796 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000797 (!FTL && Visit(TL)))
798 return true;
799
800 // Visit the nested-name-specifier, if present.
801 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
803 return true;
804
805 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000806 if (!isa<CXXDestructorDecl>(ND))
807 if (VisitDeclarationNameInfo(ND->getNameInfo()))
808 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000809
810 // FIXME: Visit explicitly-specified template arguments!
811
812 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000813 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 return true;
815
Bill Wendling44426052012-12-20 19:22:21 +0000816 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 }
818
819 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821 // Find the initializers that were written in the source.
822 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 for (auto *I : Constructor->inits()) {
824 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 continue;
826
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 }
829
830 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000831 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832 &CompareCXXCtorInitializers);
833
Guy Benyei11169dd2012-12-18 14:30:41 +0000834 // Visit the initializers in source order
835 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836 CXXCtorInitializer *Init = WrittenInits[I];
837 if (Init->isAnyMemberInitializer()) {
838 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839 Init->getMemberLocation(), TU)))
840 return true;
841 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842 if (Visit(TInfo->getTypeLoc()))
843 return true;
844 }
845
846 // Visit the initializer value.
847 if (Expr *Initializer = Init->getInit())
848 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849 return true;
850 }
851 }
852
853 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854 return true;
855 }
856
857 return false;
858}
859
860bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861 if (VisitDeclaratorDecl(D))
862 return true;
863
864 if (Expr *BitWidth = D->getBitWidth())
865 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871 if (VisitDeclaratorDecl(D))
872 return true;
873
874 if (Expr *Init = D->getInit())
875 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876
877 return false;
878}
879
880bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881 if (VisitDeclaratorDecl(D))
882 return true;
883
884 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885 if (Expr *DefArg = D->getDefaultArgument())
886 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887
888 return false;
889}
890
891bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitFunctionDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901 // FIXME: Visit the "outer" template parameter lists on the TagDecl
902 // before visiting these template parameters.
903 if (VisitTemplateParameters(D->getTemplateParameters()))
904 return true;
905
906 return VisitCXXRecordDecl(D->getTemplatedDecl());
907}
908
909bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914 VisitTemplateArgumentLoc(D->getDefaultArgument()))
915 return true;
916
917 return false;
918}
919
920bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000921 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000922 if (Visit(TSInfo->getTypeLoc()))
923 return true;
924
Aaron Ballman43b68be2014-03-07 17:50:17 +0000925 for (const auto *P : ND->params()) {
926 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000927 return true;
928 }
929
930 if (ND->isThisDeclarationADefinition() &&
931 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
932 return true;
933
934 return false;
935}
936
937template <typename DeclIt>
938static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
939 SourceManager &SM, SourceLocation EndLoc,
940 SmallVectorImpl<Decl *> &Decls) {
941 DeclIt next = *DI_current;
942 while (++next != DE_current) {
943 Decl *D_next = *next;
944 if (!D_next)
945 break;
946 SourceLocation L = D_next->getLocStart();
947 if (!L.isValid())
948 break;
949 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
950 *DI_current = next;
951 Decls.push_back(D_next);
952 continue;
953 }
954 break;
955 }
956}
957
Guy Benyei11169dd2012-12-18 14:30:41 +0000958bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
959 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
960 // an @implementation can lexically contain Decls that are not properly
961 // nested in the AST. When we identify such cases, we need to retrofit
962 // this nesting here.
963 if (!DI_current && !FileDI_current)
964 return VisitDeclContext(D);
965
966 // Scan the Decls that immediately come after the container
967 // in the current DeclContext. If any fall within the
968 // container's lexical region, stash them into a vector
969 // for later processing.
970 SmallVector<Decl *, 24> DeclsInContainer;
971 SourceLocation EndLoc = D->getSourceRange().getEnd();
972 SourceManager &SM = AU->getSourceManager();
973 if (EndLoc.isValid()) {
974 if (DI_current) {
975 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
976 DeclsInContainer);
977 } else {
978 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
979 DeclsInContainer);
980 }
981 }
982
983 // The common case.
984 if (DeclsInContainer.empty())
985 return VisitDeclContext(D);
986
987 // Get all the Decls in the DeclContext, and sort them with the
988 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000989 for (auto *SubDecl : D->decls()) {
990 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
991 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000992 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000993 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000994 }
995
996 // Now sort the Decls so that they appear in lexical order.
997 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000998 [&SM](Decl *A, Decl *B) {
999 SourceLocation L_A = A->getLocStart();
1000 SourceLocation L_B = B->getLocStart();
1001 assert(L_A.isValid() && L_B.isValid());
1002 return SM.isBeforeInTranslationUnit(L_A, L_B);
1003 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001004
1005 // Now visit the decls.
1006 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1007 E = DeclsInContainer.end(); I != E; ++I) {
1008 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001009 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001010 if (!V.hasValue())
1011 continue;
1012 if (!V.getValue())
1013 return false;
1014 if (Visit(Cursor, true))
1015 return true;
1016 }
1017 return false;
1018}
1019
1020bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1021 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1022 TU)))
1023 return true;
1024
1025 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1026 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1027 E = ND->protocol_end(); I != E; ++I, ++PL)
1028 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1029 return true;
1030
1031 return VisitObjCContainerDecl(ND);
1032}
1033
1034bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1035 if (!PID->isThisDeclarationADefinition())
1036 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1037
1038 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1039 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1040 E = PID->protocol_end(); I != E; ++I, ++PL)
1041 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042 return true;
1043
1044 return VisitObjCContainerDecl(PID);
1045}
1046
1047bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1048 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1049 return true;
1050
1051 // FIXME: This implements a workaround with @property declarations also being
1052 // installed in the DeclContext for the @interface. Eventually this code
1053 // should be removed.
1054 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1055 if (!CDecl || !CDecl->IsClassExtension())
1056 return false;
1057
1058 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1059 if (!ID)
1060 return false;
1061
1062 IdentifierInfo *PropertyId = PD->getIdentifier();
1063 ObjCPropertyDecl *prevDecl =
1064 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1065
1066 if (!prevDecl)
1067 return false;
1068
1069 // Visit synthesized methods since they will be skipped when visiting
1070 // the @interface.
1071 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1072 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1073 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1074 return true;
1075
1076 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1077 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1078 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1079 return true;
1080
1081 return false;
1082}
1083
1084bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1085 if (!D->isThisDeclarationADefinition()) {
1086 // Forward declaration is treated like a reference.
1087 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1088 }
1089
1090 // Issue callbacks for super class.
1091 if (D->getSuperClass() &&
1092 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1093 D->getSuperClassLoc(),
1094 TU)))
1095 return true;
1096
1097 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1098 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1099 E = D->protocol_end(); I != E; ++I, ++PL)
1100 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1101 return true;
1102
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1107 return VisitObjCContainerDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1111 // 'ID' could be null when dealing with invalid code.
1112 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1113 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1114 return true;
1115
1116 return VisitObjCImplDecl(D);
1117}
1118
1119bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1120#if 0
1121 // Issue callbacks for super class.
1122 // FIXME: No source location information!
1123 if (D->getSuperClass() &&
1124 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125 D->getSuperClassLoc(),
1126 TU)))
1127 return true;
1128#endif
1129
1130 return VisitObjCImplDecl(D);
1131}
1132
1133bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1134 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1135 if (PD->isIvarNameSpecified())
1136 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1137
1138 return false;
1139}
1140
1141bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1142 return VisitDeclContext(D);
1143}
1144
1145bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1146 // Visit nested-name-specifier.
1147 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1148 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149 return true;
1150
1151 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1152 D->getTargetNameLoc(), TU));
1153}
1154
1155bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1156 // Visit nested-name-specifier.
1157 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1158 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1159 return true;
1160 }
1161
1162 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1163 return true;
1164
1165 return VisitDeclarationNameInfo(D->getNameInfo());
1166}
1167
1168bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1169 // Visit nested-name-specifier.
1170 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172 return true;
1173
1174 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1175 D->getIdentLocation(), TU));
1176}
1177
1178bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1179 // Visit nested-name-specifier.
1180 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1181 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1182 return true;
1183 }
1184
1185 return VisitDeclarationNameInfo(D->getNameInfo());
1186}
1187
1188bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1189 UnresolvedUsingTypenameDecl *D) {
1190 // Visit nested-name-specifier.
1191 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1192 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1193 return true;
1194
1195 return false;
1196}
1197
1198bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1199 switch (Name.getName().getNameKind()) {
1200 case clang::DeclarationName::Identifier:
1201 case clang::DeclarationName::CXXLiteralOperatorName:
1202 case clang::DeclarationName::CXXOperatorName:
1203 case clang::DeclarationName::CXXUsingDirective:
1204 return false;
1205
1206 case clang::DeclarationName::CXXConstructorName:
1207 case clang::DeclarationName::CXXDestructorName:
1208 case clang::DeclarationName::CXXConversionFunctionName:
1209 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1210 return Visit(TSInfo->getTypeLoc());
1211 return false;
1212
1213 case clang::DeclarationName::ObjCZeroArgSelector:
1214 case clang::DeclarationName::ObjCOneArgSelector:
1215 case clang::DeclarationName::ObjCMultiArgSelector:
1216 // FIXME: Per-identifier location info?
1217 return false;
1218 }
1219
1220 llvm_unreachable("Invalid DeclarationName::Kind!");
1221}
1222
1223bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1224 SourceRange Range) {
1225 // FIXME: This whole routine is a hack to work around the lack of proper
1226 // source information in nested-name-specifiers (PR5791). Since we do have
1227 // a beginning source location, we can visit the first component of the
1228 // nested-name-specifier, if it's a single-token component.
1229 if (!NNS)
1230 return false;
1231
1232 // Get the first component in the nested-name-specifier.
1233 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1234 NNS = Prefix;
1235
1236 switch (NNS->getKind()) {
1237 case NestedNameSpecifier::Namespace:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1239 TU));
1240
1241 case NestedNameSpecifier::NamespaceAlias:
1242 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1243 Range.getBegin(), TU));
1244
1245 case NestedNameSpecifier::TypeSpec: {
1246 // If the type has a form where we know that the beginning of the source
1247 // range matches up with a reference cursor. Visit the appropriate reference
1248 // cursor.
1249 const Type *T = NNS->getAsType();
1250 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1251 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1252 if (const TagType *Tag = dyn_cast<TagType>(T))
1253 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1254 if (const TemplateSpecializationType *TST
1255 = dyn_cast<TemplateSpecializationType>(T))
1256 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1257 break;
1258 }
1259
1260 case NestedNameSpecifier::TypeSpecWithTemplate:
1261 case NestedNameSpecifier::Global:
1262 case NestedNameSpecifier::Identifier:
1263 break;
1264 }
1265
1266 return false;
1267}
1268
1269bool
1270CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1271 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1272 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1273 Qualifiers.push_back(Qualifier);
1274
1275 while (!Qualifiers.empty()) {
1276 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1277 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1278 switch (NNS->getKind()) {
1279 case NestedNameSpecifier::Namespace:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::NamespaceAlias:
1288 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1289 Q.getLocalBeginLoc(),
1290 TU)))
1291 return true;
1292
1293 break;
1294
1295 case NestedNameSpecifier::TypeSpec:
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 if (Visit(Q.getTypeLoc()))
1298 return true;
1299
1300 break;
1301
1302 case NestedNameSpecifier::Global:
1303 case NestedNameSpecifier::Identifier:
1304 break;
1305 }
1306 }
1307
1308 return false;
1309}
1310
1311bool CursorVisitor::VisitTemplateParameters(
1312 const TemplateParameterList *Params) {
1313 if (!Params)
1314 return false;
1315
1316 for (TemplateParameterList::const_iterator P = Params->begin(),
1317 PEnd = Params->end();
1318 P != PEnd; ++P) {
1319 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1320 return true;
1321 }
1322
1323 return false;
1324}
1325
1326bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1327 switch (Name.getKind()) {
1328 case TemplateName::Template:
1329 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1330
1331 case TemplateName::OverloadedTemplate:
1332 // Visit the overloaded template set.
1333 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1334 return true;
1335
1336 return false;
1337
1338 case TemplateName::DependentTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return false;
1341
1342 case TemplateName::QualifiedTemplate:
1343 // FIXME: Visit nested-name-specifier.
1344 return Visit(MakeCursorTemplateRef(
1345 Name.getAsQualifiedTemplateName()->getDecl(),
1346 Loc, TU));
1347
1348 case TemplateName::SubstTemplateTemplateParm:
1349 return Visit(MakeCursorTemplateRef(
1350 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1351 Loc, TU));
1352
1353 case TemplateName::SubstTemplateTemplateParmPack:
1354 return Visit(MakeCursorTemplateRef(
1355 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1356 Loc, TU));
1357 }
1358
1359 llvm_unreachable("Invalid TemplateName::Kind!");
1360}
1361
1362bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1363 switch (TAL.getArgument().getKind()) {
1364 case TemplateArgument::Null:
1365 case TemplateArgument::Integral:
1366 case TemplateArgument::Pack:
1367 return false;
1368
1369 case TemplateArgument::Type:
1370 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1371 return Visit(TSInfo->getTypeLoc());
1372 return false;
1373
1374 case TemplateArgument::Declaration:
1375 if (Expr *E = TAL.getSourceDeclExpression())
1376 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1377 return false;
1378
1379 case TemplateArgument::NullPtr:
1380 if (Expr *E = TAL.getSourceNullPtrExpression())
1381 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1382 return false;
1383
1384 case TemplateArgument::Expression:
1385 if (Expr *E = TAL.getSourceExpression())
1386 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1387 return false;
1388
1389 case TemplateArgument::Template:
1390 case TemplateArgument::TemplateExpansion:
1391 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1392 return true;
1393
1394 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1395 TAL.getTemplateNameLoc());
1396 }
1397
1398 llvm_unreachable("Invalid TemplateArgument::Kind!");
1399}
1400
1401bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1402 return VisitDeclContext(D);
1403}
1404
1405bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1406 return Visit(TL.getUnqualifiedLoc());
1407}
1408
1409bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1410 ASTContext &Context = AU->getASTContext();
1411
1412 // Some builtin types (such as Objective-C's "id", "sel", and
1413 // "Class") have associated declarations. Create cursors for those.
1414 QualType VisitType;
1415 switch (TL.getTypePtr()->getKind()) {
1416
1417 case BuiltinType::Void:
1418 case BuiltinType::NullPtr:
1419 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001420 case BuiltinType::OCLImage1d:
1421 case BuiltinType::OCLImage1dArray:
1422 case BuiltinType::OCLImage1dBuffer:
1423 case BuiltinType::OCLImage2d:
1424 case BuiltinType::OCLImage2dArray:
1425 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001426 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001427 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001428#define BUILTIN_TYPE(Id, SingletonId)
1429#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1432#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1433#include "clang/AST/BuiltinTypes.def"
1434 break;
1435
1436 case BuiltinType::ObjCId:
1437 VisitType = Context.getObjCIdType();
1438 break;
1439
1440 case BuiltinType::ObjCClass:
1441 VisitType = Context.getObjCClassType();
1442 break;
1443
1444 case BuiltinType::ObjCSel:
1445 VisitType = Context.getObjCSelType();
1446 break;
1447 }
1448
1449 if (!VisitType.isNull()) {
1450 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1451 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1452 TU));
1453 }
1454
1455 return false;
1456}
1457
1458bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1463 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1464}
1465
1466bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1467 if (TL.isDefinition())
1468 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1469
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1474 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1475}
1476
1477bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1478 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1479 return true;
1480
1481 return false;
1482}
1483
1484bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1485 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1486 return true;
1487
1488 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1489 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1490 TU)))
1491 return true;
1492 }
1493
1494 return false;
1495}
1496
1497bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1502 return Visit(TL.getInnerLoc());
1503}
1504
1505bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1522 return Visit(TL.getPointeeLoc());
1523}
1524
1525bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1526 return Visit(TL.getModifiedLoc());
1527}
1528
1529bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1530 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001531 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 return true;
1533
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001534 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1535 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001536 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1537 return true;
1538
1539 return false;
1540}
1541
1542bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1543 if (Visit(TL.getElementLoc()))
1544 return true;
1545
1546 if (Expr *Size = TL.getSizeExpr())
1547 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1548
1549 return false;
1550}
1551
Reid Kleckner8a365022013-06-24 17:51:48 +00001552bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Reid Kleckner0503a872013-12-05 01:23:43 +00001556bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1557 return Visit(TL.getOriginalLoc());
1558}
1559
Guy Benyei11169dd2012-12-18 14:30:41 +00001560bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1561 TemplateSpecializationTypeLoc TL) {
1562 // Visit the template name.
1563 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1564 TL.getTemplateNameLoc()))
1565 return true;
1566
1567 // Visit the template arguments.
1568 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1569 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1570 return true;
1571
1572 return false;
1573}
1574
1575bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1576 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1577}
1578
1579bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1580 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1581 return Visit(TSInfo->getTypeLoc());
1582
1583 return false;
1584}
1585
1586bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1587 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1588 return Visit(TSInfo->getTypeLoc());
1589
1590 return false;
1591}
1592
1593bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1594 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1595 return true;
1596
1597 return false;
1598}
1599
1600bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1601 DependentTemplateSpecializationTypeLoc TL) {
1602 // Visit the nested-name-specifier, if there is one.
1603 if (TL.getQualifierLoc() &&
1604 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1605 return true;
1606
1607 // Visit the template arguments.
1608 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1609 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1610 return true;
1611
1612 return false;
1613}
1614
1615bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1616 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1617 return true;
1618
1619 return Visit(TL.getNamedTypeLoc());
1620}
1621
1622bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1623 return Visit(TL.getPatternLoc());
1624}
1625
1626bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1627 if (Expr *E = TL.getUnderlyingExpr())
1628 return Visit(MakeCXCursor(E, StmtParent, TU));
1629
1630 return false;
1631}
1632
1633bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1634 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1635}
1636
1637bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1638 return Visit(TL.getValueLoc());
1639}
1640
1641#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1642bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1643 return Visit##PARENT##Loc(TL); \
1644}
1645
1646DEFAULT_TYPELOC_IMPL(Complex, Type)
1647DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1648DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1650DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1651DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1652DEFAULT_TYPELOC_IMPL(Vector, Type)
1653DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1654DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1655DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1656DEFAULT_TYPELOC_IMPL(Record, TagType)
1657DEFAULT_TYPELOC_IMPL(Enum, TagType)
1658DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1659DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1660DEFAULT_TYPELOC_IMPL(Auto, Type)
1661
1662bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1663 // Visit the nested-name-specifier, if present.
1664 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1665 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1666 return true;
1667
1668 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001669 for (const auto &I : D->bases()) {
1670 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001671 return true;
1672 }
1673 }
1674
1675 return VisitTagDecl(D);
1676}
1677
1678bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001679 for (const auto *I : D->attrs())
1680 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001681 return true;
1682
1683 return false;
1684}
1685
1686//===----------------------------------------------------------------------===//
1687// Data-recursive visitor methods.
1688//===----------------------------------------------------------------------===//
1689
1690namespace {
1691#define DEF_JOB(NAME, DATA, KIND)\
1692class NAME : public VisitorJob {\
1693public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001694 NAME(const DATA *d, CXCursor parent) : \
1695 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001696 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001697 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001698};
1699
1700DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1701DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1702DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1703DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1704DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1705 ExplicitTemplateArgsVisitKind)
1706DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1707DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1708DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1709#undef DEF_JOB
1710
1711class DeclVisit : public VisitorJob {
1712public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001713 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001715 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 static bool classof(const VisitorJob *VJ) {
1717 return VJ->getKind() == DeclVisitKind;
1718 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001719 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001720 bool isFirst() const { return data[1] ? true : false; }
1721};
1722class TypeLocVisit : public VisitorJob {
1723public:
1724 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1725 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1726 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1727
1728 static bool classof(const VisitorJob *VJ) {
1729 return VJ->getKind() == TypeLocVisitKind;
1730 }
1731
1732 TypeLoc get() const {
1733 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001734 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 }
1736};
1737
1738class LabelRefVisit : public VisitorJob {
1739public:
1740 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1741 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1742 labelLoc.getPtrEncoding()) {}
1743
1744 static bool classof(const VisitorJob *VJ) {
1745 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1746 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 const LabelDecl *get() const {
1748 return static_cast<const LabelDecl *>(data[0]);
1749 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 SourceLocation getLoc() const {
1751 return SourceLocation::getFromPtrEncoding(data[1]); }
1752};
1753
1754class NestedNameSpecifierLocVisit : public VisitorJob {
1755public:
1756 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1757 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1758 Qualifier.getNestedNameSpecifier(),
1759 Qualifier.getOpaqueData()) { }
1760
1761 static bool classof(const VisitorJob *VJ) {
1762 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1763 }
1764
1765 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 return NestedNameSpecifierLoc(
1767 const_cast<NestedNameSpecifier *>(
1768 static_cast<const NestedNameSpecifier *>(data[0])),
1769 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 }
1771};
1772
1773class DeclarationNameInfoVisit : public VisitorJob {
1774public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001775 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001776 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001777 static bool classof(const VisitorJob *VJ) {
1778 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1779 }
1780 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001781 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 switch (S->getStmtClass()) {
1783 default:
1784 llvm_unreachable("Unhandled Stmt");
1785 case clang::Stmt::MSDependentExistsStmtClass:
1786 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1787 case Stmt::CXXDependentScopeMemberExprClass:
1788 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1789 case Stmt::DependentScopeDeclRefExprClass:
1790 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001791 case Stmt::OMPCriticalDirectiveClass:
1792 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 }
1794 }
1795};
1796class MemberRefVisit : public VisitorJob {
1797public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001799 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1800 L.getPtrEncoding()) {}
1801 static bool classof(const VisitorJob *VJ) {
1802 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1803 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804 const FieldDecl *get() const {
1805 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001806 }
1807 SourceLocation getLoc() const {
1808 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1809 }
1810};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001811class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001812 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001813 VisitorWorkList &WL;
1814 CXCursor Parent;
1815public:
1816 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1817 : WL(wl), Parent(parent) {}
1818
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001819 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1820 void VisitBlockExpr(const BlockExpr *B);
1821 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1822 void VisitCompoundStmt(const CompoundStmt *S);
1823 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1824 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1825 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1826 void VisitCXXNewExpr(const CXXNewExpr *E);
1827 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1828 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1829 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1830 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1831 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1832 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1833 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1834 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1835 void VisitDeclRefExpr(const DeclRefExpr *D);
1836 void VisitDeclStmt(const DeclStmt *S);
1837 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1838 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1839 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1840 void VisitForStmt(const ForStmt *FS);
1841 void VisitGotoStmt(const GotoStmt *GS);
1842 void VisitIfStmt(const IfStmt *If);
1843 void VisitInitListExpr(const InitListExpr *IE);
1844 void VisitMemberExpr(const MemberExpr *M);
1845 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1846 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1847 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1848 void VisitOverloadExpr(const OverloadExpr *E);
1849 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1850 void VisitStmt(const Stmt *S);
1851 void VisitSwitchStmt(const SwitchStmt *S);
1852 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001853 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1854 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1855 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1856 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1857 void VisitVAArgExpr(const VAArgExpr *E);
1858 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1859 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1860 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1861 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001862 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1863 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001864 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001865 void VisitOMPForDirective(const OMPForDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001866 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001867 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001868 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001869 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001870 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001871 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001872 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001873 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001874 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001875 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001876 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001877 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001878 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001879 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001880
Guy Benyei11169dd2012-12-18 14:30:41 +00001881private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001882 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001883 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1884 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1886 void AddStmt(const Stmt *S);
1887 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001888 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001890 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001891};
1892} // end anonyous namespace
1893
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 // 'S' should always be non-null, since it comes from the
1896 // statement we are visiting.
1897 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1898}
1899
1900void
1901EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1902 if (Qualifier)
1903 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1904}
1905
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 if (S)
1908 WL.push_back(StmtVisit(S, Parent));
1909}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001910void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001911 if (D)
1912 WL.push_back(DeclVisit(D, Parent, isFirst));
1913}
1914void EnqueueVisitor::
1915 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1916 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001918}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001919void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001920 if (D)
1921 WL.push_back(MemberRefVisit(D, L, Parent));
1922}
1923void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1924 if (TI)
1925 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1926 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001927void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001928 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001929 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001930 AddStmt(*Child);
1931 }
1932 if (size == WL.size())
1933 return;
1934 // Now reverse the entries we just added. This will match the DFS
1935 // ordering performed by the worklist.
1936 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1937 std::reverse(I, E);
1938}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001939namespace {
1940class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1941 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001942 /// \brief Process clauses with list of variables.
1943 template <typename T>
1944 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945public:
1946 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1947#define OPENMP_CLAUSE(Name, Class) \
1948 void Visit##Class(const Class *C);
1949#include "clang/Basic/OpenMPKinds.def"
1950};
1951
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001952void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1953 Visitor->AddStmt(C->getCondition());
1954}
1955
Alexey Bataev3778b602014-07-17 07:32:53 +00001956void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1957 Visitor->AddStmt(C->getCondition());
1958}
1959
Alexey Bataev568a8332014-03-06 06:15:19 +00001960void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1961 Visitor->AddStmt(C->getNumThreads());
1962}
1963
Alexey Bataev62c87d22014-03-21 04:51:18 +00001964void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1965 Visitor->AddStmt(C->getSafelen());
1966}
1967
Alexander Musman8bd31e62014-05-27 15:12:19 +00001968void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1969 Visitor->AddStmt(C->getNumForLoops());
1970}
1971
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001972void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001973
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001974void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1975
Alexey Bataev56dafe82014-06-20 07:16:17 +00001976void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1977 Visitor->AddStmt(C->getChunkSize());
1978}
1979
Alexey Bataev142e1fc2014-06-20 09:44:06 +00001980void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1981
Alexey Bataev236070f2014-06-20 11:19:47 +00001982void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1983
Alexey Bataev7aea99a2014-07-17 12:19:31 +00001984void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1985
Alexey Bataev74ba3a52014-07-17 12:47:03 +00001986void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1987
Alexey Bataevf98b00c2014-07-23 02:27:21 +00001988void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1989
Alexey Bataevdea47612014-07-23 07:46:59 +00001990void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1991
Alexey Bataev67a4f222014-07-23 10:25:33 +00001992void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
1993
Alexey Bataev459dec02014-07-24 06:46:57 +00001994void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
1995
Alexey Bataev82bad8b2014-07-24 08:55:34 +00001996void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
1997
Alexey Bataev756c1962013-09-24 03:17:45 +00001998template<typename T>
1999void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002000 for (const auto *I : Node->varlists())
2001 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00002002}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002003
2004void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002005 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002006}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002007void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2008 const OMPFirstprivateClause *C) {
2009 VisitOMPClauseList(C);
2010}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002011void OMPClauseEnqueue::VisitOMPLastprivateClause(
2012 const OMPLastprivateClause *C) {
2013 VisitOMPClauseList(C);
2014}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002015void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002016 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002017}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002018void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2019 VisitOMPClauseList(C);
2020}
Alexander Musman8dba6642014-04-22 13:09:42 +00002021void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2022 VisitOMPClauseList(C);
2023 Visitor->AddStmt(C->getStep());
2024}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002025void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2026 VisitOMPClauseList(C);
2027 Visitor->AddStmt(C->getAlignment());
2028}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002029void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2030 VisitOMPClauseList(C);
2031}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002032void
2033OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2034 VisitOMPClauseList(C);
2035}
Alexey Bataev6125da92014-07-21 11:26:11 +00002036void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2037 VisitOMPClauseList(C);
2038}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002039}
Alexey Bataev756c1962013-09-24 03:17:45 +00002040
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002041void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2042 unsigned size = WL.size();
2043 OMPClauseEnqueue Visitor(this);
2044 Visitor.Visit(S);
2045 if (size == WL.size())
2046 return;
2047 // Now reverse the entries we just added. This will match the DFS
2048 // ordering performed by the worklist.
2049 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2050 std::reverse(I, E);
2051}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002053 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2054}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 AddDecl(B->getBlockDecl());
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002059 EnqueueChildren(E);
2060 AddTypeLoc(E->getTypeSourceInfo());
2061}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2063 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002064 E = S->body_rend(); I != E; ++I) {
2065 AddStmt(*I);
2066 }
2067}
2068void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 AddStmt(S->getSubStmt());
2071 AddDeclarationNameInfo(S);
2072 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2073 AddNestedNameSpecifierLoc(QualifierLoc);
2074}
2075
2076void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2079 AddDeclarationNameInfo(E);
2080 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2081 AddNestedNameSpecifierLoc(QualifierLoc);
2082 if (!E->isImplicitAccess())
2083 AddStmt(E->getBase());
2084}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002085void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002086 // Enqueue the initializer , if any.
2087 AddStmt(E->getInitializer());
2088 // Enqueue the array size, if any.
2089 AddStmt(E->getArraySize());
2090 // Enqueue the allocated type.
2091 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2092 // Enqueue the placement arguments.
2093 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2094 AddStmt(E->getPlacementArg(I-1));
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2098 AddStmt(CE->getArg(I-1));
2099 AddStmt(CE->getCallee());
2100 AddStmt(CE->getArg(0));
2101}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2103 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002104 // Visit the name of the type being destroyed.
2105 AddTypeLoc(E->getDestroyedTypeInfo());
2106 // Visit the scope type that looks disturbingly like the nested-name-specifier
2107 // but isn't.
2108 AddTypeLoc(E->getScopeTypeInfo());
2109 // Visit the nested-name-specifier.
2110 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2111 AddNestedNameSpecifierLoc(QualifierLoc);
2112 // Visit base expression.
2113 AddStmt(E->getBase());
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2116 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 AddTypeLoc(E->getTypeSourceInfo());
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2120 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 EnqueueChildren(E);
2122 AddTypeLoc(E->getTypeSourceInfo());
2123}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 EnqueueChildren(E);
2126 if (E->isTypeOperand())
2127 AddTypeLoc(E->getTypeOperandSourceInfo());
2128}
2129
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2131 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 EnqueueChildren(E);
2133 AddTypeLoc(E->getTypeSourceInfo());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 EnqueueChildren(E);
2137 if (E->isTypeOperand())
2138 AddTypeLoc(E->getTypeOperandSourceInfo());
2139}
2140
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 EnqueueChildren(S);
2143 AddDecl(S->getExceptionDecl());
2144}
2145
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 if (DR->hasExplicitTemplateArgs()) {
2148 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2149 }
2150 WL.push_back(DeclRefExprParts(DR, Parent));
2151}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2153 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2155 AddDeclarationNameInfo(E);
2156 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 unsigned size = WL.size();
2160 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002161 for (const auto *D : S->decls()) {
2162 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002163 isFirst = false;
2164 }
2165 if (size == WL.size())
2166 return;
2167 // Now reverse the entries we just added. This will match the DFS
2168 // ordering performed by the worklist.
2169 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2170 std::reverse(I, E);
2171}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002172void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002173 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 D = E->designators_rbegin(), DEnd = E->designators_rend();
2176 D != DEnd; ++D) {
2177 if (D->isFieldDesignator()) {
2178 if (FieldDecl *Field = D->getField())
2179 AddMemberRef(Field, D->getFieldLoc());
2180 continue;
2181 }
2182 if (D->isArrayDesignator()) {
2183 AddStmt(E->getArrayIndex(*D));
2184 continue;
2185 }
2186 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2187 AddStmt(E->getArrayRangeEnd(*D));
2188 AddStmt(E->getArrayRangeStart(*D));
2189 }
2190}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 EnqueueChildren(E);
2193 AddTypeLoc(E->getTypeInfoAsWritten());
2194}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002196 AddStmt(FS->getBody());
2197 AddStmt(FS->getInc());
2198 AddStmt(FS->getCond());
2199 AddDecl(FS->getConditionVariable());
2200 AddStmt(FS->getInit());
2201}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2204}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddStmt(If->getElse());
2207 AddStmt(If->getThen());
2208 AddStmt(If->getCond());
2209 AddDecl(If->getConditionVariable());
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 // We care about the syntactic form of the initializer list, only.
2213 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2214 IE = Syntactic;
2215 EnqueueChildren(IE);
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 WL.push_back(MemberExprParts(M, Parent));
2219
2220 // If the base of the member access expression is an implicit 'this', don't
2221 // visit it.
2222 // FIXME: If we ever want to show these implicit accesses, this will be
2223 // unfortunate. However, clang_getCursor() relies on this behavior.
2224 if (!M->isImplicitAccess())
2225 AddStmt(M->getBase());
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 AddTypeLoc(E->getEncodedTypeSourceInfo());
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 EnqueueChildren(M);
2232 AddTypeLoc(M->getClassReceiverTypeInfo());
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 // Visit the components of the offsetof expression.
2236 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2237 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2238 const OffsetOfNode &Node = E->getComponent(I-1);
2239 switch (Node.getKind()) {
2240 case OffsetOfNode::Array:
2241 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2242 break;
2243 case OffsetOfNode::Field:
2244 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2245 break;
2246 case OffsetOfNode::Identifier:
2247 case OffsetOfNode::Base:
2248 continue;
2249 }
2250 }
2251 // Visit the type into which we're computing the offset.
2252 AddTypeLoc(E->getTypeSourceInfo());
2253}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002254void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002255 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2256 WL.push_back(OverloadExprParts(E, Parent));
2257}
2258void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 EnqueueChildren(E);
2261 if (E->isArgumentType())
2262 AddTypeLoc(E->getArgumentTypeInfo());
2263}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002264void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002265 EnqueueChildren(S);
2266}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 AddStmt(S->getBody());
2269 AddStmt(S->getCond());
2270 AddDecl(S->getConditionVariable());
2271}
2272
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 AddStmt(W->getBody());
2275 AddStmt(W->getCond());
2276 AddDecl(W->getConditionVariable());
2277}
2278
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 for (unsigned I = E->getNumArgs(); I > 0; --I)
2281 AddTypeLoc(E->getArg(I-1));
2282}
2283
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 AddTypeLoc(E->getQueriedTypeSourceInfo());
2286}
2287
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 EnqueueChildren(E);
2290}
2291
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002292void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002293 VisitOverloadExpr(U);
2294 if (!U->isImplicitAccess())
2295 AddStmt(U->getBase());
2296}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002297void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002298 AddStmt(E->getSubExpr());
2299 AddTypeLoc(E->getWrittenTypeInfo());
2300}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002301void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002302 WL.push_back(SizeOfPackExprParts(E, Parent));
2303}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002304void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002305 // If the opaque value has a source expression, just transparently
2306 // visit that. This is useful for (e.g.) pseudo-object expressions.
2307 if (Expr *SourceExpr = E->getSourceExpr())
2308 return Visit(SourceExpr);
2309}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002311 AddStmt(E->getBody());
2312 WL.push_back(LambdaExprParts(E, Parent));
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 // Treat the expression like its syntactic form.
2316 Visit(E->getSyntacticForm());
2317}
2318
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002319void EnqueueVisitor::VisitOMPExecutableDirective(
2320 const OMPExecutableDirective *D) {
2321 EnqueueChildren(D);
2322 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2323 E = D->clauses().end();
2324 I != E; ++I)
2325 EnqueueChildren(*I);
2326}
2327
2328void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2329 VisitOMPExecutableDirective(D);
2330}
2331
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002332void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2333 VisitOMPExecutableDirective(D);
2334}
2335
Alexey Bataevf29276e2014-06-18 04:14:57 +00002336void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2337 VisitOMPExecutableDirective(D);
2338}
2339
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002340void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2341 VisitOMPExecutableDirective(D);
2342}
2343
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002344void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2345 VisitOMPExecutableDirective(D);
2346}
2347
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002348void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2349 VisitOMPExecutableDirective(D);
2350}
2351
Alexander Musman80c22892014-07-17 08:54:58 +00002352void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2353 VisitOMPExecutableDirective(D);
2354}
2355
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002356void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2357 VisitOMPExecutableDirective(D);
2358 AddDeclarationNameInfo(D);
2359}
2360
Alexey Bataev4acb8592014-07-07 13:01:15 +00002361void
2362EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2363 VisitOMPExecutableDirective(D);
2364}
2365
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002366void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2367 const OMPParallelSectionsDirective *D) {
2368 VisitOMPExecutableDirective(D);
2369}
2370
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002371void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2372 VisitOMPExecutableDirective(D);
2373}
2374
Alexey Bataev68446b72014-07-18 07:47:19 +00002375void
2376EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2377 VisitOMPExecutableDirective(D);
2378}
2379
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002380void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2381 VisitOMPExecutableDirective(D);
2382}
2383
Alexey Bataev2df347a2014-07-18 10:17:07 +00002384void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2385 VisitOMPExecutableDirective(D);
2386}
2387
Alexey Bataev6125da92014-07-21 11:26:11 +00002388void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2389 VisitOMPExecutableDirective(D);
2390}
2391
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002392void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2393 VisitOMPExecutableDirective(D);
2394}
2395
Alexey Bataev0162e452014-07-22 10:10:35 +00002396void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2397 VisitOMPExecutableDirective(D);
2398}
2399
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002400void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002401 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2402}
2403
2404bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2405 if (RegionOfInterest.isValid()) {
2406 SourceRange Range = getRawCursorExtent(C);
2407 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2408 return false;
2409 }
2410 return true;
2411}
2412
2413bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2414 while (!WL.empty()) {
2415 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002416 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002417
2418 // Set the Parent field, then back to its old value once we're done.
2419 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2420
2421 switch (LI.getKind()) {
2422 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002423 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002424 if (!D)
2425 continue;
2426
2427 // For now, perform default visitation for Decls.
2428 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2429 cast<DeclVisit>(&LI)->isFirst())))
2430 return true;
2431
2432 continue;
2433 }
2434 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2435 const ASTTemplateArgumentListInfo *ArgList =
2436 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2437 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2438 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2439 Arg != ArgEnd; ++Arg) {
2440 if (VisitTemplateArgumentLoc(*Arg))
2441 return true;
2442 }
2443 continue;
2444 }
2445 case VisitorJob::TypeLocVisitKind: {
2446 // Perform default visitation for TypeLocs.
2447 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2448 return true;
2449 continue;
2450 }
2451 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002452 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002453 if (LabelStmt *stmt = LS->getStmt()) {
2454 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2455 TU))) {
2456 return true;
2457 }
2458 }
2459 continue;
2460 }
2461
2462 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2463 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2464 if (VisitNestedNameSpecifierLoc(V->get()))
2465 return true;
2466 continue;
2467 }
2468
2469 case VisitorJob::DeclarationNameInfoVisitKind: {
2470 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2471 ->get()))
2472 return true;
2473 continue;
2474 }
2475 case VisitorJob::MemberRefVisitKind: {
2476 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2477 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2478 return true;
2479 continue;
2480 }
2481 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002482 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002483 if (!S)
2484 continue;
2485
2486 // Update the current cursor.
2487 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2488 if (!IsInRegionOfInterest(Cursor))
2489 continue;
2490 switch (Visitor(Cursor, Parent, ClientData)) {
2491 case CXChildVisit_Break: return true;
2492 case CXChildVisit_Continue: break;
2493 case CXChildVisit_Recurse:
2494 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002495 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002496 EnqueueWorkList(WL, S);
2497 break;
2498 }
2499 continue;
2500 }
2501 case VisitorJob::MemberExprPartsKind: {
2502 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002503 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002504
2505 // Visit the nested-name-specifier
2506 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2507 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2508 return true;
2509
2510 // Visit the declaration name.
2511 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2512 return true;
2513
2514 // Visit the explicitly-specified template arguments, if any.
2515 if (M->hasExplicitTemplateArgs()) {
2516 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2517 *ArgEnd = Arg + M->getNumTemplateArgs();
2518 Arg != ArgEnd; ++Arg) {
2519 if (VisitTemplateArgumentLoc(*Arg))
2520 return true;
2521 }
2522 }
2523 continue;
2524 }
2525 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002526 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002527 // Visit nested-name-specifier, if present.
2528 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2529 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2530 return true;
2531 // Visit declaration name.
2532 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2533 return true;
2534 continue;
2535 }
2536 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002537 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002538 // Visit the nested-name-specifier.
2539 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2540 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2541 return true;
2542 // Visit the declaration name.
2543 if (VisitDeclarationNameInfo(O->getNameInfo()))
2544 return true;
2545 // Visit the overloaded declaration reference.
2546 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2547 return true;
2548 continue;
2549 }
2550 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002551 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002552 NamedDecl *Pack = E->getPack();
2553 if (isa<TemplateTypeParmDecl>(Pack)) {
2554 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2555 E->getPackLoc(), TU)))
2556 return true;
2557
2558 continue;
2559 }
2560
2561 if (isa<TemplateTemplateParmDecl>(Pack)) {
2562 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2563 E->getPackLoc(), TU)))
2564 return true;
2565
2566 continue;
2567 }
2568
2569 // Non-type template parameter packs and function parameter packs are
2570 // treated like DeclRefExpr cursors.
2571 continue;
2572 }
2573
2574 case VisitorJob::LambdaExprPartsKind: {
2575 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002576 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002577 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2578 CEnd = E->explicit_capture_end();
2579 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002580 // FIXME: Lambda init-captures.
2581 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002582 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002583
Guy Benyei11169dd2012-12-18 14:30:41 +00002584 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2585 C->getLocation(),
2586 TU)))
2587 return true;
2588 }
2589
2590 // Visit parameters and return type, if present.
2591 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2592 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2593 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2594 // Visit the whole type.
2595 if (Visit(TL))
2596 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002597 } else if (FunctionProtoTypeLoc Proto =
2598 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002599 if (E->hasExplicitParameters()) {
2600 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002601 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2602 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002603 return true;
2604 } else {
2605 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002606 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002607 return true;
2608 }
2609 }
2610 }
2611 break;
2612 }
2613
2614 case VisitorJob::PostChildrenVisitKind:
2615 if (PostChildrenVisitor(Parent, ClientData))
2616 return true;
2617 break;
2618 }
2619 }
2620 return false;
2621}
2622
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002623bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002624 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002625 if (!WorkListFreeList.empty()) {
2626 WL = WorkListFreeList.back();
2627 WL->clear();
2628 WorkListFreeList.pop_back();
2629 }
2630 else {
2631 WL = new VisitorWorkList();
2632 WorkListCache.push_back(WL);
2633 }
2634 EnqueueWorkList(*WL, S);
2635 bool result = RunVisitorWorkList(*WL);
2636 WorkListFreeList.push_back(WL);
2637 return result;
2638}
2639
2640namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002641typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002642RefNamePieces
2643buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2644 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2645 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002646 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2647 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2648 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2649
2650 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2651
2652 RefNamePieces Pieces;
2653
2654 if (WantQualifier && QLoc.isValid())
2655 Pieces.push_back(QLoc);
2656
2657 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2658 Pieces.push_back(NI.getLoc());
2659
2660 if (WantTemplateArgs && TemplateArgs)
2661 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2662 TemplateArgs->RAngleLoc));
2663
2664 if (Kind == DeclarationName::CXXOperatorName) {
2665 Pieces.push_back(SourceLocation::getFromRawEncoding(
2666 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2667 Pieces.push_back(SourceLocation::getFromRawEncoding(
2668 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2669 }
2670
2671 if (WantSinglePiece) {
2672 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2673 Pieces.clear();
2674 Pieces.push_back(R);
2675 }
2676
2677 return Pieces;
2678}
2679}
2680
2681//===----------------------------------------------------------------------===//
2682// Misc. API hooks.
2683//===----------------------------------------------------------------------===//
2684
Chad Rosier05c71aa2013-03-27 18:28:23 +00002685static void fatal_error_handler(void *user_data, const std::string& reason,
2686 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002687 // Write the result out to stderr avoiding errs() because raw_ostreams can
2688 // call report_fatal_error.
2689 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2690 ::abort();
2691}
2692
Chandler Carruth66660742014-06-27 16:37:27 +00002693namespace {
2694struct RegisterFatalErrorHandler {
2695 RegisterFatalErrorHandler() {
2696 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2697 }
2698};
2699}
2700
2701static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2702
Guy Benyei11169dd2012-12-18 14:30:41 +00002703extern "C" {
2704CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2705 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 // We use crash recovery to make some of our APIs more reliable, implicitly
2707 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002708 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2709 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002710
Chandler Carruth66660742014-06-27 16:37:27 +00002711 // Look through the managed static to trigger construction of the managed
2712 // static which registers our fatal error handler. This ensures it is only
2713 // registered once.
2714 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002715
2716 CIndexer *CIdxr = new CIndexer();
2717 if (excludeDeclarationsFromPCH)
2718 CIdxr->setOnlyLocalDecls();
2719 if (displayDiagnostics)
2720 CIdxr->setDisplayDiagnostics();
2721
2722 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2723 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2724 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2725 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2726 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2727 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2728
2729 return CIdxr;
2730}
2731
2732void clang_disposeIndex(CXIndex CIdx) {
2733 if (CIdx)
2734 delete static_cast<CIndexer *>(CIdx);
2735}
2736
2737void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2738 if (CIdx)
2739 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2740}
2741
2742unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2743 if (CIdx)
2744 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2745 return 0;
2746}
2747
2748void clang_toggleCrashRecovery(unsigned isEnabled) {
2749 if (isEnabled)
2750 llvm::CrashRecoveryContext::Enable();
2751 else
2752 llvm::CrashRecoveryContext::Disable();
2753}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002754
Guy Benyei11169dd2012-12-18 14:30:41 +00002755CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2756 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002757 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002758 enum CXErrorCode Result =
2759 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002760 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002761 assert((TU && Result == CXError_Success) ||
2762 (!TU && Result != CXError_Success));
2763 return TU;
2764}
2765
2766enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2767 const char *ast_filename,
2768 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002769 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002770 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002771
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002772 if (!CIdx || !ast_filename || !out_TU)
2773 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002774
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002775 LOG_FUNC_SECTION {
2776 *Log << ast_filename;
2777 }
2778
Guy Benyei11169dd2012-12-18 14:30:41 +00002779 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2780 FileSystemOptions FileSystemOpts;
2781
2782 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
David Blaikie6f7382d2014-08-10 19:08:04 +00002783 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2784 ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2785 /*CaptureDiagnostics=*/true,
2786 /*AllowPCHWithCompilerErrors=*/true,
2787 /*UserFilesAreVolatile=*/true);
2788 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002789 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002790}
2791
2792unsigned clang_defaultEditingTranslationUnitOptions() {
2793 return CXTranslationUnit_PrecompiledPreamble |
2794 CXTranslationUnit_CacheCompletionResults;
2795}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002796
Guy Benyei11169dd2012-12-18 14:30:41 +00002797CXTranslationUnit
2798clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2799 const char *source_filename,
2800 int num_command_line_args,
2801 const char * const *command_line_args,
2802 unsigned num_unsaved_files,
2803 struct CXUnsavedFile *unsaved_files) {
2804 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2805 return clang_parseTranslationUnit(CIdx, source_filename,
2806 command_line_args, num_command_line_args,
2807 unsaved_files, num_unsaved_files,
2808 Options);
2809}
2810
2811struct ParseTranslationUnitInfo {
2812 CXIndex CIdx;
2813 const char *source_filename;
2814 const char *const *command_line_args;
2815 int num_command_line_args;
Alp Toker9d85b182014-07-07 01:23:14 +00002816 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00002817 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002818 CXTranslationUnit *out_TU;
Alp Toker5c532982014-07-07 22:42:03 +00002819 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002820};
2821static void clang_parseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00002822 const ParseTranslationUnitInfo *PTUI =
2823 static_cast<ParseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00002824 CXIndex CIdx = PTUI->CIdx;
2825 const char *source_filename = PTUI->source_filename;
2826 const char * const *command_line_args = PTUI->command_line_args;
2827 int num_command_line_args = PTUI->num_command_line_args;
Guy Benyei11169dd2012-12-18 14:30:41 +00002828 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002829 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002830
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002831 // Set up the initial return values.
2832 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002833 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002834
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002835 // Check arguments.
Alp Toker9d85b182014-07-07 01:23:14 +00002836 if (!CIdx || !out_TU) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002837 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002838 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002839 }
2840
Guy Benyei11169dd2012-12-18 14:30:41 +00002841 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2842
2843 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2844 setThreadBackgroundPriority();
2845
2846 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2847 // FIXME: Add a flag for modules.
2848 TranslationUnitKind TUKind
2849 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002850 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002851 = options & CXTranslationUnit_CacheCompletionResults;
2852 bool IncludeBriefCommentsInCodeCompletion
2853 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2854 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2855 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2856
2857 // Configure the diagnostics.
2858 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002859 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002860
2861 // Recover resources if we crash before exiting this function.
2862 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2863 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00002864 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00002865
Ahmed Charlesb8984322014-03-07 20:03:18 +00002866 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2867 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002868
2869 // Recover resources if we crash before exiting this function.
2870 llvm::CrashRecoveryContextCleanupRegistrar<
2871 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2872
Alp Toker9d85b182014-07-07 01:23:14 +00002873 for (auto &UF : PTUI->unsaved_files) {
2874 llvm::MemoryBuffer *MB =
2875 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2876 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00002877 }
2878
Ahmed Charlesb8984322014-03-07 20:03:18 +00002879 std::unique_ptr<std::vector<const char *>> Args(
2880 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002881
2882 // Recover resources if we crash before exiting this method.
2883 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2884 ArgsCleanup(Args.get());
2885
2886 // Since the Clang C library is primarily used by batch tools dealing with
2887 // (often very broken) source code, where spell-checking can have a
2888 // significant negative impact on performance (particularly when
2889 // precompiled headers are involved), we disable it by default.
2890 // Only do this if we haven't found a spell-checking-related argument.
2891 bool FoundSpellCheckingArgument = false;
2892 for (int I = 0; I != num_command_line_args; ++I) {
2893 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2894 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2895 FoundSpellCheckingArgument = true;
2896 break;
2897 }
2898 }
2899 if (!FoundSpellCheckingArgument)
2900 Args->push_back("-fno-spell-checking");
2901
2902 Args->insert(Args->end(), command_line_args,
2903 command_line_args + num_command_line_args);
2904
2905 // The 'source_filename' argument is optional. If the caller does not
2906 // specify it then it is assumed that the source file is specified
2907 // in the actual argument list.
2908 // Put the source file after command_line_args otherwise if '-x' flag is
2909 // present it will be unused.
2910 if (source_filename)
2911 Args->push_back(source_filename);
2912
2913 // Do we need the detailed preprocessing record?
2914 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2915 Args->push_back("-Xclang");
2916 Args->push_back("-detailed-preprocessing-record");
2917 }
2918
2919 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002920 std::unique_ptr<ASTUnit> ErrUnit;
2921 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002922 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002923 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2924 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2925 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2926 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2927 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2928 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002929
2930 if (NumErrors != Diags->getClient()->getNumErrors()) {
2931 // Make sure to check that 'Unit' is non-NULL.
2932 if (CXXIdx->getDisplayDiagnostics())
2933 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2934 }
2935
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002936 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2937 PTUI->result = CXError_ASTReadError;
2938 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002939 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002940 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2941 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002942}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002943
2944CXTranslationUnit
2945clang_parseTranslationUnit(CXIndex CIdx,
2946 const char *source_filename,
2947 const char *const *command_line_args,
2948 int num_command_line_args,
2949 struct CXUnsavedFile *unsaved_files,
2950 unsigned num_unsaved_files,
2951 unsigned options) {
2952 CXTranslationUnit TU;
2953 enum CXErrorCode Result = clang_parseTranslationUnit2(
2954 CIdx, source_filename, command_line_args, num_command_line_args,
2955 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002956 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002957 assert((TU && Result == CXError_Success) ||
2958 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002959 return TU;
2960}
2961
2962enum CXErrorCode clang_parseTranslationUnit2(
2963 CXIndex CIdx,
2964 const char *source_filename,
2965 const char *const *command_line_args,
2966 int num_command_line_args,
2967 struct CXUnsavedFile *unsaved_files,
2968 unsigned num_unsaved_files,
2969 unsigned options,
2970 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002971 LOG_FUNC_SECTION {
2972 *Log << source_filename << ": ";
2973 for (int i = 0; i != num_command_line_args; ++i)
2974 *Log << command_line_args[i] << " ";
2975 }
2976
Alp Toker9d85b182014-07-07 01:23:14 +00002977 if (num_unsaved_files && !unsaved_files)
2978 return CXError_InvalidArguments;
2979
Alp Toker5c532982014-07-07 22:42:03 +00002980 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00002981 ParseTranslationUnitInfo PTUI = {
2982 CIdx,
2983 source_filename,
2984 command_line_args,
2985 num_command_line_args,
2986 llvm::makeArrayRef(unsaved_files, num_unsaved_files),
2987 options,
2988 out_TU,
Alp Toker5c532982014-07-07 22:42:03 +00002989 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00002990 llvm::CrashRecoveryContext CRC;
2991
2992 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2993 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2994 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2995 fprintf(stderr, " 'command_line_args' : [");
2996 for (int i = 0; i != num_command_line_args; ++i) {
2997 if (i)
2998 fprintf(stderr, ", ");
2999 fprintf(stderr, "'%s'", command_line_args[i]);
3000 }
3001 fprintf(stderr, "],\n");
3002 fprintf(stderr, " 'unsaved_files' : [");
3003 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3004 if (i)
3005 fprintf(stderr, ", ");
3006 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3007 unsaved_files[i].Length);
3008 }
3009 fprintf(stderr, "],\n");
3010 fprintf(stderr, " 'options' : %d,\n", options);
3011 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003012
3013 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003014 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003015 if (CXTranslationUnit *TU = PTUI.out_TU)
3016 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003017 }
Alp Toker5c532982014-07-07 22:42:03 +00003018
3019 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003020}
3021
3022unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3023 return CXSaveTranslationUnit_None;
3024}
3025
3026namespace {
3027
3028struct SaveTranslationUnitInfo {
3029 CXTranslationUnit TU;
3030 const char *FileName;
3031 unsigned options;
3032 CXSaveError result;
3033};
3034
3035}
3036
3037static void clang_saveTranslationUnit_Impl(void *UserData) {
3038 SaveTranslationUnitInfo *STUI =
3039 static_cast<SaveTranslationUnitInfo*>(UserData);
3040
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003041 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003042 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3043 setThreadBackgroundPriority();
3044
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003045 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00003046 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3047}
3048
3049int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3050 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003051 LOG_FUNC_SECTION {
3052 *Log << TU << ' ' << FileName;
3053 }
3054
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003055 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003056 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003057 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003058 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003059
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003060 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003061 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3062 if (!CXXUnit->hasSema())
3063 return CXSaveError_InvalidTU;
3064
3065 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3066
3067 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3068 getenv("LIBCLANG_NOTHREADS")) {
3069 clang_saveTranslationUnit_Impl(&STUI);
3070
3071 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3072 PrintLibclangResourceUsage(TU);
3073
3074 return STUI.result;
3075 }
3076
3077 // We have an AST that has invalid nodes due to compiler errors.
3078 // Use a crash recovery thread for protection.
3079
3080 llvm::CrashRecoveryContext CRC;
3081
3082 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3083 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3084 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3085 fprintf(stderr, " 'options' : %d,\n", options);
3086 fprintf(stderr, "}\n");
3087
3088 return CXSaveError_Unknown;
3089
3090 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3091 PrintLibclangResourceUsage(TU);
3092 }
3093
3094 return STUI.result;
3095}
3096
3097void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3098 if (CTUnit) {
3099 // If the translation unit has been marked as unsafe to free, just discard
3100 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003101 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3102 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 return;
3104
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003105 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003106 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3108 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003109 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003110 delete CTUnit;
3111 }
3112}
3113
3114unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3115 return CXReparse_None;
3116}
3117
3118struct ReparseTranslationUnitInfo {
3119 CXTranslationUnit TU;
Alp Toker9d85b182014-07-07 01:23:14 +00003120 ArrayRef<CXUnsavedFile> unsaved_files;
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 unsigned options;
Alp Toker5c532982014-07-07 22:42:03 +00003122 CXErrorCode &result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003123};
3124
3125static void clang_reparseTranslationUnit_Impl(void *UserData) {
Alp Toker9d85b182014-07-07 01:23:14 +00003126 const ReparseTranslationUnitInfo *RTUI =
3127 static_cast<ReparseTranslationUnitInfo *>(UserData);
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003129 unsigned options = RTUI->options;
3130 (void) options;
3131
3132 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003133 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003134 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003135 RTUI->result = CXError_InvalidArguments;
3136 return;
3137 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003138
3139 // Reset the associated diagnostics.
3140 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003141 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003142
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003143 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003144 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3145 setThreadBackgroundPriority();
3146
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003147 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003148 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003149
3150 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3151 new std::vector<ASTUnit::RemappedFile>());
3152
Guy Benyei11169dd2012-12-18 14:30:41 +00003153 // Recover resources if we crash before exiting this function.
3154 llvm::CrashRecoveryContextCleanupRegistrar<
3155 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003156
3157 for (auto &UF : RTUI->unsaved_files) {
3158 llvm::MemoryBuffer *MB =
3159 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3160 RemappedFiles->push_back(std::make_pair(UF.Filename, MB));
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003162
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003163 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003164 RTUI->result = CXError_Success;
3165 else if (isASTReadError(CXXUnit))
3166 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003167}
3168
3169int clang_reparseTranslationUnit(CXTranslationUnit TU,
3170 unsigned num_unsaved_files,
3171 struct CXUnsavedFile *unsaved_files,
3172 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003173 LOG_FUNC_SECTION {
3174 *Log << TU;
3175 }
3176
Alp Toker9d85b182014-07-07 01:23:14 +00003177 if (num_unsaved_files && !unsaved_files)
3178 return CXError_InvalidArguments;
3179
Alp Toker5c532982014-07-07 22:42:03 +00003180 CXErrorCode result = CXError_Failure;
Alp Toker9d85b182014-07-07 01:23:14 +00003181 ReparseTranslationUnitInfo RTUI = {
3182 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
Alp Toker5c532982014-07-07 22:42:03 +00003183 result};
Guy Benyei11169dd2012-12-18 14:30:41 +00003184
3185 if (getenv("LIBCLANG_NOTHREADS")) {
3186 clang_reparseTranslationUnit_Impl(&RTUI);
Alp Toker5c532982014-07-07 22:42:03 +00003187 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 }
3189
3190 llvm::CrashRecoveryContext CRC;
3191
3192 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3193 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003194 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003195 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3197 PrintLibclangResourceUsage(TU);
3198
Alp Toker5c532982014-07-07 22:42:03 +00003199 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003200}
3201
3202
3203CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003204 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003205 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003206 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003207 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003208
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003209 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003210 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003211}
3212
3213CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003214 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003215 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003216 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003217 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003218
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003219 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3221}
3222
3223} // end: extern "C"
3224
3225//===----------------------------------------------------------------------===//
3226// CXFile Operations.
3227//===----------------------------------------------------------------------===//
3228
3229extern "C" {
3230CXString clang_getFileName(CXFile SFile) {
3231 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003232 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003233
3234 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003235 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003236}
3237
3238time_t clang_getFileTime(CXFile SFile) {
3239 if (!SFile)
3240 return 0;
3241
3242 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3243 return FEnt->getModificationTime();
3244}
3245
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003246CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003247 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003248 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003249 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003250 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003251
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003252 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003253
3254 FileManager &FMgr = CXXUnit->getFileManager();
3255 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3256}
3257
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003258unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3259 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003260 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003261 LOG_BAD_TU(TU);
3262 return 0;
3263 }
3264
3265 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 return 0;
3267
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003268 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 FileEntry *FEnt = static_cast<FileEntry *>(file);
3270 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3271 .isFileMultipleIncludeGuarded(FEnt);
3272}
3273
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003274int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3275 if (!file || !outID)
3276 return 1;
3277
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003278 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003279 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3280 outID->data[0] = ID.getDevice();
3281 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003282 outID->data[2] = FEnt->getModificationTime();
3283 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003284}
3285
Guy Benyei11169dd2012-12-18 14:30:41 +00003286} // end: extern "C"
3287
3288//===----------------------------------------------------------------------===//
3289// CXCursor Operations.
3290//===----------------------------------------------------------------------===//
3291
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003292static const Decl *getDeclFromExpr(const Stmt *E) {
3293 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003294 return getDeclFromExpr(CE->getSubExpr());
3295
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003296 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003298 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003300 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003302 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003303 if (PRE->isExplicitProperty())
3304 return PRE->getExplicitProperty();
3305 // It could be messaging both getter and setter as in:
3306 // ++myobj.myprop;
3307 // in which case prefer to associate the setter since it is less obvious
3308 // from inspecting the source that the setter is going to get called.
3309 if (PRE->isMessagingSetter())
3310 return PRE->getImplicitPropertySetter();
3311 return PRE->getImplicitPropertyGetter();
3312 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003313 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003315 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 if (Expr *Src = OVE->getSourceExpr())
3317 return getDeclFromExpr(Src);
3318
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003319 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003320 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003321 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 if (!CE->isElidable())
3323 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003324 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 return OME->getMethodDecl();
3326
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003327 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003329 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3331 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003332 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3334 isa<ParmVarDecl>(SizeOfPack->getPack()))
3335 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003336
3337 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003338}
3339
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003340static SourceLocation getLocationFromExpr(const Expr *E) {
3341 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 return getLocationFromExpr(CE->getSubExpr());
3343
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003344 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003346 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003348 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003350 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003352 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003354 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 return PropRef->getLocation();
3356
3357 return E->getLocStart();
3358}
3359
3360extern "C" {
3361
3362unsigned clang_visitChildren(CXCursor parent,
3363 CXCursorVisitor visitor,
3364 CXClientData client_data) {
3365 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3366 /*VisitPreprocessorLast=*/false);
3367 return CursorVis.VisitChildren(parent);
3368}
3369
3370#ifndef __has_feature
3371#define __has_feature(x) 0
3372#endif
3373#if __has_feature(blocks)
3374typedef enum CXChildVisitResult
3375 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3376
3377static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3378 CXClientData client_data) {
3379 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3380 return block(cursor, parent);
3381}
3382#else
3383// If we are compiled with a compiler that doesn't have native blocks support,
3384// define and call the block manually, so the
3385typedef struct _CXChildVisitResult
3386{
3387 void *isa;
3388 int flags;
3389 int reserved;
3390 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3391 CXCursor);
3392} *CXCursorVisitorBlock;
3393
3394static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3395 CXClientData client_data) {
3396 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3397 return block->invoke(block, cursor, parent);
3398}
3399#endif
3400
3401
3402unsigned clang_visitChildrenWithBlock(CXCursor parent,
3403 CXCursorVisitorBlock block) {
3404 return clang_visitChildren(parent, visitWithBlock, block);
3405}
3406
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003407static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003409 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003410
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003411 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003413 if (const ObjCPropertyImplDecl *PropImpl =
3414 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003416 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003417
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003418 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003420 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003421
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003422 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 }
3424
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003425 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003426 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003427
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003428 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3430 // and returns different names. NamedDecl returns the class name and
3431 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003432 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003433
3434 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003435 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003436
3437 SmallString<1024> S;
3438 llvm::raw_svector_ostream os(S);
3439 ND->printName(os);
3440
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003441 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003442}
3443
3444CXString clang_getCursorSpelling(CXCursor C) {
3445 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003446 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003447
3448 if (clang_isReference(C.kind)) {
3449 switch (C.kind) {
3450 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003451 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003452 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 }
3454 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003455 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003456 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 }
3458 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003459 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003461 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 }
3463 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003464 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003465 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 }
3467 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003468 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003469 assert(Type && "Missing type decl");
3470
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003471 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 getAsString());
3473 }
3474 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003475 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 assert(Template && "Missing template decl");
3477
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003478 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 }
3480
3481 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003482 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 assert(NS && "Missing namespace decl");
3484
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003485 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 }
3487
3488 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003489 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 assert(Field && "Missing member decl");
3491
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003492 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 }
3494
3495 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003496 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 assert(Label && "Missing label");
3498
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003499 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 }
3501
3502 case CXCursor_OverloadedDeclRef: {
3503 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003504 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3505 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003506 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003507 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003509 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003510 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 OverloadedTemplateStorage *Ovl
3512 = Storage.get<OverloadedTemplateStorage*>();
3513 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003514 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003515 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003516 }
3517
3518 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003519 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 assert(Var && "Missing variable decl");
3521
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003522 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 }
3524
3525 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003526 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 }
3528 }
3529
3530 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003531 const Expr *E = getCursorExpr(C);
3532
3533 if (C.kind == CXCursor_ObjCStringLiteral ||
3534 C.kind == CXCursor_StringLiteral) {
3535 const StringLiteral *SLit;
3536 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3537 SLit = OSL->getString();
3538 } else {
3539 SLit = cast<StringLiteral>(E);
3540 }
3541 SmallString<256> Buf;
3542 llvm::raw_svector_ostream OS(Buf);
3543 SLit->outputString(OS);
3544 return cxstring::createDup(OS.str());
3545 }
3546
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003547 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 if (D)
3549 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003550 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 }
3552
3553 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003554 const Stmt *S = getCursorStmt(C);
3555 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003556 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003557
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003558 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 }
3560
3561 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003562 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 ->getNameStart());
3564
3565 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003566 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 ->getNameStart());
3568
3569 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003570 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003571
3572 if (clang_isDeclaration(C.kind))
3573 return getDeclSpelling(getCursorDecl(C));
3574
3575 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003576 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003577 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 }
3579
3580 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003581 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003582 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 }
3584
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003585 if (C.kind == CXCursor_PackedAttr) {
3586 return cxstring::createRef("packed");
3587 }
3588
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003589 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003590}
3591
3592CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3593 unsigned pieceIndex,
3594 unsigned options) {
3595 if (clang_Cursor_isNull(C))
3596 return clang_getNullRange();
3597
3598 ASTContext &Ctx = getCursorContext(C);
3599
3600 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003601 const Stmt *S = getCursorStmt(C);
3602 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 if (pieceIndex > 0)
3604 return clang_getNullRange();
3605 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3606 }
3607
3608 return clang_getNullRange();
3609 }
3610
3611 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003612 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3614 if (pieceIndex >= ME->getNumSelectorLocs())
3615 return clang_getNullRange();
3616 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3617 }
3618 }
3619
3620 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3621 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003622 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3624 if (pieceIndex >= MD->getNumSelectorLocs())
3625 return clang_getNullRange();
3626 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3627 }
3628 }
3629
3630 if (C.kind == CXCursor_ObjCCategoryDecl ||
3631 C.kind == CXCursor_ObjCCategoryImplDecl) {
3632 if (pieceIndex > 0)
3633 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003634 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3636 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003637 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3639 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3640 }
3641
3642 if (C.kind == CXCursor_ModuleImportDecl) {
3643 if (pieceIndex > 0)
3644 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003645 if (const ImportDecl *ImportD =
3646 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3648 if (!Locs.empty())
3649 return cxloc::translateSourceRange(Ctx,
3650 SourceRange(Locs.front(), Locs.back()));
3651 }
3652 return clang_getNullRange();
3653 }
3654
3655 // FIXME: A CXCursor_InclusionDirective should give the location of the
3656 // filename, but we don't keep track of this.
3657
3658 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3659 // but we don't keep track of this.
3660
3661 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3662 // but we don't keep track of this.
3663
3664 // Default handling, give the location of the cursor.
3665
3666 if (pieceIndex > 0)
3667 return clang_getNullRange();
3668
3669 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3670 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3671 return cxloc::translateSourceRange(Ctx, Loc);
3672}
3673
Eli Bendersky44a206f2014-07-31 18:04:56 +00003674CXString clang_Cursor_getMangling(CXCursor C) {
3675 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3676 return cxstring::createEmpty();
3677
Eli Bendersky44a206f2014-07-31 18:04:56 +00003678 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003679 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003680 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3681 return cxstring::createEmpty();
3682
Eli Bendersky79759592014-08-01 15:01:10 +00003683 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003684 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003685 ASTContext &Ctx = ND->getASTContext();
3686 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003687
Eli Bendersky79759592014-08-01 15:01:10 +00003688 std::string FrontendBuf;
3689 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3690 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003691
Eli Bendersky79759592014-08-01 15:01:10 +00003692 // Now apply backend mangling.
3693 std::unique_ptr<llvm::DataLayout> DL(
3694 new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3695 llvm::Mangler BackendMangler(DL.get());
3696
3697 std::string FinalBuf;
3698 llvm::raw_string_ostream FinalBufOS(FinalBuf);
3699 BackendMangler.getNameWithPrefix(FinalBufOS,
3700 llvm::Twine(FrontendBufOS.str()));
3701
3702 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003703}
3704
Guy Benyei11169dd2012-12-18 14:30:41 +00003705CXString clang_getCursorDisplayName(CXCursor C) {
3706 if (!clang_isDeclaration(C.kind))
3707 return clang_getCursorSpelling(C);
3708
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003709 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003711 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003712
3713 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003714 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 D = FunTmpl->getTemplatedDecl();
3716
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003717 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 SmallString<64> Str;
3719 llvm::raw_svector_ostream OS(Str);
3720 OS << *Function;
3721 if (Function->getPrimaryTemplate())
3722 OS << "<>";
3723 OS << "(";
3724 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3725 if (I)
3726 OS << ", ";
3727 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3728 }
3729
3730 if (Function->isVariadic()) {
3731 if (Function->getNumParams())
3732 OS << ", ";
3733 OS << "...";
3734 }
3735 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003736 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 }
3738
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003739 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 SmallString<64> Str;
3741 llvm::raw_svector_ostream OS(Str);
3742 OS << *ClassTemplate;
3743 OS << "<";
3744 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3745 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3746 if (I)
3747 OS << ", ";
3748
3749 NamedDecl *Param = Params->getParam(I);
3750 if (Param->getIdentifier()) {
3751 OS << Param->getIdentifier()->getName();
3752 continue;
3753 }
3754
3755 // There is no parameter name, which makes this tricky. Try to come up
3756 // with something useful that isn't too long.
3757 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3758 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3759 else if (NonTypeTemplateParmDecl *NTTP
3760 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3761 OS << NTTP->getType().getAsString(Policy);
3762 else
3763 OS << "template<...> class";
3764 }
3765
3766 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003767 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 }
3769
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003770 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3772 // If the type was explicitly written, use that.
3773 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003774 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003775
Benjamin Kramer9170e912013-02-22 15:46:01 +00003776 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 llvm::raw_svector_ostream OS(Str);
3778 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003779 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 ClassSpec->getTemplateArgs().data(),
3781 ClassSpec->getTemplateArgs().size(),
3782 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003783 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 }
3785
3786 return clang_getCursorSpelling(C);
3787}
3788
3789CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3790 switch (Kind) {
3791 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003919 case CXCursor_ObjCSelfExpr:
3920 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003929 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003930 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003931 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003932 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003934 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003936 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003937 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003938 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003940 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003942 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003944 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003946 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003948 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003950 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003952 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003954 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003956 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003958 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003960 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003962 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003964 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003966 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003968 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003970 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003972 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003974 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003976 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003978 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003980 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003982 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003984 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003986 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003987 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003988 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003990 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003992 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003994 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003996 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003997 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003998 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004009 case CXCursor_SEHLeaveStmt:
4010 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004039 case CXCursor_PackedAttr:
4040 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004041 case CXCursor_PureAttr:
4042 return cxstring::createRef("attribute(pure)");
4043 case CXCursor_ConstAttr:
4044 return cxstring::createRef("attribute(const)");
4045 case CXCursor_NoDuplicateAttr:
4046 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004047 case CXCursor_CUDAConstantAttr:
4048 return cxstring::createRef("attribute(constant)");
4049 case CXCursor_CUDADeviceAttr:
4050 return cxstring::createRef("attribute(device)");
4051 case CXCursor_CUDAGlobalAttr:
4052 return cxstring::createRef("attribute(global)");
4053 case CXCursor_CUDAHostAttr:
4054 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004055 case CXCursor_CUDASharedAttr:
4056 return cxstring::createRef("attribute(shared)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004105 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004106 return cxstring::createRef("OMPParallelDirective");
4107 case CXCursor_OMPSimdDirective:
4108 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004109 case CXCursor_OMPForDirective:
4110 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004111 case CXCursor_OMPSectionsDirective:
4112 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004113 case CXCursor_OMPSectionDirective:
4114 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004115 case CXCursor_OMPSingleDirective:
4116 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004117 case CXCursor_OMPMasterDirective:
4118 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004119 case CXCursor_OMPCriticalDirective:
4120 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004121 case CXCursor_OMPParallelForDirective:
4122 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004123 case CXCursor_OMPParallelSectionsDirective:
4124 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004125 case CXCursor_OMPTaskDirective:
4126 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004127 case CXCursor_OMPTaskyieldDirective:
4128 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004129 case CXCursor_OMPBarrierDirective:
4130 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004131 case CXCursor_OMPTaskwaitDirective:
4132 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004133 case CXCursor_OMPFlushDirective:
4134 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004135 case CXCursor_OMPOrderedDirective:
4136 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004137 case CXCursor_OMPAtomicDirective:
4138 return cxstring::createRef("OMPAtomicDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 }
4140
4141 llvm_unreachable("Unhandled CXCursorKind");
4142}
4143
4144struct GetCursorData {
4145 SourceLocation TokenBeginLoc;
4146 bool PointsAtMacroArgExpansion;
4147 bool VisitedObjCPropertyImplDecl;
4148 SourceLocation VisitedDeclaratorDeclStartLoc;
4149 CXCursor &BestCursor;
4150
4151 GetCursorData(SourceManager &SM,
4152 SourceLocation tokenBegin, CXCursor &outputCursor)
4153 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4154 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4155 VisitedObjCPropertyImplDecl = false;
4156 }
4157};
4158
4159static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4160 CXCursor parent,
4161 CXClientData client_data) {
4162 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4163 CXCursor *BestCursor = &Data->BestCursor;
4164
4165 // If we point inside a macro argument we should provide info of what the
4166 // token is so use the actual cursor, don't replace it with a macro expansion
4167 // cursor.
4168 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4169 return CXChildVisit_Recurse;
4170
4171 if (clang_isDeclaration(cursor.kind)) {
4172 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004173 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4175 if (MD->isImplicit())
4176 return CXChildVisit_Break;
4177
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004178 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4180 // Check that when we have multiple @class references in the same line,
4181 // that later ones do not override the previous ones.
4182 // If we have:
4183 // @class Foo, Bar;
4184 // source ranges for both start at '@', so 'Bar' will end up overriding
4185 // 'Foo' even though the cursor location was at 'Foo'.
4186 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4187 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004188 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4190 if (PrevID != ID &&
4191 !PrevID->isThisDeclarationADefinition() &&
4192 !ID->isThisDeclarationADefinition())
4193 return CXChildVisit_Break;
4194 }
4195
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004196 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4198 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4199 // Check that when we have multiple declarators in the same line,
4200 // that later ones do not override the previous ones.
4201 // If we have:
4202 // int Foo, Bar;
4203 // source ranges for both start at 'int', so 'Bar' will end up overriding
4204 // 'Foo' even though the cursor location was at 'Foo'.
4205 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4206 return CXChildVisit_Break;
4207 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4208
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004209 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4211 (void)PropImp;
4212 // Check that when we have multiple @synthesize in the same line,
4213 // that later ones do not override the previous ones.
4214 // If we have:
4215 // @synthesize Foo, Bar;
4216 // source ranges for both start at '@', so 'Bar' will end up overriding
4217 // 'Foo' even though the cursor location was at 'Foo'.
4218 if (Data->VisitedObjCPropertyImplDecl)
4219 return CXChildVisit_Break;
4220 Data->VisitedObjCPropertyImplDecl = true;
4221 }
4222 }
4223
4224 if (clang_isExpression(cursor.kind) &&
4225 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004226 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 // Avoid having the cursor of an expression replace the declaration cursor
4228 // when the expression source range overlaps the declaration range.
4229 // This can happen for C++ constructor expressions whose range generally
4230 // include the variable declaration, e.g.:
4231 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4232 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4233 D->getLocation() == Data->TokenBeginLoc)
4234 return CXChildVisit_Break;
4235 }
4236 }
4237
4238 // If our current best cursor is the construction of a temporary object,
4239 // don't replace that cursor with a type reference, because we want
4240 // clang_getCursor() to point at the constructor.
4241 if (clang_isExpression(BestCursor->kind) &&
4242 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4243 cursor.kind == CXCursor_TypeRef) {
4244 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4245 // as having the actual point on the type reference.
4246 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4247 return CXChildVisit_Recurse;
4248 }
4249
4250 *BestCursor = cursor;
4251 return CXChildVisit_Recurse;
4252}
4253
4254CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004255 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004256 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004258 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004259
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004260 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004261 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4262
4263 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4264 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4265
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004266 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 CXFile SearchFile;
4268 unsigned SearchLine, SearchColumn;
4269 CXFile ResultFile;
4270 unsigned ResultLine, ResultColumn;
4271 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4272 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4273 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004274
4275 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4276 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004277 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004278 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 SearchFileName = clang_getFileName(SearchFile);
4280 ResultFileName = clang_getFileName(ResultFile);
4281 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4282 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004283 *Log << llvm::format("(%s:%d:%d) = %s",
4284 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4285 clang_getCString(KindSpelling))
4286 << llvm::format("(%s:%d:%d):%s%s",
4287 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4288 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 clang_disposeString(SearchFileName);
4290 clang_disposeString(ResultFileName);
4291 clang_disposeString(KindSpelling);
4292 clang_disposeString(USR);
4293
4294 CXCursor Definition = clang_getCursorDefinition(Result);
4295 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4296 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4297 CXString DefinitionKindSpelling
4298 = clang_getCursorKindSpelling(Definition.kind);
4299 CXFile DefinitionFile;
4300 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004301 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004302 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004304 *Log << llvm::format(" -> %s(%s:%d:%d)",
4305 clang_getCString(DefinitionKindSpelling),
4306 clang_getCString(DefinitionFileName),
4307 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 clang_disposeString(DefinitionFileName);
4309 clang_disposeString(DefinitionKindSpelling);
4310 }
4311 }
4312
4313 return Result;
4314}
4315
4316CXCursor clang_getNullCursor(void) {
4317 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4318}
4319
4320unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004321 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4322 // can't set consistently. For example, when visiting a DeclStmt we will set
4323 // it but we don't set it on the result of clang_getCursorDefinition for
4324 // a reference of the same declaration.
4325 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4326 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4327 // to provide that kind of info.
4328 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004329 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004330 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004331 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004332
Guy Benyei11169dd2012-12-18 14:30:41 +00004333 return X == Y;
4334}
4335
4336unsigned clang_hashCursor(CXCursor C) {
4337 unsigned Index = 0;
4338 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4339 Index = 1;
4340
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004341 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004342 std::make_pair(C.kind, C.data[Index]));
4343}
4344
4345unsigned clang_isInvalid(enum CXCursorKind K) {
4346 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4347}
4348
4349unsigned clang_isDeclaration(enum CXCursorKind K) {
4350 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4351 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4352}
4353
4354unsigned clang_isReference(enum CXCursorKind K) {
4355 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4356}
4357
4358unsigned clang_isExpression(enum CXCursorKind K) {
4359 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4360}
4361
4362unsigned clang_isStatement(enum CXCursorKind K) {
4363 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4364}
4365
4366unsigned clang_isAttribute(enum CXCursorKind K) {
4367 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4368}
4369
4370unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4371 return K == CXCursor_TranslationUnit;
4372}
4373
4374unsigned clang_isPreprocessing(enum CXCursorKind K) {
4375 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4376}
4377
4378unsigned clang_isUnexposed(enum CXCursorKind K) {
4379 switch (K) {
4380 case CXCursor_UnexposedDecl:
4381 case CXCursor_UnexposedExpr:
4382 case CXCursor_UnexposedStmt:
4383 case CXCursor_UnexposedAttr:
4384 return true;
4385 default:
4386 return false;
4387 }
4388}
4389
4390CXCursorKind clang_getCursorKind(CXCursor C) {
4391 return C.kind;
4392}
4393
4394CXSourceLocation clang_getCursorLocation(CXCursor C) {
4395 if (clang_isReference(C.kind)) {
4396 switch (C.kind) {
4397 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004398 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 = getCursorObjCSuperClassRef(C);
4400 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4401 }
4402
4403 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004404 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 = getCursorObjCProtocolRef(C);
4406 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4407 }
4408
4409 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004410 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004411 = getCursorObjCClassRef(C);
4412 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4413 }
4414
4415 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004416 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004417 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4418 }
4419
4420 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004421 std::pair<const TemplateDecl *, SourceLocation> P =
4422 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004423 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4424 }
4425
4426 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004427 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4429 }
4430
4431 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004432 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004433 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4434 }
4435
4436 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004437 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4439 }
4440
4441 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004442 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 if (!BaseSpec)
4444 return clang_getNullLocation();
4445
4446 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4447 return cxloc::translateSourceLocation(getCursorContext(C),
4448 TSInfo->getTypeLoc().getBeginLoc());
4449
4450 return cxloc::translateSourceLocation(getCursorContext(C),
4451 BaseSpec->getLocStart());
4452 }
4453
4454 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004455 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004456 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4457 }
4458
4459 case CXCursor_OverloadedDeclRef:
4460 return cxloc::translateSourceLocation(getCursorContext(C),
4461 getCursorOverloadedDeclRef(C).second);
4462
4463 default:
4464 // FIXME: Need a way to enumerate all non-reference cases.
4465 llvm_unreachable("Missed a reference kind");
4466 }
4467 }
4468
4469 if (clang_isExpression(C.kind))
4470 return cxloc::translateSourceLocation(getCursorContext(C),
4471 getLocationFromExpr(getCursorExpr(C)));
4472
4473 if (clang_isStatement(C.kind))
4474 return cxloc::translateSourceLocation(getCursorContext(C),
4475 getCursorStmt(C)->getLocStart());
4476
4477 if (C.kind == CXCursor_PreprocessingDirective) {
4478 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4479 return cxloc::translateSourceLocation(getCursorContext(C), L);
4480 }
4481
4482 if (C.kind == CXCursor_MacroExpansion) {
4483 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004484 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 return cxloc::translateSourceLocation(getCursorContext(C), L);
4486 }
4487
4488 if (C.kind == CXCursor_MacroDefinition) {
4489 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4490 return cxloc::translateSourceLocation(getCursorContext(C), L);
4491 }
4492
4493 if (C.kind == CXCursor_InclusionDirective) {
4494 SourceLocation L
4495 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4496 return cxloc::translateSourceLocation(getCursorContext(C), L);
4497 }
4498
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004499 if (clang_isAttribute(C.kind)) {
4500 SourceLocation L
4501 = cxcursor::getCursorAttr(C)->getLocation();
4502 return cxloc::translateSourceLocation(getCursorContext(C), L);
4503 }
4504
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 if (!clang_isDeclaration(C.kind))
4506 return clang_getNullLocation();
4507
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004508 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 if (!D)
4510 return clang_getNullLocation();
4511
4512 SourceLocation Loc = D->getLocation();
4513 // FIXME: Multiple variables declared in a single declaration
4514 // currently lack the information needed to correctly determine their
4515 // ranges when accounting for the type-specifier. We use context
4516 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4517 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004518 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 if (!cxcursor::isFirstInDeclGroup(C))
4520 Loc = VD->getLocation();
4521 }
4522
4523 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004524 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 Loc = MD->getSelectorStartLoc();
4526
4527 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4528}
4529
4530} // end extern "C"
4531
4532CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4533 assert(TU);
4534
4535 // Guard against an invalid SourceLocation, or we may assert in one
4536 // of the following calls.
4537 if (SLoc.isInvalid())
4538 return clang_getNullCursor();
4539
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004540 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004541
4542 // Translate the given source location to make it point at the beginning of
4543 // the token under the cursor.
4544 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4545 CXXUnit->getASTContext().getLangOpts());
4546
4547 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4548 if (SLoc.isValid()) {
4549 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4550 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4551 /*VisitPreprocessorLast=*/true,
4552 /*VisitIncludedEntities=*/false,
4553 SourceLocation(SLoc));
4554 CursorVis.visitFileRegion();
4555 }
4556
4557 return Result;
4558}
4559
4560static SourceRange getRawCursorExtent(CXCursor C) {
4561 if (clang_isReference(C.kind)) {
4562 switch (C.kind) {
4563 case CXCursor_ObjCSuperClassRef:
4564 return getCursorObjCSuperClassRef(C).second;
4565
4566 case CXCursor_ObjCProtocolRef:
4567 return getCursorObjCProtocolRef(C).second;
4568
4569 case CXCursor_ObjCClassRef:
4570 return getCursorObjCClassRef(C).second;
4571
4572 case CXCursor_TypeRef:
4573 return getCursorTypeRef(C).second;
4574
4575 case CXCursor_TemplateRef:
4576 return getCursorTemplateRef(C).second;
4577
4578 case CXCursor_NamespaceRef:
4579 return getCursorNamespaceRef(C).second;
4580
4581 case CXCursor_MemberRef:
4582 return getCursorMemberRef(C).second;
4583
4584 case CXCursor_CXXBaseSpecifier:
4585 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4586
4587 case CXCursor_LabelRef:
4588 return getCursorLabelRef(C).second;
4589
4590 case CXCursor_OverloadedDeclRef:
4591 return getCursorOverloadedDeclRef(C).second;
4592
4593 case CXCursor_VariableRef:
4594 return getCursorVariableRef(C).second;
4595
4596 default:
4597 // FIXME: Need a way to enumerate all non-reference cases.
4598 llvm_unreachable("Missed a reference kind");
4599 }
4600 }
4601
4602 if (clang_isExpression(C.kind))
4603 return getCursorExpr(C)->getSourceRange();
4604
4605 if (clang_isStatement(C.kind))
4606 return getCursorStmt(C)->getSourceRange();
4607
4608 if (clang_isAttribute(C.kind))
4609 return getCursorAttr(C)->getRange();
4610
4611 if (C.kind == CXCursor_PreprocessingDirective)
4612 return cxcursor::getCursorPreprocessingDirective(C);
4613
4614 if (C.kind == CXCursor_MacroExpansion) {
4615 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004616 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 return TU->mapRangeFromPreamble(Range);
4618 }
4619
4620 if (C.kind == CXCursor_MacroDefinition) {
4621 ASTUnit *TU = getCursorASTUnit(C);
4622 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4623 return TU->mapRangeFromPreamble(Range);
4624 }
4625
4626 if (C.kind == CXCursor_InclusionDirective) {
4627 ASTUnit *TU = getCursorASTUnit(C);
4628 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4629 return TU->mapRangeFromPreamble(Range);
4630 }
4631
4632 if (C.kind == CXCursor_TranslationUnit) {
4633 ASTUnit *TU = getCursorASTUnit(C);
4634 FileID MainID = TU->getSourceManager().getMainFileID();
4635 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4636 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4637 return SourceRange(Start, End);
4638 }
4639
4640 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004641 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004642 if (!D)
4643 return SourceRange();
4644
4645 SourceRange R = D->getSourceRange();
4646 // FIXME: Multiple variables declared in a single declaration
4647 // currently lack the information needed to correctly determine their
4648 // ranges when accounting for the type-specifier. We use context
4649 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4650 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004651 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 if (!cxcursor::isFirstInDeclGroup(C))
4653 R.setBegin(VD->getLocation());
4654 }
4655 return R;
4656 }
4657 return SourceRange();
4658}
4659
4660/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4661/// the decl-specifier-seq for declarations.
4662static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4663 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004664 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 if (!D)
4666 return SourceRange();
4667
4668 SourceRange R = D->getSourceRange();
4669
4670 // Adjust the start of the location for declarations preceded by
4671 // declaration specifiers.
4672 SourceLocation StartLoc;
4673 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4674 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4675 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004676 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4678 StartLoc = TI->getTypeLoc().getLocStart();
4679 }
4680
4681 if (StartLoc.isValid() && R.getBegin().isValid() &&
4682 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4683 R.setBegin(StartLoc);
4684
4685 // FIXME: Multiple variables declared in a single declaration
4686 // currently lack the information needed to correctly determine their
4687 // ranges when accounting for the type-specifier. We use context
4688 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4689 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004690 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 if (!cxcursor::isFirstInDeclGroup(C))
4692 R.setBegin(VD->getLocation());
4693 }
4694
4695 return R;
4696 }
4697
4698 return getRawCursorExtent(C);
4699}
4700
4701extern "C" {
4702
4703CXSourceRange clang_getCursorExtent(CXCursor C) {
4704 SourceRange R = getRawCursorExtent(C);
4705 if (R.isInvalid())
4706 return clang_getNullRange();
4707
4708 return cxloc::translateSourceRange(getCursorContext(C), R);
4709}
4710
4711CXCursor clang_getCursorReferenced(CXCursor C) {
4712 if (clang_isInvalid(C.kind))
4713 return clang_getNullCursor();
4714
4715 CXTranslationUnit tu = getCursorTU(C);
4716 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004717 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 if (!D)
4719 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004720 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004722 if (const ObjCPropertyImplDecl *PropImpl =
4723 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004724 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4725 return MakeCXCursor(Property, tu);
4726
4727 return C;
4728 }
4729
4730 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004731 const Expr *E = getCursorExpr(C);
4732 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 if (D) {
4734 CXCursor declCursor = MakeCXCursor(D, tu);
4735 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4736 declCursor);
4737 return declCursor;
4738 }
4739
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004740 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 return MakeCursorOverloadedDeclRef(Ovl, tu);
4742
4743 return clang_getNullCursor();
4744 }
4745
4746 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004747 const Stmt *S = getCursorStmt(C);
4748 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 if (LabelDecl *label = Goto->getLabel())
4750 if (LabelStmt *labelS = label->getStmt())
4751 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4752
4753 return clang_getNullCursor();
4754 }
4755
4756 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004757 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004758 return MakeMacroDefinitionCursor(Def, tu);
4759 }
4760
4761 if (!clang_isReference(C.kind))
4762 return clang_getNullCursor();
4763
4764 switch (C.kind) {
4765 case CXCursor_ObjCSuperClassRef:
4766 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4767
4768 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004769 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4770 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 return MakeCXCursor(Def, tu);
4772
4773 return MakeCXCursor(Prot, tu);
4774 }
4775
4776 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004777 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4778 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 return MakeCXCursor(Def, tu);
4780
4781 return MakeCXCursor(Class, tu);
4782 }
4783
4784 case CXCursor_TypeRef:
4785 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4786
4787 case CXCursor_TemplateRef:
4788 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4789
4790 case CXCursor_NamespaceRef:
4791 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4792
4793 case CXCursor_MemberRef:
4794 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4795
4796 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004797 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004798 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4799 tu ));
4800 }
4801
4802 case CXCursor_LabelRef:
4803 // FIXME: We end up faking the "parent" declaration here because we
4804 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004805 return MakeCXCursor(getCursorLabelRef(C).first,
4806 cxtu::getASTUnit(tu)->getASTContext()
4807 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004808 tu);
4809
4810 case CXCursor_OverloadedDeclRef:
4811 return C;
4812
4813 case CXCursor_VariableRef:
4814 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4815
4816 default:
4817 // We would prefer to enumerate all non-reference cursor kinds here.
4818 llvm_unreachable("Unhandled reference cursor kind");
4819 }
4820}
4821
4822CXCursor clang_getCursorDefinition(CXCursor C) {
4823 if (clang_isInvalid(C.kind))
4824 return clang_getNullCursor();
4825
4826 CXTranslationUnit TU = getCursorTU(C);
4827
4828 bool WasReference = false;
4829 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4830 C = clang_getCursorReferenced(C);
4831 WasReference = true;
4832 }
4833
4834 if (C.kind == CXCursor_MacroExpansion)
4835 return clang_getCursorReferenced(C);
4836
4837 if (!clang_isDeclaration(C.kind))
4838 return clang_getNullCursor();
4839
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004840 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004841 if (!D)
4842 return clang_getNullCursor();
4843
4844 switch (D->getKind()) {
4845 // Declaration kinds that don't really separate the notions of
4846 // declaration and definition.
4847 case Decl::Namespace:
4848 case Decl::Typedef:
4849 case Decl::TypeAlias:
4850 case Decl::TypeAliasTemplate:
4851 case Decl::TemplateTypeParm:
4852 case Decl::EnumConstant:
4853 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004854 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004855 case Decl::IndirectField:
4856 case Decl::ObjCIvar:
4857 case Decl::ObjCAtDefsField:
4858 case Decl::ImplicitParam:
4859 case Decl::ParmVar:
4860 case Decl::NonTypeTemplateParm:
4861 case Decl::TemplateTemplateParm:
4862 case Decl::ObjCCategoryImpl:
4863 case Decl::ObjCImplementation:
4864 case Decl::AccessSpec:
4865 case Decl::LinkageSpec:
4866 case Decl::ObjCPropertyImpl:
4867 case Decl::FileScopeAsm:
4868 case Decl::StaticAssert:
4869 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004870 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004871 case Decl::Label: // FIXME: Is this right??
4872 case Decl::ClassScopeFunctionSpecialization:
4873 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004874 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004875 return C;
4876
4877 // Declaration kinds that don't make any sense here, but are
4878 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004879 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004880 case Decl::TranslationUnit:
4881 break;
4882
4883 // Declaration kinds for which the definition is not resolvable.
4884 case Decl::UnresolvedUsingTypename:
4885 case Decl::UnresolvedUsingValue:
4886 break;
4887
4888 case Decl::UsingDirective:
4889 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4890 TU);
4891
4892 case Decl::NamespaceAlias:
4893 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4894
4895 case Decl::Enum:
4896 case Decl::Record:
4897 case Decl::CXXRecord:
4898 case Decl::ClassTemplateSpecialization:
4899 case Decl::ClassTemplatePartialSpecialization:
4900 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4901 return MakeCXCursor(Def, TU);
4902 return clang_getNullCursor();
4903
4904 case Decl::Function:
4905 case Decl::CXXMethod:
4906 case Decl::CXXConstructor:
4907 case Decl::CXXDestructor:
4908 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004909 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004910 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004911 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004912 return clang_getNullCursor();
4913 }
4914
Larisse Voufo39a1e502013-08-06 01:03:05 +00004915 case Decl::Var:
4916 case Decl::VarTemplateSpecialization:
4917 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004918 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004919 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 return MakeCXCursor(Def, TU);
4921 return clang_getNullCursor();
4922 }
4923
4924 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004925 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004926 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4927 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4928 return clang_getNullCursor();
4929 }
4930
4931 case Decl::ClassTemplate: {
4932 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4933 ->getDefinition())
4934 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4935 TU);
4936 return clang_getNullCursor();
4937 }
4938
Larisse Voufo39a1e502013-08-06 01:03:05 +00004939 case Decl::VarTemplate: {
4940 if (VarDecl *Def =
4941 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4942 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4943 return clang_getNullCursor();
4944 }
4945
Guy Benyei11169dd2012-12-18 14:30:41 +00004946 case Decl::Using:
4947 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4948 D->getLocation(), TU);
4949
4950 case Decl::UsingShadow:
4951 return clang_getCursorDefinition(
4952 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4953 TU));
4954
4955 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004956 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004957 if (Method->isThisDeclarationADefinition())
4958 return C;
4959
4960 // Dig out the method definition in the associated
4961 // @implementation, if we have it.
4962 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004963 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004964 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4965 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4966 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4967 Method->isInstanceMethod()))
4968 if (Def->isThisDeclarationADefinition())
4969 return MakeCXCursor(Def, TU);
4970
4971 return clang_getNullCursor();
4972 }
4973
4974 case Decl::ObjCCategory:
4975 if (ObjCCategoryImplDecl *Impl
4976 = cast<ObjCCategoryDecl>(D)->getImplementation())
4977 return MakeCXCursor(Impl, TU);
4978 return clang_getNullCursor();
4979
4980 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004981 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004982 return MakeCXCursor(Def, TU);
4983 return clang_getNullCursor();
4984
4985 case Decl::ObjCInterface: {
4986 // There are two notions of a "definition" for an Objective-C
4987 // class: the interface and its implementation. When we resolved a
4988 // reference to an Objective-C class, produce the @interface as
4989 // the definition; when we were provided with the interface,
4990 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004991 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004993 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 return MakeCXCursor(Def, TU);
4995 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4996 return MakeCXCursor(Impl, TU);
4997 return clang_getNullCursor();
4998 }
4999
5000 case Decl::ObjCProperty:
5001 // FIXME: We don't really know where to find the
5002 // ObjCPropertyImplDecls that implement this property.
5003 return clang_getNullCursor();
5004
5005 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005006 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005008 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005009 return MakeCXCursor(Def, TU);
5010
5011 return clang_getNullCursor();
5012
5013 case Decl::Friend:
5014 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5015 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5016 return clang_getNullCursor();
5017
5018 case Decl::FriendTemplate:
5019 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5020 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5021 return clang_getNullCursor();
5022 }
5023
5024 return clang_getNullCursor();
5025}
5026
5027unsigned clang_isCursorDefinition(CXCursor C) {
5028 if (!clang_isDeclaration(C.kind))
5029 return 0;
5030
5031 return clang_getCursorDefinition(C) == C;
5032}
5033
5034CXCursor clang_getCanonicalCursor(CXCursor C) {
5035 if (!clang_isDeclaration(C.kind))
5036 return C;
5037
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005038 if (const Decl *D = getCursorDecl(C)) {
5039 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005040 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5041 return MakeCXCursor(CatD, getCursorTU(C));
5042
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005043 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5044 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 return MakeCXCursor(IFD, getCursorTU(C));
5046
5047 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5048 }
5049
5050 return C;
5051}
5052
5053int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5054 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5055}
5056
5057unsigned clang_getNumOverloadedDecls(CXCursor C) {
5058 if (C.kind != CXCursor_OverloadedDeclRef)
5059 return 0;
5060
5061 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005062 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005063 return E->getNumDecls();
5064
5065 if (OverloadedTemplateStorage *S
5066 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5067 return S->size();
5068
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005069 const Decl *D = Storage.get<const Decl *>();
5070 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005071 return Using->shadow_size();
5072
5073 return 0;
5074}
5075
5076CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5077 if (cursor.kind != CXCursor_OverloadedDeclRef)
5078 return clang_getNullCursor();
5079
5080 if (index >= clang_getNumOverloadedDecls(cursor))
5081 return clang_getNullCursor();
5082
5083 CXTranslationUnit TU = getCursorTU(cursor);
5084 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005085 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005086 return MakeCXCursor(E->decls_begin()[index], TU);
5087
5088 if (OverloadedTemplateStorage *S
5089 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5090 return MakeCXCursor(S->begin()[index], TU);
5091
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005092 const Decl *D = Storage.get<const Decl *>();
5093 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 // FIXME: This is, unfortunately, linear time.
5095 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5096 std::advance(Pos, index);
5097 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5098 }
5099
5100 return clang_getNullCursor();
5101}
5102
5103void clang_getDefinitionSpellingAndExtent(CXCursor C,
5104 const char **startBuf,
5105 const char **endBuf,
5106 unsigned *startLine,
5107 unsigned *startColumn,
5108 unsigned *endLine,
5109 unsigned *endColumn) {
5110 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005111 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005112 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5113
5114 SourceManager &SM = FD->getASTContext().getSourceManager();
5115 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5116 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5117 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5118 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5119 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5120 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5121}
5122
5123
5124CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5125 unsigned PieceIndex) {
5126 RefNamePieces Pieces;
5127
5128 switch (C.kind) {
5129 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005130 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5132 E->getQualifierLoc().getSourceRange());
5133 break;
5134
5135 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005136 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005137 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5138 E->getQualifierLoc().getSourceRange(),
5139 E->getOptionalExplicitTemplateArgs());
5140 break;
5141
5142 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005143 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005145 const Expr *Callee = OCE->getCallee();
5146 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005147 Callee = ICE->getSubExpr();
5148
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005149 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5151 DRE->getQualifierLoc().getSourceRange());
5152 }
5153 break;
5154
5155 default:
5156 break;
5157 }
5158
5159 if (Pieces.empty()) {
5160 if (PieceIndex == 0)
5161 return clang_getCursorExtent(C);
5162 } else if (PieceIndex < Pieces.size()) {
5163 SourceRange R = Pieces[PieceIndex];
5164 if (R.isValid())
5165 return cxloc::translateSourceRange(getCursorContext(C), R);
5166 }
5167
5168 return clang_getNullRange();
5169}
5170
5171void clang_enableStackTraces(void) {
5172 llvm::sys::PrintStackTraceOnErrorSignal();
5173}
5174
5175void clang_executeOnThread(void (*fn)(void*), void *user_data,
5176 unsigned stack_size) {
5177 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5178}
5179
5180} // end: extern "C"
5181
5182//===----------------------------------------------------------------------===//
5183// Token-based Operations.
5184//===----------------------------------------------------------------------===//
5185
5186/* CXToken layout:
5187 * int_data[0]: a CXTokenKind
5188 * int_data[1]: starting token location
5189 * int_data[2]: token length
5190 * int_data[3]: reserved
5191 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5192 * otherwise unused.
5193 */
5194extern "C" {
5195
5196CXTokenKind clang_getTokenKind(CXToken CXTok) {
5197 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5198}
5199
5200CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5201 switch (clang_getTokenKind(CXTok)) {
5202 case CXToken_Identifier:
5203 case CXToken_Keyword:
5204 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005205 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 ->getNameStart());
5207
5208 case CXToken_Literal: {
5209 // We have stashed the starting pointer in the ptr_data field. Use it.
5210 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005211 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 }
5213
5214 case CXToken_Punctuation:
5215 case CXToken_Comment:
5216 break;
5217 }
5218
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005219 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005220 LOG_BAD_TU(TU);
5221 return cxstring::createEmpty();
5222 }
5223
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 // We have to find the starting buffer pointer the hard way, by
5225 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005226 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005228 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005229
5230 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5231 std::pair<FileID, unsigned> LocInfo
5232 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5233 bool Invalid = false;
5234 StringRef Buffer
5235 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5236 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005237 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005238
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005239 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005240}
5241
5242CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005243 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005244 LOG_BAD_TU(TU);
5245 return clang_getNullLocation();
5246 }
5247
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005248 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005249 if (!CXXUnit)
5250 return clang_getNullLocation();
5251
5252 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5253 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5254}
5255
5256CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005257 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005258 LOG_BAD_TU(TU);
5259 return clang_getNullRange();
5260 }
5261
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005262 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005263 if (!CXXUnit)
5264 return clang_getNullRange();
5265
5266 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5267 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5268}
5269
5270static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5271 SmallVectorImpl<CXToken> &CXTokens) {
5272 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5273 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005274 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005276 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005277
5278 // Cannot tokenize across files.
5279 if (BeginLocInfo.first != EndLocInfo.first)
5280 return;
5281
5282 // Create a lexer
5283 bool Invalid = false;
5284 StringRef Buffer
5285 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5286 if (Invalid)
5287 return;
5288
5289 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5290 CXXUnit->getASTContext().getLangOpts(),
5291 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5292 Lex.SetCommentRetentionState(true);
5293
5294 // Lex tokens until we hit the end of the range.
5295 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5296 Token Tok;
5297 bool previousWasAt = false;
5298 do {
5299 // Lex the next token
5300 Lex.LexFromRawLexer(Tok);
5301 if (Tok.is(tok::eof))
5302 break;
5303
5304 // Initialize the CXToken.
5305 CXToken CXTok;
5306
5307 // - Common fields
5308 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5309 CXTok.int_data[2] = Tok.getLength();
5310 CXTok.int_data[3] = 0;
5311
5312 // - Kind-specific fields
5313 if (Tok.isLiteral()) {
5314 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005315 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 } else if (Tok.is(tok::raw_identifier)) {
5317 // Lookup the identifier to determine whether we have a keyword.
5318 IdentifierInfo *II
5319 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5320
5321 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5322 CXTok.int_data[0] = CXToken_Keyword;
5323 }
5324 else {
5325 CXTok.int_data[0] = Tok.is(tok::identifier)
5326 ? CXToken_Identifier
5327 : CXToken_Keyword;
5328 }
5329 CXTok.ptr_data = II;
5330 } else if (Tok.is(tok::comment)) {
5331 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005332 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 } else {
5334 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005335 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 }
5337 CXTokens.push_back(CXTok);
5338 previousWasAt = Tok.is(tok::at);
5339 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5340}
5341
5342void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5343 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005344 LOG_FUNC_SECTION {
5345 *Log << TU << ' ' << Range;
5346 }
5347
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005349 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 if (NumTokens)
5351 *NumTokens = 0;
5352
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005353 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005354 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005355 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005356 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005357
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005358 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005359 if (!CXXUnit || !Tokens || !NumTokens)
5360 return;
5361
5362 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5363
5364 SourceRange R = cxloc::translateCXSourceRange(Range);
5365 if (R.isInvalid())
5366 return;
5367
5368 SmallVector<CXToken, 32> CXTokens;
5369 getTokens(CXXUnit, R, CXTokens);
5370
5371 if (CXTokens.empty())
5372 return;
5373
5374 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5375 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5376 *NumTokens = CXTokens.size();
5377}
5378
5379void clang_disposeTokens(CXTranslationUnit TU,
5380 CXToken *Tokens, unsigned NumTokens) {
5381 free(Tokens);
5382}
5383
5384} // end: extern "C"
5385
5386//===----------------------------------------------------------------------===//
5387// Token annotation APIs.
5388//===----------------------------------------------------------------------===//
5389
Guy Benyei11169dd2012-12-18 14:30:41 +00005390static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5391 CXCursor parent,
5392 CXClientData client_data);
5393static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5394 CXClientData client_data);
5395
5396namespace {
5397class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005398 CXToken *Tokens;
5399 CXCursor *Cursors;
5400 unsigned NumTokens;
5401 unsigned TokIdx;
5402 unsigned PreprocessingTokIdx;
5403 CursorVisitor AnnotateVis;
5404 SourceManager &SrcMgr;
5405 bool HasContextSensitiveKeywords;
5406
5407 struct PostChildrenInfo {
5408 CXCursor Cursor;
5409 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005410 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005411 unsigned BeforeChildrenTokenIdx;
5412 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005413 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005414
5415 CXToken &getTok(unsigned Idx) {
5416 assert(Idx < NumTokens);
5417 return Tokens[Idx];
5418 }
5419 const CXToken &getTok(unsigned Idx) const {
5420 assert(Idx < NumTokens);
5421 return Tokens[Idx];
5422 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 bool MoreTokens() const { return TokIdx < NumTokens; }
5424 unsigned NextToken() const { return TokIdx; }
5425 void AdvanceToken() { ++TokIdx; }
5426 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005427 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005428 }
5429 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005430 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 }
5432 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005433 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005434 }
5435
5436 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005437 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005438 SourceRange);
5439
5440public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005441 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005442 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005443 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005445 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005446 AnnotateTokensVisitor, this,
5447 /*VisitPreprocessorLast=*/true,
5448 /*VisitIncludedEntities=*/false,
5449 RegionOfInterest,
5450 /*VisitDeclsOnly=*/false,
5451 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005452 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 HasContextSensitiveKeywords(false) { }
5454
5455 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5456 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5457 bool postVisitChildren(CXCursor cursor);
5458 void AnnotateTokens();
5459
5460 /// \brief Determine whether the annotator saw any cursors that have
5461 /// context-sensitive keywords.
5462 bool hasContextSensitiveKeywords() const {
5463 return HasContextSensitiveKeywords;
5464 }
5465
5466 ~AnnotateTokensWorker() {
5467 assert(PostChildrenInfos.empty());
5468 }
5469};
5470}
5471
5472void AnnotateTokensWorker::AnnotateTokens() {
5473 // Walk the AST within the region of interest, annotating tokens
5474 // along the way.
5475 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005476}
Guy Benyei11169dd2012-12-18 14:30:41 +00005477
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005478static inline void updateCursorAnnotation(CXCursor &Cursor,
5479 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005480 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005482 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005483}
5484
5485/// \brief It annotates and advances tokens with a cursor until the comparison
5486//// between the cursor location and the source range is the same as
5487/// \arg compResult.
5488///
5489/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5490/// Pass RangeOverlap to annotate tokens inside a range.
5491void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5492 RangeComparisonResult compResult,
5493 SourceRange range) {
5494 while (MoreTokens()) {
5495 const unsigned I = NextToken();
5496 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005497 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5498 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005499
5500 SourceLocation TokLoc = GetTokenLoc(I);
5501 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005502 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005503 AdvanceToken();
5504 continue;
5505 }
5506 break;
5507 }
5508}
5509
5510/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005511/// \returns true if it advanced beyond all macro tokens, false otherwise.
5512bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005513 CXCursor updateC,
5514 RangeComparisonResult compResult,
5515 SourceRange range) {
5516 assert(MoreTokens());
5517 assert(isFunctionMacroToken(NextToken()) &&
5518 "Should be called only for macro arg tokens");
5519
5520 // This works differently than annotateAndAdvanceTokens; because expanded
5521 // macro arguments can have arbitrary translation-unit source order, we do not
5522 // advance the token index one by one until a token fails the range test.
5523 // We only advance once past all of the macro arg tokens if all of them
5524 // pass the range test. If one of them fails we keep the token index pointing
5525 // at the start of the macro arg tokens so that the failing token will be
5526 // annotated by a subsequent annotation try.
5527
5528 bool atLeastOneCompFail = false;
5529
5530 unsigned I = NextToken();
5531 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5532 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5533 if (TokLoc.isFileID())
5534 continue; // not macro arg token, it's parens or comma.
5535 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5536 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5537 Cursors[I] = updateC;
5538 } else
5539 atLeastOneCompFail = true;
5540 }
5541
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005542 if (atLeastOneCompFail)
5543 return false;
5544
5545 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5546 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005547}
5548
5549enum CXChildVisitResult
5550AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005551 SourceRange cursorRange = getRawCursorExtent(cursor);
5552 if (cursorRange.isInvalid())
5553 return CXChildVisit_Recurse;
5554
5555 if (!HasContextSensitiveKeywords) {
5556 // Objective-C properties can have context-sensitive keywords.
5557 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005558 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005559 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5560 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5561 }
5562 // Objective-C methods can have context-sensitive keywords.
5563 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5564 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005565 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005566 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5567 if (Method->getObjCDeclQualifier())
5568 HasContextSensitiveKeywords = true;
5569 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005570 for (const auto *P : Method->params()) {
5571 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005572 HasContextSensitiveKeywords = true;
5573 break;
5574 }
5575 }
5576 }
5577 }
5578 }
5579 // C++ methods can have context-sensitive keywords.
5580 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005581 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005582 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5583 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5584 HasContextSensitiveKeywords = true;
5585 }
5586 }
5587 // C++ classes can have context-sensitive keywords.
5588 else if (cursor.kind == CXCursor_StructDecl ||
5589 cursor.kind == CXCursor_ClassDecl ||
5590 cursor.kind == CXCursor_ClassTemplate ||
5591 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005592 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005593 if (D->hasAttr<FinalAttr>())
5594 HasContextSensitiveKeywords = true;
5595 }
5596 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005597
5598 // Don't override a property annotation with its getter/setter method.
5599 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5600 parent.kind == CXCursor_ObjCPropertyDecl)
5601 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005602
5603 if (clang_isPreprocessing(cursor.kind)) {
5604 // Items in the preprocessing record are kept separate from items in
5605 // declarations, so we keep a separate token index.
5606 unsigned SavedTokIdx = TokIdx;
5607 TokIdx = PreprocessingTokIdx;
5608
5609 // Skip tokens up until we catch up to the beginning of the preprocessing
5610 // entry.
5611 while (MoreTokens()) {
5612 const unsigned I = NextToken();
5613 SourceLocation TokLoc = GetTokenLoc(I);
5614 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5615 case RangeBefore:
5616 AdvanceToken();
5617 continue;
5618 case RangeAfter:
5619 case RangeOverlap:
5620 break;
5621 }
5622 break;
5623 }
5624
5625 // Look at all of the tokens within this range.
5626 while (MoreTokens()) {
5627 const unsigned I = NextToken();
5628 SourceLocation TokLoc = GetTokenLoc(I);
5629 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5630 case RangeBefore:
5631 llvm_unreachable("Infeasible");
5632 case RangeAfter:
5633 break;
5634 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005635 // For macro expansions, just note where the beginning of the macro
5636 // expansion occurs.
5637 if (cursor.kind == CXCursor_MacroExpansion) {
5638 if (TokLoc == cursorRange.getBegin())
5639 Cursors[I] = cursor;
5640 AdvanceToken();
5641 break;
5642 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005643 // We may have already annotated macro names inside macro definitions.
5644 if (Cursors[I].kind != CXCursor_MacroExpansion)
5645 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 continue;
5648 }
5649 break;
5650 }
5651
5652 // Save the preprocessing token index; restore the non-preprocessing
5653 // token index.
5654 PreprocessingTokIdx = TokIdx;
5655 TokIdx = SavedTokIdx;
5656 return CXChildVisit_Recurse;
5657 }
5658
5659 if (cursorRange.isInvalid())
5660 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005661
5662 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005664 const enum CXCursorKind K = clang_getCursorKind(parent);
5665 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005666 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5667 // Attributes are annotated out-of-order, skip tokens until we reach it.
5668 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005669 ? clang_getNullCursor() : parent;
5670
5671 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5672
5673 // Avoid having the cursor of an expression "overwrite" the annotation of the
5674 // variable declaration that it belongs to.
5675 // This can happen for C++ constructor expressions whose range generally
5676 // include the variable declaration, e.g.:
5677 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005678 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005679 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005680 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 const unsigned I = NextToken();
5682 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5683 E->getLocStart() == D->getLocation() &&
5684 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005685 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005686 AdvanceToken();
5687 }
5688 }
5689 }
5690
5691 // Before recursing into the children keep some state that we are going
5692 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5693 // extra work after the child nodes are visited.
5694 // Note that we don't call VisitChildren here to avoid traversing statements
5695 // code-recursively which can blow the stack.
5696
5697 PostChildrenInfo Info;
5698 Info.Cursor = cursor;
5699 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005700 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005701 Info.BeforeChildrenTokenIdx = NextToken();
5702 PostChildrenInfos.push_back(Info);
5703
5704 return CXChildVisit_Recurse;
5705}
5706
5707bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5708 if (PostChildrenInfos.empty())
5709 return false;
5710 const PostChildrenInfo &Info = PostChildrenInfos.back();
5711 if (!clang_equalCursors(Info.Cursor, cursor))
5712 return false;
5713
5714 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5715 const unsigned AfterChildren = NextToken();
5716 SourceRange cursorRange = Info.CursorRange;
5717
5718 // Scan the tokens that are at the end of the cursor, but are not captured
5719 // but the child cursors.
5720 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5721
5722 // Scan the tokens that are at the beginning of the cursor, but are not
5723 // capture by the child cursors.
5724 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5725 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5726 break;
5727
5728 Cursors[I] = cursor;
5729 }
5730
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005731 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5732 // encountered the attribute cursor.
5733 if (clang_isAttribute(cursor.kind))
5734 TokIdx = Info.BeforeReachingCursorIdx;
5735
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 PostChildrenInfos.pop_back();
5737 return false;
5738}
5739
5740static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5741 CXCursor parent,
5742 CXClientData client_data) {
5743 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5744}
5745
5746static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5747 CXClientData client_data) {
5748 return static_cast<AnnotateTokensWorker*>(client_data)->
5749 postVisitChildren(cursor);
5750}
5751
5752namespace {
5753
5754/// \brief Uses the macro expansions in the preprocessing record to find
5755/// and mark tokens that are macro arguments. This info is used by the
5756/// AnnotateTokensWorker.
5757class MarkMacroArgTokensVisitor {
5758 SourceManager &SM;
5759 CXToken *Tokens;
5760 unsigned NumTokens;
5761 unsigned CurIdx;
5762
5763public:
5764 MarkMacroArgTokensVisitor(SourceManager &SM,
5765 CXToken *tokens, unsigned numTokens)
5766 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5767
5768 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5769 if (cursor.kind != CXCursor_MacroExpansion)
5770 return CXChildVisit_Continue;
5771
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005772 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005773 if (macroRange.getBegin() == macroRange.getEnd())
5774 return CXChildVisit_Continue; // it's not a function macro.
5775
5776 for (; CurIdx < NumTokens; ++CurIdx) {
5777 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5778 macroRange.getBegin()))
5779 break;
5780 }
5781
5782 if (CurIdx == NumTokens)
5783 return CXChildVisit_Break;
5784
5785 for (; CurIdx < NumTokens; ++CurIdx) {
5786 SourceLocation tokLoc = getTokenLoc(CurIdx);
5787 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5788 break;
5789
5790 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5791 }
5792
5793 if (CurIdx == NumTokens)
5794 return CXChildVisit_Break;
5795
5796 return CXChildVisit_Continue;
5797 }
5798
5799private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005800 CXToken &getTok(unsigned Idx) {
5801 assert(Idx < NumTokens);
5802 return Tokens[Idx];
5803 }
5804 const CXToken &getTok(unsigned Idx) const {
5805 assert(Idx < NumTokens);
5806 return Tokens[Idx];
5807 }
5808
Guy Benyei11169dd2012-12-18 14:30:41 +00005809 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005810 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005811 }
5812
5813 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5814 // The third field is reserved and currently not used. Use it here
5815 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005816 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005817 }
5818};
5819
5820} // end anonymous namespace
5821
5822static CXChildVisitResult
5823MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5824 CXClientData client_data) {
5825 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5826 parent);
5827}
5828
5829namespace {
5830 struct clang_annotateTokens_Data {
5831 CXTranslationUnit TU;
5832 ASTUnit *CXXUnit;
5833 CXToken *Tokens;
5834 unsigned NumTokens;
5835 CXCursor *Cursors;
5836 };
5837}
5838
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005839/// \brief Used by \c annotatePreprocessorTokens.
5840/// \returns true if lexing was finished, false otherwise.
5841static bool lexNext(Lexer &Lex, Token &Tok,
5842 unsigned &NextIdx, unsigned NumTokens) {
5843 if (NextIdx >= NumTokens)
5844 return true;
5845
5846 ++NextIdx;
5847 Lex.LexFromRawLexer(Tok);
5848 if (Tok.is(tok::eof))
5849 return true;
5850
5851 return false;
5852}
5853
Guy Benyei11169dd2012-12-18 14:30:41 +00005854static void annotatePreprocessorTokens(CXTranslationUnit TU,
5855 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005856 CXCursor *Cursors,
5857 CXToken *Tokens,
5858 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005859 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005860
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005861 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005862 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5863 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005864 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005865 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005866 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005867
5868 if (BeginLocInfo.first != EndLocInfo.first)
5869 return;
5870
5871 StringRef Buffer;
5872 bool Invalid = false;
5873 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5874 if (Buffer.empty() || Invalid)
5875 return;
5876
5877 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5878 CXXUnit->getASTContext().getLangOpts(),
5879 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5880 Buffer.end());
5881 Lex.SetCommentRetentionState(true);
5882
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005883 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005884 // Lex tokens in raw mode until we hit the end of the range, to avoid
5885 // entering #includes or expanding macros.
5886 while (true) {
5887 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005888 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5889 break;
5890 unsigned TokIdx = NextIdx-1;
5891 assert(Tok.getLocation() ==
5892 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005893
5894 reprocess:
5895 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005896 // We have found a preprocessing directive. Annotate the tokens
5897 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 //
5899 // FIXME: Some simple tests here could identify macro definitions and
5900 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005901
5902 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005903 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5904 break;
5905
Craig Topper69186e72014-06-08 08:38:04 +00005906 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005907 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005908 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5909 break;
5910
5911 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005912 IdentifierInfo &II =
5913 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005914 SourceLocation MappedTokLoc =
5915 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5916 MI = getMacroInfo(II, MappedTokLoc, TU);
5917 }
5918 }
5919
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005920 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005921 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005922 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5923 finished = true;
5924 break;
5925 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005926 // If we are in a macro definition, check if the token was ever a
5927 // macro name and annotate it if that's the case.
5928 if (MI) {
5929 SourceLocation SaveLoc = Tok.getLocation();
5930 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5931 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5932 Tok.setLocation(SaveLoc);
5933 if (MacroDef)
5934 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5935 Tok.getLocation(), TU);
5936 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005937 } while (!Tok.isAtStartOfLine());
5938
5939 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5940 assert(TokIdx <= LastIdx);
5941 SourceLocation EndLoc =
5942 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5943 CXCursor Cursor =
5944 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5945
5946 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005947 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005948
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005949 if (finished)
5950 break;
5951 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005952 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005953 }
5954}
5955
5956// This gets run a separate thread to avoid stack blowout.
5957static void clang_annotateTokensImpl(void *UserData) {
5958 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5959 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5960 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5961 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5962 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5963
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005964 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005965 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5966 setThreadBackgroundPriority();
5967
5968 // Determine the region of interest, which contains all of the tokens.
5969 SourceRange RegionOfInterest;
5970 RegionOfInterest.setBegin(
5971 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5972 RegionOfInterest.setEnd(
5973 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5974 Tokens[NumTokens-1])));
5975
Guy Benyei11169dd2012-12-18 14:30:41 +00005976 // Relex the tokens within the source range to look for preprocessing
5977 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005978 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005979
5980 // If begin location points inside a macro argument, set it to the expansion
5981 // location so we can have the full context when annotating semantically.
5982 {
5983 SourceManager &SM = CXXUnit->getSourceManager();
5984 SourceLocation Loc =
5985 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5986 if (Loc.isMacroID())
5987 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5988 }
5989
Guy Benyei11169dd2012-12-18 14:30:41 +00005990 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5991 // Search and mark tokens that are macro argument expansions.
5992 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5993 Tokens, NumTokens);
5994 CursorVisitor MacroArgMarker(TU,
5995 MarkMacroArgTokensVisitorDelegate, &Visitor,
5996 /*VisitPreprocessorLast=*/true,
5997 /*VisitIncludedEntities=*/false,
5998 RegionOfInterest);
5999 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6000 }
6001
6002 // Annotate all of the source locations in the region of interest that map to
6003 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006004 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006005
6006 // FIXME: We use a ridiculous stack size here because the data-recursion
6007 // algorithm uses a large stack frame than the non-data recursive version,
6008 // and AnnotationTokensWorker currently transforms the data-recursion
6009 // algorithm back into a traditional recursion by explicitly calling
6010 // VisitChildren(). We will need to remove this explicit recursive call.
6011 W.AnnotateTokens();
6012
6013 // If we ran into any entities that involve context-sensitive keywords,
6014 // take another pass through the tokens to mark them as such.
6015 if (W.hasContextSensitiveKeywords()) {
6016 for (unsigned I = 0; I != NumTokens; ++I) {
6017 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6018 continue;
6019
6020 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6021 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006022 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006023 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6024 if (Property->getPropertyAttributesAsWritten() != 0 &&
6025 llvm::StringSwitch<bool>(II->getName())
6026 .Case("readonly", true)
6027 .Case("assign", true)
6028 .Case("unsafe_unretained", true)
6029 .Case("readwrite", true)
6030 .Case("retain", true)
6031 .Case("copy", true)
6032 .Case("nonatomic", true)
6033 .Case("atomic", true)
6034 .Case("getter", true)
6035 .Case("setter", true)
6036 .Case("strong", true)
6037 .Case("weak", true)
6038 .Default(false))
6039 Tokens[I].int_data[0] = CXToken_Keyword;
6040 }
6041 continue;
6042 }
6043
6044 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6045 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6046 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6047 if (llvm::StringSwitch<bool>(II->getName())
6048 .Case("in", true)
6049 .Case("out", true)
6050 .Case("inout", true)
6051 .Case("oneway", true)
6052 .Case("bycopy", true)
6053 .Case("byref", true)
6054 .Default(false))
6055 Tokens[I].int_data[0] = CXToken_Keyword;
6056 continue;
6057 }
6058
6059 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6060 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6061 Tokens[I].int_data[0] = CXToken_Keyword;
6062 continue;
6063 }
6064 }
6065 }
6066}
6067
6068extern "C" {
6069
6070void clang_annotateTokens(CXTranslationUnit TU,
6071 CXToken *Tokens, unsigned NumTokens,
6072 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006073 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006074 LOG_BAD_TU(TU);
6075 return;
6076 }
6077 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006078 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006079 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006080 }
6081
6082 LOG_FUNC_SECTION {
6083 *Log << TU << ' ';
6084 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6085 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6086 *Log << clang_getRange(bloc, eloc);
6087 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006088
6089 // Any token we don't specifically annotate will have a NULL cursor.
6090 CXCursor C = clang_getNullCursor();
6091 for (unsigned I = 0; I != NumTokens; ++I)
6092 Cursors[I] = C;
6093
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006094 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006095 if (!CXXUnit)
6096 return;
6097
6098 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6099
6100 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6101 llvm::CrashRecoveryContext CRC;
6102 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6103 GetSafetyThreadStackSize() * 2)) {
6104 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6105 }
6106}
6107
6108} // end: extern "C"
6109
6110//===----------------------------------------------------------------------===//
6111// Operations for querying linkage of a cursor.
6112//===----------------------------------------------------------------------===//
6113
6114extern "C" {
6115CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6116 if (!clang_isDeclaration(cursor.kind))
6117 return CXLinkage_Invalid;
6118
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006119 const Decl *D = cxcursor::getCursorDecl(cursor);
6120 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006121 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006122 case NoLinkage:
6123 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006124 case InternalLinkage: return CXLinkage_Internal;
6125 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6126 case ExternalLinkage: return CXLinkage_External;
6127 };
6128
6129 return CXLinkage_Invalid;
6130}
6131} // end: extern "C"
6132
6133//===----------------------------------------------------------------------===//
6134// Operations for querying language of a cursor.
6135//===----------------------------------------------------------------------===//
6136
6137static CXLanguageKind getDeclLanguage(const Decl *D) {
6138 if (!D)
6139 return CXLanguage_C;
6140
6141 switch (D->getKind()) {
6142 default:
6143 break;
6144 case Decl::ImplicitParam:
6145 case Decl::ObjCAtDefsField:
6146 case Decl::ObjCCategory:
6147 case Decl::ObjCCategoryImpl:
6148 case Decl::ObjCCompatibleAlias:
6149 case Decl::ObjCImplementation:
6150 case Decl::ObjCInterface:
6151 case Decl::ObjCIvar:
6152 case Decl::ObjCMethod:
6153 case Decl::ObjCProperty:
6154 case Decl::ObjCPropertyImpl:
6155 case Decl::ObjCProtocol:
6156 return CXLanguage_ObjC;
6157 case Decl::CXXConstructor:
6158 case Decl::CXXConversion:
6159 case Decl::CXXDestructor:
6160 case Decl::CXXMethod:
6161 case Decl::CXXRecord:
6162 case Decl::ClassTemplate:
6163 case Decl::ClassTemplatePartialSpecialization:
6164 case Decl::ClassTemplateSpecialization:
6165 case Decl::Friend:
6166 case Decl::FriendTemplate:
6167 case Decl::FunctionTemplate:
6168 case Decl::LinkageSpec:
6169 case Decl::Namespace:
6170 case Decl::NamespaceAlias:
6171 case Decl::NonTypeTemplateParm:
6172 case Decl::StaticAssert:
6173 case Decl::TemplateTemplateParm:
6174 case Decl::TemplateTypeParm:
6175 case Decl::UnresolvedUsingTypename:
6176 case Decl::UnresolvedUsingValue:
6177 case Decl::Using:
6178 case Decl::UsingDirective:
6179 case Decl::UsingShadow:
6180 return CXLanguage_CPlusPlus;
6181 }
6182
6183 return CXLanguage_C;
6184}
6185
6186extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006187
6188static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6189 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6190 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006191
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006192 switch (D->getAvailability()) {
6193 case AR_Available:
6194 case AR_NotYetIntroduced:
6195 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006196 return getCursorAvailabilityForDecl(
6197 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006198 return CXAvailability_Available;
6199
6200 case AR_Deprecated:
6201 return CXAvailability_Deprecated;
6202
6203 case AR_Unavailable:
6204 return CXAvailability_NotAvailable;
6205 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006206
6207 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006208}
6209
Guy Benyei11169dd2012-12-18 14:30:41 +00006210enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6211 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006212 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6213 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006214
6215 return CXAvailability_Available;
6216}
6217
6218static CXVersion convertVersion(VersionTuple In) {
6219 CXVersion Out = { -1, -1, -1 };
6220 if (In.empty())
6221 return Out;
6222
6223 Out.Major = In.getMajor();
6224
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006225 Optional<unsigned> Minor = In.getMinor();
6226 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006227 Out.Minor = *Minor;
6228 else
6229 return Out;
6230
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006231 Optional<unsigned> Subminor = In.getSubminor();
6232 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006233 Out.Subminor = *Subminor;
6234
6235 return Out;
6236}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006237
6238static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6239 int *always_deprecated,
6240 CXString *deprecated_message,
6241 int *always_unavailable,
6242 CXString *unavailable_message,
6243 CXPlatformAvailability *availability,
6244 int availability_size) {
6245 bool HadAvailAttr = false;
6246 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006247 for (auto A : D->attrs()) {
6248 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006249 HadAvailAttr = true;
6250 if (always_deprecated)
6251 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006252 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006253 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006254 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006255 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006256 continue;
6257 }
6258
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006259 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006260 HadAvailAttr = true;
6261 if (always_unavailable)
6262 *always_unavailable = 1;
6263 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006264 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006265 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6266 }
6267 continue;
6268 }
6269
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006270 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006271 HadAvailAttr = true;
6272 if (N < availability_size) {
6273 availability[N].Platform
6274 = cxstring::createDup(Avail->getPlatform()->getName());
6275 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6276 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6277 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6278 availability[N].Unavailable = Avail->getUnavailable();
6279 availability[N].Message = cxstring::createDup(Avail->getMessage());
6280 }
6281 ++N;
6282 }
6283 }
6284
6285 if (!HadAvailAttr)
6286 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6287 return getCursorPlatformAvailabilityForDecl(
6288 cast<Decl>(EnumConst->getDeclContext()),
6289 always_deprecated,
6290 deprecated_message,
6291 always_unavailable,
6292 unavailable_message,
6293 availability,
6294 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006295
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006296 return N;
6297}
6298
Guy Benyei11169dd2012-12-18 14:30:41 +00006299int clang_getCursorPlatformAvailability(CXCursor cursor,
6300 int *always_deprecated,
6301 CXString *deprecated_message,
6302 int *always_unavailable,
6303 CXString *unavailable_message,
6304 CXPlatformAvailability *availability,
6305 int availability_size) {
6306 if (always_deprecated)
6307 *always_deprecated = 0;
6308 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006309 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006310 if (always_unavailable)
6311 *always_unavailable = 0;
6312 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006313 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006314
Guy Benyei11169dd2012-12-18 14:30:41 +00006315 if (!clang_isDeclaration(cursor.kind))
6316 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006317
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006318 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006319 if (!D)
6320 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006321
6322 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6323 deprecated_message,
6324 always_unavailable,
6325 unavailable_message,
6326 availability,
6327 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006328}
6329
6330void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6331 clang_disposeString(availability->Platform);
6332 clang_disposeString(availability->Message);
6333}
6334
6335CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6336 if (clang_isDeclaration(cursor.kind))
6337 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6338
6339 return CXLanguage_Invalid;
6340}
6341
6342 /// \brief If the given cursor is the "templated" declaration
6343 /// descibing a class or function template, return the class or
6344 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006345static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006346 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006347 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006348
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006349 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006350 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6351 return FunTmpl;
6352
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006353 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006354 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6355 return ClassTmpl;
6356
6357 return D;
6358}
6359
6360CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6361 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006362 if (const Decl *D = getCursorDecl(cursor)) {
6363 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006364 if (!DC)
6365 return clang_getNullCursor();
6366
6367 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6368 getCursorTU(cursor));
6369 }
6370 }
6371
6372 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006373 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006374 return MakeCXCursor(D, getCursorTU(cursor));
6375 }
6376
6377 return clang_getNullCursor();
6378}
6379
6380CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6381 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006382 if (const Decl *D = getCursorDecl(cursor)) {
6383 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006384 if (!DC)
6385 return clang_getNullCursor();
6386
6387 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6388 getCursorTU(cursor));
6389 }
6390 }
6391
6392 // FIXME: Note that we can't easily compute the lexical context of a
6393 // statement or expression, so we return nothing.
6394 return clang_getNullCursor();
6395}
6396
6397CXFile clang_getIncludedFile(CXCursor cursor) {
6398 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006399 return nullptr;
6400
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006401 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006402 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006403}
6404
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006405unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6406 if (C.kind != CXCursor_ObjCPropertyDecl)
6407 return CXObjCPropertyAttr_noattr;
6408
6409 unsigned Result = CXObjCPropertyAttr_noattr;
6410 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6411 ObjCPropertyDecl::PropertyAttributeKind Attr =
6412 PD->getPropertyAttributesAsWritten();
6413
6414#define SET_CXOBJCPROP_ATTR(A) \
6415 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6416 Result |= CXObjCPropertyAttr_##A
6417 SET_CXOBJCPROP_ATTR(readonly);
6418 SET_CXOBJCPROP_ATTR(getter);
6419 SET_CXOBJCPROP_ATTR(assign);
6420 SET_CXOBJCPROP_ATTR(readwrite);
6421 SET_CXOBJCPROP_ATTR(retain);
6422 SET_CXOBJCPROP_ATTR(copy);
6423 SET_CXOBJCPROP_ATTR(nonatomic);
6424 SET_CXOBJCPROP_ATTR(setter);
6425 SET_CXOBJCPROP_ATTR(atomic);
6426 SET_CXOBJCPROP_ATTR(weak);
6427 SET_CXOBJCPROP_ATTR(strong);
6428 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6429#undef SET_CXOBJCPROP_ATTR
6430
6431 return Result;
6432}
6433
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006434unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6435 if (!clang_isDeclaration(C.kind))
6436 return CXObjCDeclQualifier_None;
6437
6438 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6439 const Decl *D = getCursorDecl(C);
6440 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6441 QT = MD->getObjCDeclQualifier();
6442 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6443 QT = PD->getObjCDeclQualifier();
6444 if (QT == Decl::OBJC_TQ_None)
6445 return CXObjCDeclQualifier_None;
6446
6447 unsigned Result = CXObjCDeclQualifier_None;
6448 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6449 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6450 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6451 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6452 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6453 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6454
6455 return Result;
6456}
6457
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006458unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6459 if (!clang_isDeclaration(C.kind))
6460 return 0;
6461
6462 const Decl *D = getCursorDecl(C);
6463 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6464 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6465 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6466 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6467
6468 return 0;
6469}
6470
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006471unsigned clang_Cursor_isVariadic(CXCursor C) {
6472 if (!clang_isDeclaration(C.kind))
6473 return 0;
6474
6475 const Decl *D = getCursorDecl(C);
6476 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6477 return FD->isVariadic();
6478 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6479 return MD->isVariadic();
6480
6481 return 0;
6482}
6483
Guy Benyei11169dd2012-12-18 14:30:41 +00006484CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6485 if (!clang_isDeclaration(C.kind))
6486 return clang_getNullRange();
6487
6488 const Decl *D = getCursorDecl(C);
6489 ASTContext &Context = getCursorContext(C);
6490 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6491 if (!RC)
6492 return clang_getNullRange();
6493
6494 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6495}
6496
6497CXString clang_Cursor_getRawCommentText(CXCursor C) {
6498 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006499 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006500
6501 const Decl *D = getCursorDecl(C);
6502 ASTContext &Context = getCursorContext(C);
6503 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6504 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6505 StringRef();
6506
6507 // Don't duplicate the string because RawText points directly into source
6508 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006509 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006510}
6511
6512CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6513 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006514 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006515
6516 const Decl *D = getCursorDecl(C);
6517 const ASTContext &Context = getCursorContext(C);
6518 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6519
6520 if (RC) {
6521 StringRef BriefText = RC->getBriefText(Context);
6522
6523 // Don't duplicate the string because RawComment ensures that this memory
6524 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006525 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006526 }
6527
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006528 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006529}
6530
Guy Benyei11169dd2012-12-18 14:30:41 +00006531CXModule clang_Cursor_getModule(CXCursor C) {
6532 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006533 if (const ImportDecl *ImportD =
6534 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006535 return ImportD->getImportedModule();
6536 }
6537
Craig Topper69186e72014-06-08 08:38:04 +00006538 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006539}
6540
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006541CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6542 if (isNotUsableTU(TU)) {
6543 LOG_BAD_TU(TU);
6544 return nullptr;
6545 }
6546 if (!File)
6547 return nullptr;
6548 FileEntry *FE = static_cast<FileEntry *>(File);
6549
6550 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6551 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6552 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6553
6554 if (Module *Mod = Header.getModule()) {
6555 if (Header.getRole() != ModuleMap::ExcludedHeader)
6556 return Mod;
6557 }
6558 return nullptr;
6559}
6560
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006561CXFile clang_Module_getASTFile(CXModule CXMod) {
6562 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006563 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006564 Module *Mod = static_cast<Module*>(CXMod);
6565 return const_cast<FileEntry *>(Mod->getASTFile());
6566}
6567
Guy Benyei11169dd2012-12-18 14:30:41 +00006568CXModule clang_Module_getParent(CXModule CXMod) {
6569 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006570 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 Module *Mod = static_cast<Module*>(CXMod);
6572 return Mod->Parent;
6573}
6574
6575CXString clang_Module_getName(CXModule CXMod) {
6576 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006577 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006578 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006579 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006580}
6581
6582CXString clang_Module_getFullName(CXModule CXMod) {
6583 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006584 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006585 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006586 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006587}
6588
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006589int clang_Module_isSystem(CXModule CXMod) {
6590 if (!CXMod)
6591 return 0;
6592 Module *Mod = static_cast<Module*>(CXMod);
6593 return Mod->IsSystem;
6594}
6595
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006596unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6597 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006598 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006599 LOG_BAD_TU(TU);
6600 return 0;
6601 }
6602 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006603 return 0;
6604 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006605 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6606 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6607 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006608}
6609
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006610CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6611 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006612 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006613 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006614 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006615 }
6616 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006617 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006618 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006619 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006620
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006621 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6622 if (Index < TopHeaders.size())
6623 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006624
Craig Topper69186e72014-06-08 08:38:04 +00006625 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006626}
6627
6628} // end: extern "C"
6629
6630//===----------------------------------------------------------------------===//
6631// C++ AST instrospection.
6632//===----------------------------------------------------------------------===//
6633
6634extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006635unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6636 if (!clang_isDeclaration(C.kind))
6637 return 0;
6638
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006639 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006640 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006641 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006642 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6643}
6644
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006645unsigned clang_CXXMethod_isConst(CXCursor C) {
6646 if (!clang_isDeclaration(C.kind))
6647 return 0;
6648
6649 const Decl *D = cxcursor::getCursorDecl(C);
6650 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006651 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006652 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6653}
6654
Guy Benyei11169dd2012-12-18 14:30:41 +00006655unsigned clang_CXXMethod_isStatic(CXCursor C) {
6656 if (!clang_isDeclaration(C.kind))
6657 return 0;
6658
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006659 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006660 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006661 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006662 return (Method && Method->isStatic()) ? 1 : 0;
6663}
6664
6665unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6666 if (!clang_isDeclaration(C.kind))
6667 return 0;
6668
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006669 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006670 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006671 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006672 return (Method && Method->isVirtual()) ? 1 : 0;
6673}
6674} // end: extern "C"
6675
6676//===----------------------------------------------------------------------===//
6677// Attribute introspection.
6678//===----------------------------------------------------------------------===//
6679
6680extern "C" {
6681CXType clang_getIBOutletCollectionType(CXCursor C) {
6682 if (C.kind != CXCursor_IBOutletCollectionAttr)
6683 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6684
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006685 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006686 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6687
6688 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6689}
6690} // end: extern "C"
6691
6692//===----------------------------------------------------------------------===//
6693// Inspecting memory usage.
6694//===----------------------------------------------------------------------===//
6695
6696typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6697
6698static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6699 enum CXTUResourceUsageKind k,
6700 unsigned long amount) {
6701 CXTUResourceUsageEntry entry = { k, amount };
6702 entries.push_back(entry);
6703}
6704
6705extern "C" {
6706
6707const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6708 const char *str = "";
6709 switch (kind) {
6710 case CXTUResourceUsage_AST:
6711 str = "ASTContext: expressions, declarations, and types";
6712 break;
6713 case CXTUResourceUsage_Identifiers:
6714 str = "ASTContext: identifiers";
6715 break;
6716 case CXTUResourceUsage_Selectors:
6717 str = "ASTContext: selectors";
6718 break;
6719 case CXTUResourceUsage_GlobalCompletionResults:
6720 str = "Code completion: cached global results";
6721 break;
6722 case CXTUResourceUsage_SourceManagerContentCache:
6723 str = "SourceManager: content cache allocator";
6724 break;
6725 case CXTUResourceUsage_AST_SideTables:
6726 str = "ASTContext: side tables";
6727 break;
6728 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6729 str = "SourceManager: malloc'ed memory buffers";
6730 break;
6731 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6732 str = "SourceManager: mmap'ed memory buffers";
6733 break;
6734 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6735 str = "ExternalASTSource: malloc'ed memory buffers";
6736 break;
6737 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6738 str = "ExternalASTSource: mmap'ed memory buffers";
6739 break;
6740 case CXTUResourceUsage_Preprocessor:
6741 str = "Preprocessor: malloc'ed memory";
6742 break;
6743 case CXTUResourceUsage_PreprocessingRecord:
6744 str = "Preprocessor: PreprocessingRecord";
6745 break;
6746 case CXTUResourceUsage_SourceManager_DataStructures:
6747 str = "SourceManager: data structures and tables";
6748 break;
6749 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6750 str = "Preprocessor: header search tables";
6751 break;
6752 }
6753 return str;
6754}
6755
6756CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006757 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006758 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006759 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006760 return usage;
6761 }
6762
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006763 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006764 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006765 ASTContext &astContext = astUnit->getASTContext();
6766
6767 // How much memory is used by AST nodes and types?
6768 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6769 (unsigned long) astContext.getASTAllocatedMemory());
6770
6771 // How much memory is used by identifiers?
6772 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6773 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6774
6775 // How much memory is used for selectors?
6776 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6777 (unsigned long) astContext.Selectors.getTotalMemory());
6778
6779 // How much memory is used by ASTContext's side tables?
6780 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6781 (unsigned long) astContext.getSideTableAllocatedMemory());
6782
6783 // How much memory is used for caching global code completion results?
6784 unsigned long completionBytes = 0;
6785 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006786 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006787 completionBytes = completionAllocator->getTotalMemory();
6788 }
6789 createCXTUResourceUsageEntry(*entries,
6790 CXTUResourceUsage_GlobalCompletionResults,
6791 completionBytes);
6792
6793 // How much memory is being used by SourceManager's content cache?
6794 createCXTUResourceUsageEntry(*entries,
6795 CXTUResourceUsage_SourceManagerContentCache,
6796 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6797
6798 // How much memory is being used by the MemoryBuffer's in SourceManager?
6799 const SourceManager::MemoryBufferSizes &srcBufs =
6800 astUnit->getSourceManager().getMemoryBufferSizes();
6801
6802 createCXTUResourceUsageEntry(*entries,
6803 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6804 (unsigned long) srcBufs.malloc_bytes);
6805 createCXTUResourceUsageEntry(*entries,
6806 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6807 (unsigned long) srcBufs.mmap_bytes);
6808 createCXTUResourceUsageEntry(*entries,
6809 CXTUResourceUsage_SourceManager_DataStructures,
6810 (unsigned long) astContext.getSourceManager()
6811 .getDataStructureSizes());
6812
6813 // How much memory is being used by the ExternalASTSource?
6814 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6815 const ExternalASTSource::MemoryBufferSizes &sizes =
6816 esrc->getMemoryBufferSizes();
6817
6818 createCXTUResourceUsageEntry(*entries,
6819 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6820 (unsigned long) sizes.malloc_bytes);
6821 createCXTUResourceUsageEntry(*entries,
6822 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6823 (unsigned long) sizes.mmap_bytes);
6824 }
6825
6826 // How much memory is being used by the Preprocessor?
6827 Preprocessor &pp = astUnit->getPreprocessor();
6828 createCXTUResourceUsageEntry(*entries,
6829 CXTUResourceUsage_Preprocessor,
6830 pp.getTotalMemory());
6831
6832 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6833 createCXTUResourceUsageEntry(*entries,
6834 CXTUResourceUsage_PreprocessingRecord,
6835 pRec->getTotalMemory());
6836 }
6837
6838 createCXTUResourceUsageEntry(*entries,
6839 CXTUResourceUsage_Preprocessor_HeaderSearch,
6840 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006841
Guy Benyei11169dd2012-12-18 14:30:41 +00006842 CXTUResourceUsage usage = { (void*) entries.get(),
6843 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006844 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006845 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006846 return usage;
6847}
6848
6849void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6850 if (usage.data)
6851 delete (MemUsageEntries*) usage.data;
6852}
6853
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006854CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6855 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006856 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006857 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006858
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006859 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006860 LOG_BAD_TU(TU);
6861 return skipped;
6862 }
6863
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006864 if (!file)
6865 return skipped;
6866
6867 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6868 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6869 if (!ppRec)
6870 return skipped;
6871
6872 ASTContext &Ctx = astUnit->getASTContext();
6873 SourceManager &sm = Ctx.getSourceManager();
6874 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6875 FileID wantedFileID = sm.translateFile(fileEntry);
6876
6877 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6878 std::vector<SourceRange> wantedRanges;
6879 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6880 i != ei; ++i) {
6881 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6882 wantedRanges.push_back(*i);
6883 }
6884
6885 skipped->count = wantedRanges.size();
6886 skipped->ranges = new CXSourceRange[skipped->count];
6887 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6888 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6889
6890 return skipped;
6891}
6892
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006893void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6894 if (ranges) {
6895 delete[] ranges->ranges;
6896 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006897 }
6898}
6899
Guy Benyei11169dd2012-12-18 14:30:41 +00006900} // end extern "C"
6901
6902void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6903 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6904 for (unsigned I = 0; I != Usage.numEntries; ++I)
6905 fprintf(stderr, " %s: %lu\n",
6906 clang_getTUResourceUsageName(Usage.entries[I].kind),
6907 Usage.entries[I].amount);
6908
6909 clang_disposeCXTUResourceUsage(Usage);
6910}
6911
6912//===----------------------------------------------------------------------===//
6913// Misc. utility functions.
6914//===----------------------------------------------------------------------===//
6915
6916/// Default to using an 8 MB stack size on "safety" threads.
6917static unsigned SafetyStackThreadSize = 8 << 20;
6918
6919namespace clang {
6920
6921bool RunSafely(llvm::CrashRecoveryContext &CRC,
6922 void (*Fn)(void*), void *UserData,
6923 unsigned Size) {
6924 if (!Size)
6925 Size = GetSafetyThreadStackSize();
6926 if (Size)
6927 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6928 return CRC.RunSafely(Fn, UserData);
6929}
6930
6931unsigned GetSafetyThreadStackSize() {
6932 return SafetyStackThreadSize;
6933}
6934
6935void SetSafetyThreadStackSize(unsigned Value) {
6936 SafetyStackThreadSize = Value;
6937}
6938
6939}
6940
6941void clang::setThreadBackgroundPriority() {
6942 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6943 return;
6944
Alp Toker1a86ad22014-07-06 06:24:00 +00006945#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006946 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6947#endif
6948}
6949
6950void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6951 if (!Unit)
6952 return;
6953
6954 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6955 DEnd = Unit->stored_diag_end();
6956 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006957 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006958 CXString Msg = clang_formatDiagnostic(&Diag,
6959 clang_defaultDiagnosticDisplayOptions());
6960 fprintf(stderr, "%s\n", clang_getCString(Msg));
6961 clang_disposeString(Msg);
6962 }
6963#ifdef LLVM_ON_WIN32
6964 // On Windows, force a flush, since there may be multiple copies of
6965 // stderr and stdout in the file system, all with different buffers
6966 // but writing to the same device.
6967 fflush(stderr);
6968#endif
6969}
6970
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006971MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6972 SourceLocation MacroDefLoc,
6973 CXTranslationUnit TU){
6974 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006975 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006976 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006977 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006978
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006979 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006980 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006981 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006982 if (MD) {
6983 for (MacroDirective::DefInfo
6984 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6985 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6986 return Def.getMacroInfo();
6987 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006988 }
6989
Craig Topper69186e72014-06-08 08:38:04 +00006990 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006991}
6992
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006993const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6994 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006995 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006996 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006997 const IdentifierInfo *II = MacroDef->getName();
6998 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006999 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007000
7001 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7002}
7003
7004MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7005 const Token &Tok,
7006 CXTranslationUnit TU) {
7007 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007008 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007009 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007010 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007011
7012 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007013 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007014 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7015 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007016 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007017
7018 // Check that the token is inside the definition and not its argument list.
7019 SourceManager &SM = Unit->getSourceManager();
7020 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007021 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007022 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007023 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007024
7025 Preprocessor &PP = Unit->getPreprocessor();
7026 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7027 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007028 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007029
Alp Toker2d57cea2014-05-17 04:53:25 +00007030 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007031 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007032 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007033
7034 // Check that the identifier is not one of the macro arguments.
7035 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007036 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007037
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007038 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7039 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007040 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007041
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007042 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007043}
7044
7045MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7046 SourceLocation Loc,
7047 CXTranslationUnit TU) {
7048 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007049 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007050
7051 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007052 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007053 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007054 Preprocessor &PP = Unit->getPreprocessor();
7055 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007056 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007057 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7058 Token Tok;
7059 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007060 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007061
7062 return checkForMacroInMacroDefinition(MI, Tok, TU);
7063}
7064
Guy Benyei11169dd2012-12-18 14:30:41 +00007065extern "C" {
7066
7067CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007068 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007069}
7070
7071} // end: extern "C"
7072
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007073Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7074 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007075 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007076 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007077 if (Unit->isMainFileAST())
7078 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007079 return *this;
7080 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007081 } else {
7082 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007083 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007084 return *this;
7085}
7086
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007087Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7088 *this << FE->getName();
7089 return *this;
7090}
7091
7092Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7093 CXString cursorName = clang_getCursorDisplayName(cursor);
7094 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7095 clang_disposeString(cursorName);
7096 return *this;
7097}
7098
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007099Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7100 CXFile File;
7101 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007102 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007103 CXString FileName = clang_getFileName(File);
7104 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7105 clang_disposeString(FileName);
7106 return *this;
7107}
7108
7109Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7110 CXSourceLocation BLoc = clang_getRangeStart(range);
7111 CXSourceLocation ELoc = clang_getRangeEnd(range);
7112
7113 CXFile BFile;
7114 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007115 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007116
7117 CXFile EFile;
7118 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007119 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007120
7121 CXString BFileName = clang_getFileName(BFile);
7122 if (BFile == EFile) {
7123 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7124 BLine, BColumn, ELine, EColumn);
7125 } else {
7126 CXString EFileName = clang_getFileName(EFile);
7127 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7128 BLine, BColumn)
7129 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7130 ELine, EColumn);
7131 clang_disposeString(EFileName);
7132 }
7133 clang_disposeString(BFileName);
7134 return *this;
7135}
7136
7137Logger &cxindex::Logger::operator<<(CXString Str) {
7138 *this << clang_getCString(Str);
7139 return *this;
7140}
7141
7142Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7143 LogOS << Fmt;
7144 return *this;
7145}
7146
Chandler Carruth37ad2582014-06-27 15:14:39 +00007147static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7148
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007149cxindex::Logger::~Logger() {
7150 LogOS.flush();
7151
Chandler Carruth37ad2582014-06-27 15:14:39 +00007152 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007153
7154 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7155
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007156 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007157 OS << "[libclang:" << Name << ':';
7158
Alp Toker1a86ad22014-07-06 06:24:00 +00007159#ifdef USE_DARWIN_THREADS
7160 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007161 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7162 OS << tid << ':';
7163#endif
7164
7165 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7166 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7167 OS << Msg.str() << '\n';
7168
7169 if (Trace) {
7170 llvm::sys::PrintStackTrace(stderr);
7171 OS << "--------------------------------------------------\n";
7172 }
7173}