blob: d898f90ca6284c88bad7bd65a4c342452446dbfb [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;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002783 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002784 CXXIdx->getOnlyLocalDecls(), None,
2785 /*CaptureDiagnostics=*/true,
2786 /*AllowPCHWithCompilerErrors=*/true,
2787 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002788 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2789 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)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004078 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004103 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004104 return cxstring::createRef("OMPParallelDirective");
4105 case CXCursor_OMPSimdDirective:
4106 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004107 case CXCursor_OMPForDirective:
4108 return cxstring::createRef("OMPForDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004109 case CXCursor_OMPSectionsDirective:
4110 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004111 case CXCursor_OMPSectionDirective:
4112 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004113 case CXCursor_OMPSingleDirective:
4114 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004115 case CXCursor_OMPMasterDirective:
4116 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004117 case CXCursor_OMPCriticalDirective:
4118 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004119 case CXCursor_OMPParallelForDirective:
4120 return cxstring::createRef("OMPParallelForDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004121 case CXCursor_OMPParallelSectionsDirective:
4122 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004123 case CXCursor_OMPTaskDirective:
4124 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004125 case CXCursor_OMPTaskyieldDirective:
4126 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004127 case CXCursor_OMPBarrierDirective:
4128 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004129 case CXCursor_OMPTaskwaitDirective:
4130 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004131 case CXCursor_OMPFlushDirective:
4132 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004133 case CXCursor_OMPOrderedDirective:
4134 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004135 case CXCursor_OMPAtomicDirective:
4136 return cxstring::createRef("OMPAtomicDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 }
4138
4139 llvm_unreachable("Unhandled CXCursorKind");
4140}
4141
4142struct GetCursorData {
4143 SourceLocation TokenBeginLoc;
4144 bool PointsAtMacroArgExpansion;
4145 bool VisitedObjCPropertyImplDecl;
4146 SourceLocation VisitedDeclaratorDeclStartLoc;
4147 CXCursor &BestCursor;
4148
4149 GetCursorData(SourceManager &SM,
4150 SourceLocation tokenBegin, CXCursor &outputCursor)
4151 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4152 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4153 VisitedObjCPropertyImplDecl = false;
4154 }
4155};
4156
4157static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4158 CXCursor parent,
4159 CXClientData client_data) {
4160 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4161 CXCursor *BestCursor = &Data->BestCursor;
4162
4163 // If we point inside a macro argument we should provide info of what the
4164 // token is so use the actual cursor, don't replace it with a macro expansion
4165 // cursor.
4166 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4167 return CXChildVisit_Recurse;
4168
4169 if (clang_isDeclaration(cursor.kind)) {
4170 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004171 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4173 if (MD->isImplicit())
4174 return CXChildVisit_Break;
4175
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004176 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4178 // Check that when we have multiple @class references in the same line,
4179 // that later ones do not override the previous ones.
4180 // If we have:
4181 // @class Foo, Bar;
4182 // source ranges for both start at '@', so 'Bar' will end up overriding
4183 // 'Foo' even though the cursor location was at 'Foo'.
4184 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4185 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004186 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4188 if (PrevID != ID &&
4189 !PrevID->isThisDeclarationADefinition() &&
4190 !ID->isThisDeclarationADefinition())
4191 return CXChildVisit_Break;
4192 }
4193
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004194 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4196 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4197 // Check that when we have multiple declarators in the same line,
4198 // that later ones do not override the previous ones.
4199 // If we have:
4200 // int Foo, Bar;
4201 // source ranges for both start at 'int', so 'Bar' will end up overriding
4202 // 'Foo' even though the cursor location was at 'Foo'.
4203 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4204 return CXChildVisit_Break;
4205 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4206
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004207 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4209 (void)PropImp;
4210 // Check that when we have multiple @synthesize in the same line,
4211 // that later ones do not override the previous ones.
4212 // If we have:
4213 // @synthesize Foo, Bar;
4214 // source ranges for both start at '@', so 'Bar' will end up overriding
4215 // 'Foo' even though the cursor location was at 'Foo'.
4216 if (Data->VisitedObjCPropertyImplDecl)
4217 return CXChildVisit_Break;
4218 Data->VisitedObjCPropertyImplDecl = true;
4219 }
4220 }
4221
4222 if (clang_isExpression(cursor.kind) &&
4223 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004224 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 // Avoid having the cursor of an expression replace the declaration cursor
4226 // when the expression source range overlaps the declaration range.
4227 // This can happen for C++ constructor expressions whose range generally
4228 // include the variable declaration, e.g.:
4229 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4230 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4231 D->getLocation() == Data->TokenBeginLoc)
4232 return CXChildVisit_Break;
4233 }
4234 }
4235
4236 // If our current best cursor is the construction of a temporary object,
4237 // don't replace that cursor with a type reference, because we want
4238 // clang_getCursor() to point at the constructor.
4239 if (clang_isExpression(BestCursor->kind) &&
4240 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4241 cursor.kind == CXCursor_TypeRef) {
4242 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4243 // as having the actual point on the type reference.
4244 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4245 return CXChildVisit_Recurse;
4246 }
4247
4248 *BestCursor = cursor;
4249 return CXChildVisit_Recurse;
4250}
4251
4252CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004253 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004254 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004256 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004257
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004258 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4260
4261 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4262 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4263
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004264 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 CXFile SearchFile;
4266 unsigned SearchLine, SearchColumn;
4267 CXFile ResultFile;
4268 unsigned ResultLine, ResultColumn;
4269 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4270 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4271 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004272
4273 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4274 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004275 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004276 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 SearchFileName = clang_getFileName(SearchFile);
4278 ResultFileName = clang_getFileName(ResultFile);
4279 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4280 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004281 *Log << llvm::format("(%s:%d:%d) = %s",
4282 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4283 clang_getCString(KindSpelling))
4284 << llvm::format("(%s:%d:%d):%s%s",
4285 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4286 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 clang_disposeString(SearchFileName);
4288 clang_disposeString(ResultFileName);
4289 clang_disposeString(KindSpelling);
4290 clang_disposeString(USR);
4291
4292 CXCursor Definition = clang_getCursorDefinition(Result);
4293 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4294 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4295 CXString DefinitionKindSpelling
4296 = clang_getCursorKindSpelling(Definition.kind);
4297 CXFile DefinitionFile;
4298 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004299 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004300 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004302 *Log << llvm::format(" -> %s(%s:%d:%d)",
4303 clang_getCString(DefinitionKindSpelling),
4304 clang_getCString(DefinitionFileName),
4305 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 clang_disposeString(DefinitionFileName);
4307 clang_disposeString(DefinitionKindSpelling);
4308 }
4309 }
4310
4311 return Result;
4312}
4313
4314CXCursor clang_getNullCursor(void) {
4315 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4316}
4317
4318unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004319 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4320 // can't set consistently. For example, when visiting a DeclStmt we will set
4321 // it but we don't set it on the result of clang_getCursorDefinition for
4322 // a reference of the same declaration.
4323 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4324 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4325 // to provide that kind of info.
4326 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004327 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004328 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004329 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004330
Guy Benyei11169dd2012-12-18 14:30:41 +00004331 return X == Y;
4332}
4333
4334unsigned clang_hashCursor(CXCursor C) {
4335 unsigned Index = 0;
4336 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4337 Index = 1;
4338
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004339 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004340 std::make_pair(C.kind, C.data[Index]));
4341}
4342
4343unsigned clang_isInvalid(enum CXCursorKind K) {
4344 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4345}
4346
4347unsigned clang_isDeclaration(enum CXCursorKind K) {
4348 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4349 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4350}
4351
4352unsigned clang_isReference(enum CXCursorKind K) {
4353 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4354}
4355
4356unsigned clang_isExpression(enum CXCursorKind K) {
4357 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4358}
4359
4360unsigned clang_isStatement(enum CXCursorKind K) {
4361 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4362}
4363
4364unsigned clang_isAttribute(enum CXCursorKind K) {
4365 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4366}
4367
4368unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4369 return K == CXCursor_TranslationUnit;
4370}
4371
4372unsigned clang_isPreprocessing(enum CXCursorKind K) {
4373 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4374}
4375
4376unsigned clang_isUnexposed(enum CXCursorKind K) {
4377 switch (K) {
4378 case CXCursor_UnexposedDecl:
4379 case CXCursor_UnexposedExpr:
4380 case CXCursor_UnexposedStmt:
4381 case CXCursor_UnexposedAttr:
4382 return true;
4383 default:
4384 return false;
4385 }
4386}
4387
4388CXCursorKind clang_getCursorKind(CXCursor C) {
4389 return C.kind;
4390}
4391
4392CXSourceLocation clang_getCursorLocation(CXCursor C) {
4393 if (clang_isReference(C.kind)) {
4394 switch (C.kind) {
4395 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004396 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004397 = getCursorObjCSuperClassRef(C);
4398 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4399 }
4400
4401 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004402 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 = getCursorObjCProtocolRef(C);
4404 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4405 }
4406
4407 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004408 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004409 = getCursorObjCClassRef(C);
4410 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4411 }
4412
4413 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004414 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4416 }
4417
4418 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004419 std::pair<const TemplateDecl *, SourceLocation> P =
4420 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4422 }
4423
4424 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004425 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004426 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4427 }
4428
4429 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004430 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004431 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4432 }
4433
4434 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004435 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4437 }
4438
4439 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004440 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 if (!BaseSpec)
4442 return clang_getNullLocation();
4443
4444 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4445 return cxloc::translateSourceLocation(getCursorContext(C),
4446 TSInfo->getTypeLoc().getBeginLoc());
4447
4448 return cxloc::translateSourceLocation(getCursorContext(C),
4449 BaseSpec->getLocStart());
4450 }
4451
4452 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004453 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004454 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4455 }
4456
4457 case CXCursor_OverloadedDeclRef:
4458 return cxloc::translateSourceLocation(getCursorContext(C),
4459 getCursorOverloadedDeclRef(C).second);
4460
4461 default:
4462 // FIXME: Need a way to enumerate all non-reference cases.
4463 llvm_unreachable("Missed a reference kind");
4464 }
4465 }
4466
4467 if (clang_isExpression(C.kind))
4468 return cxloc::translateSourceLocation(getCursorContext(C),
4469 getLocationFromExpr(getCursorExpr(C)));
4470
4471 if (clang_isStatement(C.kind))
4472 return cxloc::translateSourceLocation(getCursorContext(C),
4473 getCursorStmt(C)->getLocStart());
4474
4475 if (C.kind == CXCursor_PreprocessingDirective) {
4476 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4477 return cxloc::translateSourceLocation(getCursorContext(C), L);
4478 }
4479
4480 if (C.kind == CXCursor_MacroExpansion) {
4481 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004482 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 return cxloc::translateSourceLocation(getCursorContext(C), L);
4484 }
4485
4486 if (C.kind == CXCursor_MacroDefinition) {
4487 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4488 return cxloc::translateSourceLocation(getCursorContext(C), L);
4489 }
4490
4491 if (C.kind == CXCursor_InclusionDirective) {
4492 SourceLocation L
4493 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4494 return cxloc::translateSourceLocation(getCursorContext(C), L);
4495 }
4496
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004497 if (clang_isAttribute(C.kind)) {
4498 SourceLocation L
4499 = cxcursor::getCursorAttr(C)->getLocation();
4500 return cxloc::translateSourceLocation(getCursorContext(C), L);
4501 }
4502
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 if (!clang_isDeclaration(C.kind))
4504 return clang_getNullLocation();
4505
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004506 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 if (!D)
4508 return clang_getNullLocation();
4509
4510 SourceLocation Loc = D->getLocation();
4511 // FIXME: Multiple variables declared in a single declaration
4512 // currently lack the information needed to correctly determine their
4513 // ranges when accounting for the type-specifier. We use context
4514 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4515 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004516 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 if (!cxcursor::isFirstInDeclGroup(C))
4518 Loc = VD->getLocation();
4519 }
4520
4521 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004522 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 Loc = MD->getSelectorStartLoc();
4524
4525 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4526}
4527
4528} // end extern "C"
4529
4530CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4531 assert(TU);
4532
4533 // Guard against an invalid SourceLocation, or we may assert in one
4534 // of the following calls.
4535 if (SLoc.isInvalid())
4536 return clang_getNullCursor();
4537
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004538 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004539
4540 // Translate the given source location to make it point at the beginning of
4541 // the token under the cursor.
4542 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4543 CXXUnit->getASTContext().getLangOpts());
4544
4545 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4546 if (SLoc.isValid()) {
4547 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4548 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4549 /*VisitPreprocessorLast=*/true,
4550 /*VisitIncludedEntities=*/false,
4551 SourceLocation(SLoc));
4552 CursorVis.visitFileRegion();
4553 }
4554
4555 return Result;
4556}
4557
4558static SourceRange getRawCursorExtent(CXCursor C) {
4559 if (clang_isReference(C.kind)) {
4560 switch (C.kind) {
4561 case CXCursor_ObjCSuperClassRef:
4562 return getCursorObjCSuperClassRef(C).second;
4563
4564 case CXCursor_ObjCProtocolRef:
4565 return getCursorObjCProtocolRef(C).second;
4566
4567 case CXCursor_ObjCClassRef:
4568 return getCursorObjCClassRef(C).second;
4569
4570 case CXCursor_TypeRef:
4571 return getCursorTypeRef(C).second;
4572
4573 case CXCursor_TemplateRef:
4574 return getCursorTemplateRef(C).second;
4575
4576 case CXCursor_NamespaceRef:
4577 return getCursorNamespaceRef(C).second;
4578
4579 case CXCursor_MemberRef:
4580 return getCursorMemberRef(C).second;
4581
4582 case CXCursor_CXXBaseSpecifier:
4583 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4584
4585 case CXCursor_LabelRef:
4586 return getCursorLabelRef(C).second;
4587
4588 case CXCursor_OverloadedDeclRef:
4589 return getCursorOverloadedDeclRef(C).second;
4590
4591 case CXCursor_VariableRef:
4592 return getCursorVariableRef(C).second;
4593
4594 default:
4595 // FIXME: Need a way to enumerate all non-reference cases.
4596 llvm_unreachable("Missed a reference kind");
4597 }
4598 }
4599
4600 if (clang_isExpression(C.kind))
4601 return getCursorExpr(C)->getSourceRange();
4602
4603 if (clang_isStatement(C.kind))
4604 return getCursorStmt(C)->getSourceRange();
4605
4606 if (clang_isAttribute(C.kind))
4607 return getCursorAttr(C)->getRange();
4608
4609 if (C.kind == CXCursor_PreprocessingDirective)
4610 return cxcursor::getCursorPreprocessingDirective(C);
4611
4612 if (C.kind == CXCursor_MacroExpansion) {
4613 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004614 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 return TU->mapRangeFromPreamble(Range);
4616 }
4617
4618 if (C.kind == CXCursor_MacroDefinition) {
4619 ASTUnit *TU = getCursorASTUnit(C);
4620 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4621 return TU->mapRangeFromPreamble(Range);
4622 }
4623
4624 if (C.kind == CXCursor_InclusionDirective) {
4625 ASTUnit *TU = getCursorASTUnit(C);
4626 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4627 return TU->mapRangeFromPreamble(Range);
4628 }
4629
4630 if (C.kind == CXCursor_TranslationUnit) {
4631 ASTUnit *TU = getCursorASTUnit(C);
4632 FileID MainID = TU->getSourceManager().getMainFileID();
4633 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4634 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4635 return SourceRange(Start, End);
4636 }
4637
4638 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004639 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 if (!D)
4641 return SourceRange();
4642
4643 SourceRange R = D->getSourceRange();
4644 // FIXME: Multiple variables declared in a single declaration
4645 // currently lack the information needed to correctly determine their
4646 // ranges when accounting for the type-specifier. We use context
4647 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4648 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004649 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 if (!cxcursor::isFirstInDeclGroup(C))
4651 R.setBegin(VD->getLocation());
4652 }
4653 return R;
4654 }
4655 return SourceRange();
4656}
4657
4658/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4659/// the decl-specifier-seq for declarations.
4660static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4661 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004662 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 if (!D)
4664 return SourceRange();
4665
4666 SourceRange R = D->getSourceRange();
4667
4668 // Adjust the start of the location for declarations preceded by
4669 // declaration specifiers.
4670 SourceLocation StartLoc;
4671 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4672 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4673 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004674 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4676 StartLoc = TI->getTypeLoc().getLocStart();
4677 }
4678
4679 if (StartLoc.isValid() && R.getBegin().isValid() &&
4680 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4681 R.setBegin(StartLoc);
4682
4683 // FIXME: Multiple variables declared in a single declaration
4684 // currently lack the information needed to correctly determine their
4685 // ranges when accounting for the type-specifier. We use context
4686 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4687 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004688 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 if (!cxcursor::isFirstInDeclGroup(C))
4690 R.setBegin(VD->getLocation());
4691 }
4692
4693 return R;
4694 }
4695
4696 return getRawCursorExtent(C);
4697}
4698
4699extern "C" {
4700
4701CXSourceRange clang_getCursorExtent(CXCursor C) {
4702 SourceRange R = getRawCursorExtent(C);
4703 if (R.isInvalid())
4704 return clang_getNullRange();
4705
4706 return cxloc::translateSourceRange(getCursorContext(C), R);
4707}
4708
4709CXCursor clang_getCursorReferenced(CXCursor C) {
4710 if (clang_isInvalid(C.kind))
4711 return clang_getNullCursor();
4712
4713 CXTranslationUnit tu = getCursorTU(C);
4714 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004715 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004716 if (!D)
4717 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004718 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004720 if (const ObjCPropertyImplDecl *PropImpl =
4721 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4723 return MakeCXCursor(Property, tu);
4724
4725 return C;
4726 }
4727
4728 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004729 const Expr *E = getCursorExpr(C);
4730 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 if (D) {
4732 CXCursor declCursor = MakeCXCursor(D, tu);
4733 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4734 declCursor);
4735 return declCursor;
4736 }
4737
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004738 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 return MakeCursorOverloadedDeclRef(Ovl, tu);
4740
4741 return clang_getNullCursor();
4742 }
4743
4744 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004745 const Stmt *S = getCursorStmt(C);
4746 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 if (LabelDecl *label = Goto->getLabel())
4748 if (LabelStmt *labelS = label->getStmt())
4749 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4750
4751 return clang_getNullCursor();
4752 }
4753
4754 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004755 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 return MakeMacroDefinitionCursor(Def, tu);
4757 }
4758
4759 if (!clang_isReference(C.kind))
4760 return clang_getNullCursor();
4761
4762 switch (C.kind) {
4763 case CXCursor_ObjCSuperClassRef:
4764 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4765
4766 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004767 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4768 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 return MakeCXCursor(Def, tu);
4770
4771 return MakeCXCursor(Prot, tu);
4772 }
4773
4774 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004775 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4776 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 return MakeCXCursor(Def, tu);
4778
4779 return MakeCXCursor(Class, tu);
4780 }
4781
4782 case CXCursor_TypeRef:
4783 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4784
4785 case CXCursor_TemplateRef:
4786 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4787
4788 case CXCursor_NamespaceRef:
4789 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4790
4791 case CXCursor_MemberRef:
4792 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4793
4794 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004795 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004796 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4797 tu ));
4798 }
4799
4800 case CXCursor_LabelRef:
4801 // FIXME: We end up faking the "parent" declaration here because we
4802 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004803 return MakeCXCursor(getCursorLabelRef(C).first,
4804 cxtu::getASTUnit(tu)->getASTContext()
4805 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004806 tu);
4807
4808 case CXCursor_OverloadedDeclRef:
4809 return C;
4810
4811 case CXCursor_VariableRef:
4812 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4813
4814 default:
4815 // We would prefer to enumerate all non-reference cursor kinds here.
4816 llvm_unreachable("Unhandled reference cursor kind");
4817 }
4818}
4819
4820CXCursor clang_getCursorDefinition(CXCursor C) {
4821 if (clang_isInvalid(C.kind))
4822 return clang_getNullCursor();
4823
4824 CXTranslationUnit TU = getCursorTU(C);
4825
4826 bool WasReference = false;
4827 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4828 C = clang_getCursorReferenced(C);
4829 WasReference = true;
4830 }
4831
4832 if (C.kind == CXCursor_MacroExpansion)
4833 return clang_getCursorReferenced(C);
4834
4835 if (!clang_isDeclaration(C.kind))
4836 return clang_getNullCursor();
4837
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004838 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004839 if (!D)
4840 return clang_getNullCursor();
4841
4842 switch (D->getKind()) {
4843 // Declaration kinds that don't really separate the notions of
4844 // declaration and definition.
4845 case Decl::Namespace:
4846 case Decl::Typedef:
4847 case Decl::TypeAlias:
4848 case Decl::TypeAliasTemplate:
4849 case Decl::TemplateTypeParm:
4850 case Decl::EnumConstant:
4851 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004852 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 case Decl::IndirectField:
4854 case Decl::ObjCIvar:
4855 case Decl::ObjCAtDefsField:
4856 case Decl::ImplicitParam:
4857 case Decl::ParmVar:
4858 case Decl::NonTypeTemplateParm:
4859 case Decl::TemplateTemplateParm:
4860 case Decl::ObjCCategoryImpl:
4861 case Decl::ObjCImplementation:
4862 case Decl::AccessSpec:
4863 case Decl::LinkageSpec:
4864 case Decl::ObjCPropertyImpl:
4865 case Decl::FileScopeAsm:
4866 case Decl::StaticAssert:
4867 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004868 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 case Decl::Label: // FIXME: Is this right??
4870 case Decl::ClassScopeFunctionSpecialization:
4871 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004872 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 return C;
4874
4875 // Declaration kinds that don't make any sense here, but are
4876 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004877 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004878 case Decl::TranslationUnit:
4879 break;
4880
4881 // Declaration kinds for which the definition is not resolvable.
4882 case Decl::UnresolvedUsingTypename:
4883 case Decl::UnresolvedUsingValue:
4884 break;
4885
4886 case Decl::UsingDirective:
4887 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4888 TU);
4889
4890 case Decl::NamespaceAlias:
4891 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4892
4893 case Decl::Enum:
4894 case Decl::Record:
4895 case Decl::CXXRecord:
4896 case Decl::ClassTemplateSpecialization:
4897 case Decl::ClassTemplatePartialSpecialization:
4898 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4899 return MakeCXCursor(Def, TU);
4900 return clang_getNullCursor();
4901
4902 case Decl::Function:
4903 case Decl::CXXMethod:
4904 case Decl::CXXConstructor:
4905 case Decl::CXXDestructor:
4906 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00004907 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004908 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004909 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004910 return clang_getNullCursor();
4911 }
4912
Larisse Voufo39a1e502013-08-06 01:03:05 +00004913 case Decl::Var:
4914 case Decl::VarTemplateSpecialization:
4915 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004916 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004917 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004918 return MakeCXCursor(Def, TU);
4919 return clang_getNullCursor();
4920 }
4921
4922 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00004923 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4925 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4926 return clang_getNullCursor();
4927 }
4928
4929 case Decl::ClassTemplate: {
4930 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4931 ->getDefinition())
4932 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4933 TU);
4934 return clang_getNullCursor();
4935 }
4936
Larisse Voufo39a1e502013-08-06 01:03:05 +00004937 case Decl::VarTemplate: {
4938 if (VarDecl *Def =
4939 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4940 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4941 return clang_getNullCursor();
4942 }
4943
Guy Benyei11169dd2012-12-18 14:30:41 +00004944 case Decl::Using:
4945 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4946 D->getLocation(), TU);
4947
4948 case Decl::UsingShadow:
4949 return clang_getCursorDefinition(
4950 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4951 TU));
4952
4953 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004954 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004955 if (Method->isThisDeclarationADefinition())
4956 return C;
4957
4958 // Dig out the method definition in the associated
4959 // @implementation, if we have it.
4960 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004961 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004962 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4963 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4964 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4965 Method->isInstanceMethod()))
4966 if (Def->isThisDeclarationADefinition())
4967 return MakeCXCursor(Def, TU);
4968
4969 return clang_getNullCursor();
4970 }
4971
4972 case Decl::ObjCCategory:
4973 if (ObjCCategoryImplDecl *Impl
4974 = cast<ObjCCategoryDecl>(D)->getImplementation())
4975 return MakeCXCursor(Impl, TU);
4976 return clang_getNullCursor();
4977
4978 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004979 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004980 return MakeCXCursor(Def, TU);
4981 return clang_getNullCursor();
4982
4983 case Decl::ObjCInterface: {
4984 // There are two notions of a "definition" for an Objective-C
4985 // class: the interface and its implementation. When we resolved a
4986 // reference to an Objective-C class, produce the @interface as
4987 // the definition; when we were provided with the interface,
4988 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004989 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004990 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004991 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 return MakeCXCursor(Def, TU);
4993 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4994 return MakeCXCursor(Impl, TU);
4995 return clang_getNullCursor();
4996 }
4997
4998 case Decl::ObjCProperty:
4999 // FIXME: We don't really know where to find the
5000 // ObjCPropertyImplDecls that implement this property.
5001 return clang_getNullCursor();
5002
5003 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005004 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005006 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 return MakeCXCursor(Def, TU);
5008
5009 return clang_getNullCursor();
5010
5011 case Decl::Friend:
5012 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5013 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5014 return clang_getNullCursor();
5015
5016 case Decl::FriendTemplate:
5017 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5018 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5019 return clang_getNullCursor();
5020 }
5021
5022 return clang_getNullCursor();
5023}
5024
5025unsigned clang_isCursorDefinition(CXCursor C) {
5026 if (!clang_isDeclaration(C.kind))
5027 return 0;
5028
5029 return clang_getCursorDefinition(C) == C;
5030}
5031
5032CXCursor clang_getCanonicalCursor(CXCursor C) {
5033 if (!clang_isDeclaration(C.kind))
5034 return C;
5035
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005036 if (const Decl *D = getCursorDecl(C)) {
5037 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005038 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5039 return MakeCXCursor(CatD, getCursorTU(C));
5040
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005041 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5042 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005043 return MakeCXCursor(IFD, getCursorTU(C));
5044
5045 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5046 }
5047
5048 return C;
5049}
5050
5051int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5052 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5053}
5054
5055unsigned clang_getNumOverloadedDecls(CXCursor C) {
5056 if (C.kind != CXCursor_OverloadedDeclRef)
5057 return 0;
5058
5059 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005060 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005061 return E->getNumDecls();
5062
5063 if (OverloadedTemplateStorage *S
5064 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5065 return S->size();
5066
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005067 const Decl *D = Storage.get<const Decl *>();
5068 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 return Using->shadow_size();
5070
5071 return 0;
5072}
5073
5074CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5075 if (cursor.kind != CXCursor_OverloadedDeclRef)
5076 return clang_getNullCursor();
5077
5078 if (index >= clang_getNumOverloadedDecls(cursor))
5079 return clang_getNullCursor();
5080
5081 CXTranslationUnit TU = getCursorTU(cursor);
5082 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005083 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005084 return MakeCXCursor(E->decls_begin()[index], TU);
5085
5086 if (OverloadedTemplateStorage *S
5087 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5088 return MakeCXCursor(S->begin()[index], TU);
5089
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005090 const Decl *D = Storage.get<const Decl *>();
5091 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 // FIXME: This is, unfortunately, linear time.
5093 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5094 std::advance(Pos, index);
5095 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5096 }
5097
5098 return clang_getNullCursor();
5099}
5100
5101void clang_getDefinitionSpellingAndExtent(CXCursor C,
5102 const char **startBuf,
5103 const char **endBuf,
5104 unsigned *startLine,
5105 unsigned *startColumn,
5106 unsigned *endLine,
5107 unsigned *endColumn) {
5108 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005109 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5111
5112 SourceManager &SM = FD->getASTContext().getSourceManager();
5113 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5114 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5115 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5116 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5117 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5118 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5119}
5120
5121
5122CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5123 unsigned PieceIndex) {
5124 RefNamePieces Pieces;
5125
5126 switch (C.kind) {
5127 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005128 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005129 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5130 E->getQualifierLoc().getSourceRange());
5131 break;
5132
5133 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005134 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005135 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5136 E->getQualifierLoc().getSourceRange(),
5137 E->getOptionalExplicitTemplateArgs());
5138 break;
5139
5140 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005141 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005143 const Expr *Callee = OCE->getCallee();
5144 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 Callee = ICE->getSubExpr();
5146
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005147 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5149 DRE->getQualifierLoc().getSourceRange());
5150 }
5151 break;
5152
5153 default:
5154 break;
5155 }
5156
5157 if (Pieces.empty()) {
5158 if (PieceIndex == 0)
5159 return clang_getCursorExtent(C);
5160 } else if (PieceIndex < Pieces.size()) {
5161 SourceRange R = Pieces[PieceIndex];
5162 if (R.isValid())
5163 return cxloc::translateSourceRange(getCursorContext(C), R);
5164 }
5165
5166 return clang_getNullRange();
5167}
5168
5169void clang_enableStackTraces(void) {
5170 llvm::sys::PrintStackTraceOnErrorSignal();
5171}
5172
5173void clang_executeOnThread(void (*fn)(void*), void *user_data,
5174 unsigned stack_size) {
5175 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5176}
5177
5178} // end: extern "C"
5179
5180//===----------------------------------------------------------------------===//
5181// Token-based Operations.
5182//===----------------------------------------------------------------------===//
5183
5184/* CXToken layout:
5185 * int_data[0]: a CXTokenKind
5186 * int_data[1]: starting token location
5187 * int_data[2]: token length
5188 * int_data[3]: reserved
5189 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5190 * otherwise unused.
5191 */
5192extern "C" {
5193
5194CXTokenKind clang_getTokenKind(CXToken CXTok) {
5195 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5196}
5197
5198CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5199 switch (clang_getTokenKind(CXTok)) {
5200 case CXToken_Identifier:
5201 case CXToken_Keyword:
5202 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005203 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 ->getNameStart());
5205
5206 case CXToken_Literal: {
5207 // We have stashed the starting pointer in the ptr_data field. Use it.
5208 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005209 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 }
5211
5212 case CXToken_Punctuation:
5213 case CXToken_Comment:
5214 break;
5215 }
5216
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005217 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005218 LOG_BAD_TU(TU);
5219 return cxstring::createEmpty();
5220 }
5221
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 // We have to find the starting buffer pointer the hard way, by
5223 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005224 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005225 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005226 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005227
5228 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5229 std::pair<FileID, unsigned> LocInfo
5230 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5231 bool Invalid = false;
5232 StringRef Buffer
5233 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5234 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005235 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005236
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005237 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005238}
5239
5240CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005241 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005242 LOG_BAD_TU(TU);
5243 return clang_getNullLocation();
5244 }
5245
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005246 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005247 if (!CXXUnit)
5248 return clang_getNullLocation();
5249
5250 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5251 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5252}
5253
5254CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005255 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005256 LOG_BAD_TU(TU);
5257 return clang_getNullRange();
5258 }
5259
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005260 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005261 if (!CXXUnit)
5262 return clang_getNullRange();
5263
5264 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5265 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5266}
5267
5268static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5269 SmallVectorImpl<CXToken> &CXTokens) {
5270 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5271 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005272 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005273 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005274 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005275
5276 // Cannot tokenize across files.
5277 if (BeginLocInfo.first != EndLocInfo.first)
5278 return;
5279
5280 // Create a lexer
5281 bool Invalid = false;
5282 StringRef Buffer
5283 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5284 if (Invalid)
5285 return;
5286
5287 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5288 CXXUnit->getASTContext().getLangOpts(),
5289 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5290 Lex.SetCommentRetentionState(true);
5291
5292 // Lex tokens until we hit the end of the range.
5293 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5294 Token Tok;
5295 bool previousWasAt = false;
5296 do {
5297 // Lex the next token
5298 Lex.LexFromRawLexer(Tok);
5299 if (Tok.is(tok::eof))
5300 break;
5301
5302 // Initialize the CXToken.
5303 CXToken CXTok;
5304
5305 // - Common fields
5306 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5307 CXTok.int_data[2] = Tok.getLength();
5308 CXTok.int_data[3] = 0;
5309
5310 // - Kind-specific fields
5311 if (Tok.isLiteral()) {
5312 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005313 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 } else if (Tok.is(tok::raw_identifier)) {
5315 // Lookup the identifier to determine whether we have a keyword.
5316 IdentifierInfo *II
5317 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5318
5319 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5320 CXTok.int_data[0] = CXToken_Keyword;
5321 }
5322 else {
5323 CXTok.int_data[0] = Tok.is(tok::identifier)
5324 ? CXToken_Identifier
5325 : CXToken_Keyword;
5326 }
5327 CXTok.ptr_data = II;
5328 } else if (Tok.is(tok::comment)) {
5329 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005330 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005331 } else {
5332 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005333 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 }
5335 CXTokens.push_back(CXTok);
5336 previousWasAt = Tok.is(tok::at);
5337 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5338}
5339
5340void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5341 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005342 LOG_FUNC_SECTION {
5343 *Log << TU << ' ' << Range;
5344 }
5345
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005347 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 if (NumTokens)
5349 *NumTokens = 0;
5350
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005351 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005352 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005353 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005354 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005355
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005356 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 if (!CXXUnit || !Tokens || !NumTokens)
5358 return;
5359
5360 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5361
5362 SourceRange R = cxloc::translateCXSourceRange(Range);
5363 if (R.isInvalid())
5364 return;
5365
5366 SmallVector<CXToken, 32> CXTokens;
5367 getTokens(CXXUnit, R, CXTokens);
5368
5369 if (CXTokens.empty())
5370 return;
5371
5372 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5373 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5374 *NumTokens = CXTokens.size();
5375}
5376
5377void clang_disposeTokens(CXTranslationUnit TU,
5378 CXToken *Tokens, unsigned NumTokens) {
5379 free(Tokens);
5380}
5381
5382} // end: extern "C"
5383
5384//===----------------------------------------------------------------------===//
5385// Token annotation APIs.
5386//===----------------------------------------------------------------------===//
5387
Guy Benyei11169dd2012-12-18 14:30:41 +00005388static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5389 CXCursor parent,
5390 CXClientData client_data);
5391static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5392 CXClientData client_data);
5393
5394namespace {
5395class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005396 CXToken *Tokens;
5397 CXCursor *Cursors;
5398 unsigned NumTokens;
5399 unsigned TokIdx;
5400 unsigned PreprocessingTokIdx;
5401 CursorVisitor AnnotateVis;
5402 SourceManager &SrcMgr;
5403 bool HasContextSensitiveKeywords;
5404
5405 struct PostChildrenInfo {
5406 CXCursor Cursor;
5407 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005408 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005409 unsigned BeforeChildrenTokenIdx;
5410 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005411 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005412
5413 CXToken &getTok(unsigned Idx) {
5414 assert(Idx < NumTokens);
5415 return Tokens[Idx];
5416 }
5417 const CXToken &getTok(unsigned Idx) const {
5418 assert(Idx < NumTokens);
5419 return Tokens[Idx];
5420 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005421 bool MoreTokens() const { return TokIdx < NumTokens; }
5422 unsigned NextToken() const { return TokIdx; }
5423 void AdvanceToken() { ++TokIdx; }
5424 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005425 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 }
5427 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005428 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 }
5430 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005431 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005432 }
5433
5434 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005435 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005436 SourceRange);
5437
5438public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005439 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005440 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005441 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005443 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 AnnotateTokensVisitor, this,
5445 /*VisitPreprocessorLast=*/true,
5446 /*VisitIncludedEntities=*/false,
5447 RegionOfInterest,
5448 /*VisitDeclsOnly=*/false,
5449 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005450 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 HasContextSensitiveKeywords(false) { }
5452
5453 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5454 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5455 bool postVisitChildren(CXCursor cursor);
5456 void AnnotateTokens();
5457
5458 /// \brief Determine whether the annotator saw any cursors that have
5459 /// context-sensitive keywords.
5460 bool hasContextSensitiveKeywords() const {
5461 return HasContextSensitiveKeywords;
5462 }
5463
5464 ~AnnotateTokensWorker() {
5465 assert(PostChildrenInfos.empty());
5466 }
5467};
5468}
5469
5470void AnnotateTokensWorker::AnnotateTokens() {
5471 // Walk the AST within the region of interest, annotating tokens
5472 // along the way.
5473 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005474}
Guy Benyei11169dd2012-12-18 14:30:41 +00005475
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005476static inline void updateCursorAnnotation(CXCursor &Cursor,
5477 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005478 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005480 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005481}
5482
5483/// \brief It annotates and advances tokens with a cursor until the comparison
5484//// between the cursor location and the source range is the same as
5485/// \arg compResult.
5486///
5487/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5488/// Pass RangeOverlap to annotate tokens inside a range.
5489void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5490 RangeComparisonResult compResult,
5491 SourceRange range) {
5492 while (MoreTokens()) {
5493 const unsigned I = NextToken();
5494 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005495 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5496 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005497
5498 SourceLocation TokLoc = GetTokenLoc(I);
5499 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005500 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005501 AdvanceToken();
5502 continue;
5503 }
5504 break;
5505 }
5506}
5507
5508/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005509/// \returns true if it advanced beyond all macro tokens, false otherwise.
5510bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 CXCursor updateC,
5512 RangeComparisonResult compResult,
5513 SourceRange range) {
5514 assert(MoreTokens());
5515 assert(isFunctionMacroToken(NextToken()) &&
5516 "Should be called only for macro arg tokens");
5517
5518 // This works differently than annotateAndAdvanceTokens; because expanded
5519 // macro arguments can have arbitrary translation-unit source order, we do not
5520 // advance the token index one by one until a token fails the range test.
5521 // We only advance once past all of the macro arg tokens if all of them
5522 // pass the range test. If one of them fails we keep the token index pointing
5523 // at the start of the macro arg tokens so that the failing token will be
5524 // annotated by a subsequent annotation try.
5525
5526 bool atLeastOneCompFail = false;
5527
5528 unsigned I = NextToken();
5529 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5530 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5531 if (TokLoc.isFileID())
5532 continue; // not macro arg token, it's parens or comma.
5533 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5534 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5535 Cursors[I] = updateC;
5536 } else
5537 atLeastOneCompFail = true;
5538 }
5539
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005540 if (atLeastOneCompFail)
5541 return false;
5542
5543 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5544 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005545}
5546
5547enum CXChildVisitResult
5548AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005549 SourceRange cursorRange = getRawCursorExtent(cursor);
5550 if (cursorRange.isInvalid())
5551 return CXChildVisit_Recurse;
5552
5553 if (!HasContextSensitiveKeywords) {
5554 // Objective-C properties can have context-sensitive keywords.
5555 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005556 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005557 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5558 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5559 }
5560 // Objective-C methods can have context-sensitive keywords.
5561 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5562 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005563 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005564 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5565 if (Method->getObjCDeclQualifier())
5566 HasContextSensitiveKeywords = true;
5567 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005568 for (const auto *P : Method->params()) {
5569 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005570 HasContextSensitiveKeywords = true;
5571 break;
5572 }
5573 }
5574 }
5575 }
5576 }
5577 // C++ methods can have context-sensitive keywords.
5578 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005579 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005580 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5581 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5582 HasContextSensitiveKeywords = true;
5583 }
5584 }
5585 // C++ classes can have context-sensitive keywords.
5586 else if (cursor.kind == CXCursor_StructDecl ||
5587 cursor.kind == CXCursor_ClassDecl ||
5588 cursor.kind == CXCursor_ClassTemplate ||
5589 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005590 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005591 if (D->hasAttr<FinalAttr>())
5592 HasContextSensitiveKeywords = true;
5593 }
5594 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005595
5596 // Don't override a property annotation with its getter/setter method.
5597 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5598 parent.kind == CXCursor_ObjCPropertyDecl)
5599 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005600
5601 if (clang_isPreprocessing(cursor.kind)) {
5602 // Items in the preprocessing record are kept separate from items in
5603 // declarations, so we keep a separate token index.
5604 unsigned SavedTokIdx = TokIdx;
5605 TokIdx = PreprocessingTokIdx;
5606
5607 // Skip tokens up until we catch up to the beginning of the preprocessing
5608 // entry.
5609 while (MoreTokens()) {
5610 const unsigned I = NextToken();
5611 SourceLocation TokLoc = GetTokenLoc(I);
5612 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5613 case RangeBefore:
5614 AdvanceToken();
5615 continue;
5616 case RangeAfter:
5617 case RangeOverlap:
5618 break;
5619 }
5620 break;
5621 }
5622
5623 // Look at all of the tokens within this range.
5624 while (MoreTokens()) {
5625 const unsigned I = NextToken();
5626 SourceLocation TokLoc = GetTokenLoc(I);
5627 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5628 case RangeBefore:
5629 llvm_unreachable("Infeasible");
5630 case RangeAfter:
5631 break;
5632 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005633 // For macro expansions, just note where the beginning of the macro
5634 // expansion occurs.
5635 if (cursor.kind == CXCursor_MacroExpansion) {
5636 if (TokLoc == cursorRange.getBegin())
5637 Cursors[I] = cursor;
5638 AdvanceToken();
5639 break;
5640 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005641 // We may have already annotated macro names inside macro definitions.
5642 if (Cursors[I].kind != CXCursor_MacroExpansion)
5643 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005644 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 continue;
5646 }
5647 break;
5648 }
5649
5650 // Save the preprocessing token index; restore the non-preprocessing
5651 // token index.
5652 PreprocessingTokIdx = TokIdx;
5653 TokIdx = SavedTokIdx;
5654 return CXChildVisit_Recurse;
5655 }
5656
5657 if (cursorRange.isInvalid())
5658 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005659
5660 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005661 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005662 const enum CXCursorKind K = clang_getCursorKind(parent);
5663 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005664 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5665 // Attributes are annotated out-of-order, skip tokens until we reach it.
5666 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 ? clang_getNullCursor() : parent;
5668
5669 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5670
5671 // Avoid having the cursor of an expression "overwrite" the annotation of the
5672 // variable declaration that it belongs to.
5673 // This can happen for C++ constructor expressions whose range generally
5674 // include the variable declaration, e.g.:
5675 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005676 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005677 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005678 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005679 const unsigned I = NextToken();
5680 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5681 E->getLocStart() == D->getLocation() &&
5682 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005683 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005684 AdvanceToken();
5685 }
5686 }
5687 }
5688
5689 // Before recursing into the children keep some state that we are going
5690 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5691 // extra work after the child nodes are visited.
5692 // Note that we don't call VisitChildren here to avoid traversing statements
5693 // code-recursively which can blow the stack.
5694
5695 PostChildrenInfo Info;
5696 Info.Cursor = cursor;
5697 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005698 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 Info.BeforeChildrenTokenIdx = NextToken();
5700 PostChildrenInfos.push_back(Info);
5701
5702 return CXChildVisit_Recurse;
5703}
5704
5705bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5706 if (PostChildrenInfos.empty())
5707 return false;
5708 const PostChildrenInfo &Info = PostChildrenInfos.back();
5709 if (!clang_equalCursors(Info.Cursor, cursor))
5710 return false;
5711
5712 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5713 const unsigned AfterChildren = NextToken();
5714 SourceRange cursorRange = Info.CursorRange;
5715
5716 // Scan the tokens that are at the end of the cursor, but are not captured
5717 // but the child cursors.
5718 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5719
5720 // Scan the tokens that are at the beginning of the cursor, but are not
5721 // capture by the child cursors.
5722 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5723 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5724 break;
5725
5726 Cursors[I] = cursor;
5727 }
5728
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005729 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5730 // encountered the attribute cursor.
5731 if (clang_isAttribute(cursor.kind))
5732 TokIdx = Info.BeforeReachingCursorIdx;
5733
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 PostChildrenInfos.pop_back();
5735 return false;
5736}
5737
5738static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5739 CXCursor parent,
5740 CXClientData client_data) {
5741 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5742}
5743
5744static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5745 CXClientData client_data) {
5746 return static_cast<AnnotateTokensWorker*>(client_data)->
5747 postVisitChildren(cursor);
5748}
5749
5750namespace {
5751
5752/// \brief Uses the macro expansions in the preprocessing record to find
5753/// and mark tokens that are macro arguments. This info is used by the
5754/// AnnotateTokensWorker.
5755class MarkMacroArgTokensVisitor {
5756 SourceManager &SM;
5757 CXToken *Tokens;
5758 unsigned NumTokens;
5759 unsigned CurIdx;
5760
5761public:
5762 MarkMacroArgTokensVisitor(SourceManager &SM,
5763 CXToken *tokens, unsigned numTokens)
5764 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5765
5766 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5767 if (cursor.kind != CXCursor_MacroExpansion)
5768 return CXChildVisit_Continue;
5769
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005770 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005771 if (macroRange.getBegin() == macroRange.getEnd())
5772 return CXChildVisit_Continue; // it's not a function macro.
5773
5774 for (; CurIdx < NumTokens; ++CurIdx) {
5775 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5776 macroRange.getBegin()))
5777 break;
5778 }
5779
5780 if (CurIdx == NumTokens)
5781 return CXChildVisit_Break;
5782
5783 for (; CurIdx < NumTokens; ++CurIdx) {
5784 SourceLocation tokLoc = getTokenLoc(CurIdx);
5785 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5786 break;
5787
5788 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5789 }
5790
5791 if (CurIdx == NumTokens)
5792 return CXChildVisit_Break;
5793
5794 return CXChildVisit_Continue;
5795 }
5796
5797private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005798 CXToken &getTok(unsigned Idx) {
5799 assert(Idx < NumTokens);
5800 return Tokens[Idx];
5801 }
5802 const CXToken &getTok(unsigned Idx) const {
5803 assert(Idx < NumTokens);
5804 return Tokens[Idx];
5805 }
5806
Guy Benyei11169dd2012-12-18 14:30:41 +00005807 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005808 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005809 }
5810
5811 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5812 // The third field is reserved and currently not used. Use it here
5813 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005814 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005815 }
5816};
5817
5818} // end anonymous namespace
5819
5820static CXChildVisitResult
5821MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5822 CXClientData client_data) {
5823 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5824 parent);
5825}
5826
5827namespace {
5828 struct clang_annotateTokens_Data {
5829 CXTranslationUnit TU;
5830 ASTUnit *CXXUnit;
5831 CXToken *Tokens;
5832 unsigned NumTokens;
5833 CXCursor *Cursors;
5834 };
5835}
5836
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005837/// \brief Used by \c annotatePreprocessorTokens.
5838/// \returns true if lexing was finished, false otherwise.
5839static bool lexNext(Lexer &Lex, Token &Tok,
5840 unsigned &NextIdx, unsigned NumTokens) {
5841 if (NextIdx >= NumTokens)
5842 return true;
5843
5844 ++NextIdx;
5845 Lex.LexFromRawLexer(Tok);
5846 if (Tok.is(tok::eof))
5847 return true;
5848
5849 return false;
5850}
5851
Guy Benyei11169dd2012-12-18 14:30:41 +00005852static void annotatePreprocessorTokens(CXTranslationUnit TU,
5853 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005854 CXCursor *Cursors,
5855 CXToken *Tokens,
5856 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005857 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005858
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005859 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005860 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5861 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005862 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005863 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005864 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005865
5866 if (BeginLocInfo.first != EndLocInfo.first)
5867 return;
5868
5869 StringRef Buffer;
5870 bool Invalid = false;
5871 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5872 if (Buffer.empty() || Invalid)
5873 return;
5874
5875 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5876 CXXUnit->getASTContext().getLangOpts(),
5877 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5878 Buffer.end());
5879 Lex.SetCommentRetentionState(true);
5880
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005881 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005882 // Lex tokens in raw mode until we hit the end of the range, to avoid
5883 // entering #includes or expanding macros.
5884 while (true) {
5885 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005886 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5887 break;
5888 unsigned TokIdx = NextIdx-1;
5889 assert(Tok.getLocation() ==
5890 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005891
5892 reprocess:
5893 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005894 // We have found a preprocessing directive. Annotate the tokens
5895 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005896 //
5897 // FIXME: Some simple tests here could identify macro definitions and
5898 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005899
5900 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005901 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5902 break;
5903
Craig Topper69186e72014-06-08 08:38:04 +00005904 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00005905 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005906 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5907 break;
5908
5909 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005910 IdentifierInfo &II =
5911 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005912 SourceLocation MappedTokLoc =
5913 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5914 MI = getMacroInfo(II, MappedTokLoc, TU);
5915 }
5916 }
5917
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005918 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005919 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005920 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5921 finished = true;
5922 break;
5923 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005924 // If we are in a macro definition, check if the token was ever a
5925 // macro name and annotate it if that's the case.
5926 if (MI) {
5927 SourceLocation SaveLoc = Tok.getLocation();
5928 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5929 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5930 Tok.setLocation(SaveLoc);
5931 if (MacroDef)
5932 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5933 Tok.getLocation(), TU);
5934 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005935 } while (!Tok.isAtStartOfLine());
5936
5937 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5938 assert(TokIdx <= LastIdx);
5939 SourceLocation EndLoc =
5940 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5941 CXCursor Cursor =
5942 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5943
5944 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005945 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005946
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005947 if (finished)
5948 break;
5949 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005950 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005951 }
5952}
5953
5954// This gets run a separate thread to avoid stack blowout.
5955static void clang_annotateTokensImpl(void *UserData) {
5956 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5957 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5958 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5959 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5960 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5961
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005962 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005963 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5964 setThreadBackgroundPriority();
5965
5966 // Determine the region of interest, which contains all of the tokens.
5967 SourceRange RegionOfInterest;
5968 RegionOfInterest.setBegin(
5969 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5970 RegionOfInterest.setEnd(
5971 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5972 Tokens[NumTokens-1])));
5973
Guy Benyei11169dd2012-12-18 14:30:41 +00005974 // Relex the tokens within the source range to look for preprocessing
5975 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005976 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005977
5978 // If begin location points inside a macro argument, set it to the expansion
5979 // location so we can have the full context when annotating semantically.
5980 {
5981 SourceManager &SM = CXXUnit->getSourceManager();
5982 SourceLocation Loc =
5983 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5984 if (Loc.isMacroID())
5985 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5986 }
5987
Guy Benyei11169dd2012-12-18 14:30:41 +00005988 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5989 // Search and mark tokens that are macro argument expansions.
5990 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5991 Tokens, NumTokens);
5992 CursorVisitor MacroArgMarker(TU,
5993 MarkMacroArgTokensVisitorDelegate, &Visitor,
5994 /*VisitPreprocessorLast=*/true,
5995 /*VisitIncludedEntities=*/false,
5996 RegionOfInterest);
5997 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5998 }
5999
6000 // Annotate all of the source locations in the region of interest that map to
6001 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006002 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006003
6004 // FIXME: We use a ridiculous stack size here because the data-recursion
6005 // algorithm uses a large stack frame than the non-data recursive version,
6006 // and AnnotationTokensWorker currently transforms the data-recursion
6007 // algorithm back into a traditional recursion by explicitly calling
6008 // VisitChildren(). We will need to remove this explicit recursive call.
6009 W.AnnotateTokens();
6010
6011 // If we ran into any entities that involve context-sensitive keywords,
6012 // take another pass through the tokens to mark them as such.
6013 if (W.hasContextSensitiveKeywords()) {
6014 for (unsigned I = 0; I != NumTokens; ++I) {
6015 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6016 continue;
6017
6018 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6019 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006020 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006021 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6022 if (Property->getPropertyAttributesAsWritten() != 0 &&
6023 llvm::StringSwitch<bool>(II->getName())
6024 .Case("readonly", true)
6025 .Case("assign", true)
6026 .Case("unsafe_unretained", true)
6027 .Case("readwrite", true)
6028 .Case("retain", true)
6029 .Case("copy", true)
6030 .Case("nonatomic", true)
6031 .Case("atomic", true)
6032 .Case("getter", true)
6033 .Case("setter", true)
6034 .Case("strong", true)
6035 .Case("weak", true)
6036 .Default(false))
6037 Tokens[I].int_data[0] = CXToken_Keyword;
6038 }
6039 continue;
6040 }
6041
6042 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6043 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6044 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6045 if (llvm::StringSwitch<bool>(II->getName())
6046 .Case("in", true)
6047 .Case("out", true)
6048 .Case("inout", true)
6049 .Case("oneway", true)
6050 .Case("bycopy", true)
6051 .Case("byref", true)
6052 .Default(false))
6053 Tokens[I].int_data[0] = CXToken_Keyword;
6054 continue;
6055 }
6056
6057 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6058 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6059 Tokens[I].int_data[0] = CXToken_Keyword;
6060 continue;
6061 }
6062 }
6063 }
6064}
6065
6066extern "C" {
6067
6068void clang_annotateTokens(CXTranslationUnit TU,
6069 CXToken *Tokens, unsigned NumTokens,
6070 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006071 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006072 LOG_BAD_TU(TU);
6073 return;
6074 }
6075 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006076 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006077 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006078 }
6079
6080 LOG_FUNC_SECTION {
6081 *Log << TU << ' ';
6082 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6083 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6084 *Log << clang_getRange(bloc, eloc);
6085 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006086
6087 // Any token we don't specifically annotate will have a NULL cursor.
6088 CXCursor C = clang_getNullCursor();
6089 for (unsigned I = 0; I != NumTokens; ++I)
6090 Cursors[I] = C;
6091
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006092 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006093 if (!CXXUnit)
6094 return;
6095
6096 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6097
6098 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6099 llvm::CrashRecoveryContext CRC;
6100 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6101 GetSafetyThreadStackSize() * 2)) {
6102 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6103 }
6104}
6105
6106} // end: extern "C"
6107
6108//===----------------------------------------------------------------------===//
6109// Operations for querying linkage of a cursor.
6110//===----------------------------------------------------------------------===//
6111
6112extern "C" {
6113CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6114 if (!clang_isDeclaration(cursor.kind))
6115 return CXLinkage_Invalid;
6116
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006117 const Decl *D = cxcursor::getCursorDecl(cursor);
6118 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006119 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006120 case NoLinkage:
6121 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006122 case InternalLinkage: return CXLinkage_Internal;
6123 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6124 case ExternalLinkage: return CXLinkage_External;
6125 };
6126
6127 return CXLinkage_Invalid;
6128}
6129} // end: extern "C"
6130
6131//===----------------------------------------------------------------------===//
6132// Operations for querying language of a cursor.
6133//===----------------------------------------------------------------------===//
6134
6135static CXLanguageKind getDeclLanguage(const Decl *D) {
6136 if (!D)
6137 return CXLanguage_C;
6138
6139 switch (D->getKind()) {
6140 default:
6141 break;
6142 case Decl::ImplicitParam:
6143 case Decl::ObjCAtDefsField:
6144 case Decl::ObjCCategory:
6145 case Decl::ObjCCategoryImpl:
6146 case Decl::ObjCCompatibleAlias:
6147 case Decl::ObjCImplementation:
6148 case Decl::ObjCInterface:
6149 case Decl::ObjCIvar:
6150 case Decl::ObjCMethod:
6151 case Decl::ObjCProperty:
6152 case Decl::ObjCPropertyImpl:
6153 case Decl::ObjCProtocol:
6154 return CXLanguage_ObjC;
6155 case Decl::CXXConstructor:
6156 case Decl::CXXConversion:
6157 case Decl::CXXDestructor:
6158 case Decl::CXXMethod:
6159 case Decl::CXXRecord:
6160 case Decl::ClassTemplate:
6161 case Decl::ClassTemplatePartialSpecialization:
6162 case Decl::ClassTemplateSpecialization:
6163 case Decl::Friend:
6164 case Decl::FriendTemplate:
6165 case Decl::FunctionTemplate:
6166 case Decl::LinkageSpec:
6167 case Decl::Namespace:
6168 case Decl::NamespaceAlias:
6169 case Decl::NonTypeTemplateParm:
6170 case Decl::StaticAssert:
6171 case Decl::TemplateTemplateParm:
6172 case Decl::TemplateTypeParm:
6173 case Decl::UnresolvedUsingTypename:
6174 case Decl::UnresolvedUsingValue:
6175 case Decl::Using:
6176 case Decl::UsingDirective:
6177 case Decl::UsingShadow:
6178 return CXLanguage_CPlusPlus;
6179 }
6180
6181 return CXLanguage_C;
6182}
6183
6184extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006185
6186static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6187 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6188 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00006189
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006190 switch (D->getAvailability()) {
6191 case AR_Available:
6192 case AR_NotYetIntroduced:
6193 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006194 return getCursorAvailabilityForDecl(
6195 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006196 return CXAvailability_Available;
6197
6198 case AR_Deprecated:
6199 return CXAvailability_Deprecated;
6200
6201 case AR_Unavailable:
6202 return CXAvailability_NotAvailable;
6203 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006204
6205 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006206}
6207
Guy Benyei11169dd2012-12-18 14:30:41 +00006208enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6209 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006210 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6211 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006212
6213 return CXAvailability_Available;
6214}
6215
6216static CXVersion convertVersion(VersionTuple In) {
6217 CXVersion Out = { -1, -1, -1 };
6218 if (In.empty())
6219 return Out;
6220
6221 Out.Major = In.getMajor();
6222
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006223 Optional<unsigned> Minor = In.getMinor();
6224 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006225 Out.Minor = *Minor;
6226 else
6227 return Out;
6228
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006229 Optional<unsigned> Subminor = In.getSubminor();
6230 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006231 Out.Subminor = *Subminor;
6232
6233 return Out;
6234}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006235
6236static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6237 int *always_deprecated,
6238 CXString *deprecated_message,
6239 int *always_unavailable,
6240 CXString *unavailable_message,
6241 CXPlatformAvailability *availability,
6242 int availability_size) {
6243 bool HadAvailAttr = false;
6244 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006245 for (auto A : D->attrs()) {
6246 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006247 HadAvailAttr = true;
6248 if (always_deprecated)
6249 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006250 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006251 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006252 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006253 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006254 continue;
6255 }
6256
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006257 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006258 HadAvailAttr = true;
6259 if (always_unavailable)
6260 *always_unavailable = 1;
6261 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006262 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006263 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6264 }
6265 continue;
6266 }
6267
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006268 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006269 HadAvailAttr = true;
6270 if (N < availability_size) {
6271 availability[N].Platform
6272 = cxstring::createDup(Avail->getPlatform()->getName());
6273 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6274 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6275 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6276 availability[N].Unavailable = Avail->getUnavailable();
6277 availability[N].Message = cxstring::createDup(Avail->getMessage());
6278 }
6279 ++N;
6280 }
6281 }
6282
6283 if (!HadAvailAttr)
6284 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6285 return getCursorPlatformAvailabilityForDecl(
6286 cast<Decl>(EnumConst->getDeclContext()),
6287 always_deprecated,
6288 deprecated_message,
6289 always_unavailable,
6290 unavailable_message,
6291 availability,
6292 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006293
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006294 return N;
6295}
6296
Guy Benyei11169dd2012-12-18 14:30:41 +00006297int clang_getCursorPlatformAvailability(CXCursor cursor,
6298 int *always_deprecated,
6299 CXString *deprecated_message,
6300 int *always_unavailable,
6301 CXString *unavailable_message,
6302 CXPlatformAvailability *availability,
6303 int availability_size) {
6304 if (always_deprecated)
6305 *always_deprecated = 0;
6306 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006307 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006308 if (always_unavailable)
6309 *always_unavailable = 0;
6310 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006311 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006312
Guy Benyei11169dd2012-12-18 14:30:41 +00006313 if (!clang_isDeclaration(cursor.kind))
6314 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006315
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006316 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006317 if (!D)
6318 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006319
6320 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6321 deprecated_message,
6322 always_unavailable,
6323 unavailable_message,
6324 availability,
6325 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006326}
6327
6328void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6329 clang_disposeString(availability->Platform);
6330 clang_disposeString(availability->Message);
6331}
6332
6333CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6334 if (clang_isDeclaration(cursor.kind))
6335 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6336
6337 return CXLanguage_Invalid;
6338}
6339
6340 /// \brief If the given cursor is the "templated" declaration
6341 /// descibing a class or function template, return the class or
6342 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006343static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006344 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006345 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006346
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006347 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006348 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6349 return FunTmpl;
6350
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006351 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006352 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6353 return ClassTmpl;
6354
6355 return D;
6356}
6357
6358CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6359 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006360 if (const Decl *D = getCursorDecl(cursor)) {
6361 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006362 if (!DC)
6363 return clang_getNullCursor();
6364
6365 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6366 getCursorTU(cursor));
6367 }
6368 }
6369
6370 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006371 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006372 return MakeCXCursor(D, getCursorTU(cursor));
6373 }
6374
6375 return clang_getNullCursor();
6376}
6377
6378CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6379 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006380 if (const Decl *D = getCursorDecl(cursor)) {
6381 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 if (!DC)
6383 return clang_getNullCursor();
6384
6385 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6386 getCursorTU(cursor));
6387 }
6388 }
6389
6390 // FIXME: Note that we can't easily compute the lexical context of a
6391 // statement or expression, so we return nothing.
6392 return clang_getNullCursor();
6393}
6394
6395CXFile clang_getIncludedFile(CXCursor cursor) {
6396 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006397 return nullptr;
6398
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006399 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006400 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006401}
6402
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006403unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6404 if (C.kind != CXCursor_ObjCPropertyDecl)
6405 return CXObjCPropertyAttr_noattr;
6406
6407 unsigned Result = CXObjCPropertyAttr_noattr;
6408 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6409 ObjCPropertyDecl::PropertyAttributeKind Attr =
6410 PD->getPropertyAttributesAsWritten();
6411
6412#define SET_CXOBJCPROP_ATTR(A) \
6413 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6414 Result |= CXObjCPropertyAttr_##A
6415 SET_CXOBJCPROP_ATTR(readonly);
6416 SET_CXOBJCPROP_ATTR(getter);
6417 SET_CXOBJCPROP_ATTR(assign);
6418 SET_CXOBJCPROP_ATTR(readwrite);
6419 SET_CXOBJCPROP_ATTR(retain);
6420 SET_CXOBJCPROP_ATTR(copy);
6421 SET_CXOBJCPROP_ATTR(nonatomic);
6422 SET_CXOBJCPROP_ATTR(setter);
6423 SET_CXOBJCPROP_ATTR(atomic);
6424 SET_CXOBJCPROP_ATTR(weak);
6425 SET_CXOBJCPROP_ATTR(strong);
6426 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6427#undef SET_CXOBJCPROP_ATTR
6428
6429 return Result;
6430}
6431
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006432unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6433 if (!clang_isDeclaration(C.kind))
6434 return CXObjCDeclQualifier_None;
6435
6436 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6437 const Decl *D = getCursorDecl(C);
6438 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6439 QT = MD->getObjCDeclQualifier();
6440 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6441 QT = PD->getObjCDeclQualifier();
6442 if (QT == Decl::OBJC_TQ_None)
6443 return CXObjCDeclQualifier_None;
6444
6445 unsigned Result = CXObjCDeclQualifier_None;
6446 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6447 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6448 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6449 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6450 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6451 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6452
6453 return Result;
6454}
6455
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006456unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6457 if (!clang_isDeclaration(C.kind))
6458 return 0;
6459
6460 const Decl *D = getCursorDecl(C);
6461 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6462 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6463 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6464 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6465
6466 return 0;
6467}
6468
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006469unsigned clang_Cursor_isVariadic(CXCursor C) {
6470 if (!clang_isDeclaration(C.kind))
6471 return 0;
6472
6473 const Decl *D = getCursorDecl(C);
6474 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6475 return FD->isVariadic();
6476 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6477 return MD->isVariadic();
6478
6479 return 0;
6480}
6481
Guy Benyei11169dd2012-12-18 14:30:41 +00006482CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6483 if (!clang_isDeclaration(C.kind))
6484 return clang_getNullRange();
6485
6486 const Decl *D = getCursorDecl(C);
6487 ASTContext &Context = getCursorContext(C);
6488 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6489 if (!RC)
6490 return clang_getNullRange();
6491
6492 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6493}
6494
6495CXString clang_Cursor_getRawCommentText(CXCursor C) {
6496 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006497 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006498
6499 const Decl *D = getCursorDecl(C);
6500 ASTContext &Context = getCursorContext(C);
6501 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6502 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6503 StringRef();
6504
6505 // Don't duplicate the string because RawText points directly into source
6506 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006507 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006508}
6509
6510CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6511 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006512 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006513
6514 const Decl *D = getCursorDecl(C);
6515 const ASTContext &Context = getCursorContext(C);
6516 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6517
6518 if (RC) {
6519 StringRef BriefText = RC->getBriefText(Context);
6520
6521 // Don't duplicate the string because RawComment ensures that this memory
6522 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006523 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006524 }
6525
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006526 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006527}
6528
Guy Benyei11169dd2012-12-18 14:30:41 +00006529CXModule clang_Cursor_getModule(CXCursor C) {
6530 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006531 if (const ImportDecl *ImportD =
6532 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006533 return ImportD->getImportedModule();
6534 }
6535
Craig Topper69186e72014-06-08 08:38:04 +00006536 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006537}
6538
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006539CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6540 if (isNotUsableTU(TU)) {
6541 LOG_BAD_TU(TU);
6542 return nullptr;
6543 }
6544 if (!File)
6545 return nullptr;
6546 FileEntry *FE = static_cast<FileEntry *>(File);
6547
6548 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6549 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6550 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6551
6552 if (Module *Mod = Header.getModule()) {
6553 if (Header.getRole() != ModuleMap::ExcludedHeader)
6554 return Mod;
6555 }
6556 return nullptr;
6557}
6558
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006559CXFile clang_Module_getASTFile(CXModule CXMod) {
6560 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006561 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006562 Module *Mod = static_cast<Module*>(CXMod);
6563 return const_cast<FileEntry *>(Mod->getASTFile());
6564}
6565
Guy Benyei11169dd2012-12-18 14:30:41 +00006566CXModule clang_Module_getParent(CXModule CXMod) {
6567 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006568 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006569 Module *Mod = static_cast<Module*>(CXMod);
6570 return Mod->Parent;
6571}
6572
6573CXString clang_Module_getName(CXModule CXMod) {
6574 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006575 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006576 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006577 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006578}
6579
6580CXString clang_Module_getFullName(CXModule CXMod) {
6581 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006582 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006583 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006584 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006585}
6586
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006587int clang_Module_isSystem(CXModule CXMod) {
6588 if (!CXMod)
6589 return 0;
6590 Module *Mod = static_cast<Module*>(CXMod);
6591 return Mod->IsSystem;
6592}
6593
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006594unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6595 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006596 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006597 LOG_BAD_TU(TU);
6598 return 0;
6599 }
6600 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006601 return 0;
6602 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006603 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6604 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6605 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006606}
6607
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006608CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6609 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006610 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006611 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006612 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006613 }
6614 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006615 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006616 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006617 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006618
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006619 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6620 if (Index < TopHeaders.size())
6621 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006622
Craig Topper69186e72014-06-08 08:38:04 +00006623 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006624}
6625
6626} // end: extern "C"
6627
6628//===----------------------------------------------------------------------===//
6629// C++ AST instrospection.
6630//===----------------------------------------------------------------------===//
6631
6632extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006633unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6634 if (!clang_isDeclaration(C.kind))
6635 return 0;
6636
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006637 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006638 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006639 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006640 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6641}
6642
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006643unsigned clang_CXXMethod_isConst(CXCursor C) {
6644 if (!clang_isDeclaration(C.kind))
6645 return 0;
6646
6647 const Decl *D = cxcursor::getCursorDecl(C);
6648 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006649 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006650 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6651}
6652
Guy Benyei11169dd2012-12-18 14:30:41 +00006653unsigned clang_CXXMethod_isStatic(CXCursor C) {
6654 if (!clang_isDeclaration(C.kind))
6655 return 0;
6656
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006657 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006658 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006659 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006660 return (Method && Method->isStatic()) ? 1 : 0;
6661}
6662
6663unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6664 if (!clang_isDeclaration(C.kind))
6665 return 0;
6666
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006667 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006668 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006669 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006670 return (Method && Method->isVirtual()) ? 1 : 0;
6671}
6672} // end: extern "C"
6673
6674//===----------------------------------------------------------------------===//
6675// Attribute introspection.
6676//===----------------------------------------------------------------------===//
6677
6678extern "C" {
6679CXType clang_getIBOutletCollectionType(CXCursor C) {
6680 if (C.kind != CXCursor_IBOutletCollectionAttr)
6681 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6682
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006683 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006684 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6685
6686 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6687}
6688} // end: extern "C"
6689
6690//===----------------------------------------------------------------------===//
6691// Inspecting memory usage.
6692//===----------------------------------------------------------------------===//
6693
6694typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6695
6696static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6697 enum CXTUResourceUsageKind k,
6698 unsigned long amount) {
6699 CXTUResourceUsageEntry entry = { k, amount };
6700 entries.push_back(entry);
6701}
6702
6703extern "C" {
6704
6705const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6706 const char *str = "";
6707 switch (kind) {
6708 case CXTUResourceUsage_AST:
6709 str = "ASTContext: expressions, declarations, and types";
6710 break;
6711 case CXTUResourceUsage_Identifiers:
6712 str = "ASTContext: identifiers";
6713 break;
6714 case CXTUResourceUsage_Selectors:
6715 str = "ASTContext: selectors";
6716 break;
6717 case CXTUResourceUsage_GlobalCompletionResults:
6718 str = "Code completion: cached global results";
6719 break;
6720 case CXTUResourceUsage_SourceManagerContentCache:
6721 str = "SourceManager: content cache allocator";
6722 break;
6723 case CXTUResourceUsage_AST_SideTables:
6724 str = "ASTContext: side tables";
6725 break;
6726 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6727 str = "SourceManager: malloc'ed memory buffers";
6728 break;
6729 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6730 str = "SourceManager: mmap'ed memory buffers";
6731 break;
6732 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6733 str = "ExternalASTSource: malloc'ed memory buffers";
6734 break;
6735 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6736 str = "ExternalASTSource: mmap'ed memory buffers";
6737 break;
6738 case CXTUResourceUsage_Preprocessor:
6739 str = "Preprocessor: malloc'ed memory";
6740 break;
6741 case CXTUResourceUsage_PreprocessingRecord:
6742 str = "Preprocessor: PreprocessingRecord";
6743 break;
6744 case CXTUResourceUsage_SourceManager_DataStructures:
6745 str = "SourceManager: data structures and tables";
6746 break;
6747 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6748 str = "Preprocessor: header search tables";
6749 break;
6750 }
6751 return str;
6752}
6753
6754CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006755 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006756 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006757 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00006758 return usage;
6759 }
6760
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006761 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006762 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006763 ASTContext &astContext = astUnit->getASTContext();
6764
6765 // How much memory is used by AST nodes and types?
6766 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6767 (unsigned long) astContext.getASTAllocatedMemory());
6768
6769 // How much memory is used by identifiers?
6770 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6771 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6772
6773 // How much memory is used for selectors?
6774 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6775 (unsigned long) astContext.Selectors.getTotalMemory());
6776
6777 // How much memory is used by ASTContext's side tables?
6778 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6779 (unsigned long) astContext.getSideTableAllocatedMemory());
6780
6781 // How much memory is used for caching global code completion results?
6782 unsigned long completionBytes = 0;
6783 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00006784 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006785 completionBytes = completionAllocator->getTotalMemory();
6786 }
6787 createCXTUResourceUsageEntry(*entries,
6788 CXTUResourceUsage_GlobalCompletionResults,
6789 completionBytes);
6790
6791 // How much memory is being used by SourceManager's content cache?
6792 createCXTUResourceUsageEntry(*entries,
6793 CXTUResourceUsage_SourceManagerContentCache,
6794 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6795
6796 // How much memory is being used by the MemoryBuffer's in SourceManager?
6797 const SourceManager::MemoryBufferSizes &srcBufs =
6798 astUnit->getSourceManager().getMemoryBufferSizes();
6799
6800 createCXTUResourceUsageEntry(*entries,
6801 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6802 (unsigned long) srcBufs.malloc_bytes);
6803 createCXTUResourceUsageEntry(*entries,
6804 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6805 (unsigned long) srcBufs.mmap_bytes);
6806 createCXTUResourceUsageEntry(*entries,
6807 CXTUResourceUsage_SourceManager_DataStructures,
6808 (unsigned long) astContext.getSourceManager()
6809 .getDataStructureSizes());
6810
6811 // How much memory is being used by the ExternalASTSource?
6812 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6813 const ExternalASTSource::MemoryBufferSizes &sizes =
6814 esrc->getMemoryBufferSizes();
6815
6816 createCXTUResourceUsageEntry(*entries,
6817 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6818 (unsigned long) sizes.malloc_bytes);
6819 createCXTUResourceUsageEntry(*entries,
6820 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6821 (unsigned long) sizes.mmap_bytes);
6822 }
6823
6824 // How much memory is being used by the Preprocessor?
6825 Preprocessor &pp = astUnit->getPreprocessor();
6826 createCXTUResourceUsageEntry(*entries,
6827 CXTUResourceUsage_Preprocessor,
6828 pp.getTotalMemory());
6829
6830 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6831 createCXTUResourceUsageEntry(*entries,
6832 CXTUResourceUsage_PreprocessingRecord,
6833 pRec->getTotalMemory());
6834 }
6835
6836 createCXTUResourceUsageEntry(*entries,
6837 CXTUResourceUsage_Preprocessor_HeaderSearch,
6838 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00006839
Guy Benyei11169dd2012-12-18 14:30:41 +00006840 CXTUResourceUsage usage = { (void*) entries.get(),
6841 (unsigned) entries->size(),
Craig Topper69186e72014-06-08 08:38:04 +00006842 entries->size() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006843 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006844 return usage;
6845}
6846
6847void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6848 if (usage.data)
6849 delete (MemUsageEntries*) usage.data;
6850}
6851
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006852CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6853 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006854 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00006855 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006856
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006857 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006858 LOG_BAD_TU(TU);
6859 return skipped;
6860 }
6861
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006862 if (!file)
6863 return skipped;
6864
6865 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6866 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6867 if (!ppRec)
6868 return skipped;
6869
6870 ASTContext &Ctx = astUnit->getASTContext();
6871 SourceManager &sm = Ctx.getSourceManager();
6872 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6873 FileID wantedFileID = sm.translateFile(fileEntry);
6874
6875 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6876 std::vector<SourceRange> wantedRanges;
6877 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6878 i != ei; ++i) {
6879 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6880 wantedRanges.push_back(*i);
6881 }
6882
6883 skipped->count = wantedRanges.size();
6884 skipped->ranges = new CXSourceRange[skipped->count];
6885 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6886 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6887
6888 return skipped;
6889}
6890
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006891void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6892 if (ranges) {
6893 delete[] ranges->ranges;
6894 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006895 }
6896}
6897
Guy Benyei11169dd2012-12-18 14:30:41 +00006898} // end extern "C"
6899
6900void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6901 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6902 for (unsigned I = 0; I != Usage.numEntries; ++I)
6903 fprintf(stderr, " %s: %lu\n",
6904 clang_getTUResourceUsageName(Usage.entries[I].kind),
6905 Usage.entries[I].amount);
6906
6907 clang_disposeCXTUResourceUsage(Usage);
6908}
6909
6910//===----------------------------------------------------------------------===//
6911// Misc. utility functions.
6912//===----------------------------------------------------------------------===//
6913
6914/// Default to using an 8 MB stack size on "safety" threads.
6915static unsigned SafetyStackThreadSize = 8 << 20;
6916
6917namespace clang {
6918
6919bool RunSafely(llvm::CrashRecoveryContext &CRC,
6920 void (*Fn)(void*), void *UserData,
6921 unsigned Size) {
6922 if (!Size)
6923 Size = GetSafetyThreadStackSize();
6924 if (Size)
6925 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6926 return CRC.RunSafely(Fn, UserData);
6927}
6928
6929unsigned GetSafetyThreadStackSize() {
6930 return SafetyStackThreadSize;
6931}
6932
6933void SetSafetyThreadStackSize(unsigned Value) {
6934 SafetyStackThreadSize = Value;
6935}
6936
6937}
6938
6939void clang::setThreadBackgroundPriority() {
6940 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6941 return;
6942
Alp Toker1a86ad22014-07-06 06:24:00 +00006943#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00006944 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6945#endif
6946}
6947
6948void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6949 if (!Unit)
6950 return;
6951
6952 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6953 DEnd = Unit->stored_diag_end();
6954 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006955 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006956 CXString Msg = clang_formatDiagnostic(&Diag,
6957 clang_defaultDiagnosticDisplayOptions());
6958 fprintf(stderr, "%s\n", clang_getCString(Msg));
6959 clang_disposeString(Msg);
6960 }
6961#ifdef LLVM_ON_WIN32
6962 // On Windows, force a flush, since there may be multiple copies of
6963 // stderr and stdout in the file system, all with different buffers
6964 // but writing to the same device.
6965 fflush(stderr);
6966#endif
6967}
6968
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006969MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6970 SourceLocation MacroDefLoc,
6971 CXTranslationUnit TU){
6972 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006973 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006974 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00006975 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006976
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006977 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006978 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006979 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006980 if (MD) {
6981 for (MacroDirective::DefInfo
6982 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6983 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6984 return Def.getMacroInfo();
6985 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006986 }
6987
Craig Topper69186e72014-06-08 08:38:04 +00006988 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006989}
6990
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006991const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6992 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006993 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00006994 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006995 const IdentifierInfo *II = MacroDef->getName();
6996 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00006997 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006998
6999 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7000}
7001
7002MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7003 const Token &Tok,
7004 CXTranslationUnit TU) {
7005 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007006 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007007 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007008 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007009
7010 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007011 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007012 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7013 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007014 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007015
7016 // Check that the token is inside the definition and not its argument list.
7017 SourceManager &SM = Unit->getSourceManager();
7018 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007019 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007020 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007021 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007022
7023 Preprocessor &PP = Unit->getPreprocessor();
7024 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7025 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007026 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007027
Alp Toker2d57cea2014-05-17 04:53:25 +00007028 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007029 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007030 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007031
7032 // Check that the identifier is not one of the macro arguments.
7033 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007034 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007035
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007036 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7037 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007038 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007039
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007040 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007041}
7042
7043MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7044 SourceLocation Loc,
7045 CXTranslationUnit TU) {
7046 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007047 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007048
7049 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007050 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007051 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007052 Preprocessor &PP = Unit->getPreprocessor();
7053 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007054 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007055 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7056 Token Tok;
7057 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007058 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007059
7060 return checkForMacroInMacroDefinition(MI, Tok, TU);
7061}
7062
Guy Benyei11169dd2012-12-18 14:30:41 +00007063extern "C" {
7064
7065CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007066 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007067}
7068
7069} // end: extern "C"
7070
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007071Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7072 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007073 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007074 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007075 if (Unit->isMainFileAST())
7076 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007077 return *this;
7078 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007079 } else {
7080 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007081 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007082 return *this;
7083}
7084
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007085Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7086 *this << FE->getName();
7087 return *this;
7088}
7089
7090Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7091 CXString cursorName = clang_getCursorDisplayName(cursor);
7092 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7093 clang_disposeString(cursorName);
7094 return *this;
7095}
7096
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007097Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7098 CXFile File;
7099 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007100 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007101 CXString FileName = clang_getFileName(File);
7102 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7103 clang_disposeString(FileName);
7104 return *this;
7105}
7106
7107Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7108 CXSourceLocation BLoc = clang_getRangeStart(range);
7109 CXSourceLocation ELoc = clang_getRangeEnd(range);
7110
7111 CXFile BFile;
7112 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007113 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007114
7115 CXFile EFile;
7116 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007117 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007118
7119 CXString BFileName = clang_getFileName(BFile);
7120 if (BFile == EFile) {
7121 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7122 BLine, BColumn, ELine, EColumn);
7123 } else {
7124 CXString EFileName = clang_getFileName(EFile);
7125 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7126 BLine, BColumn)
7127 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7128 ELine, EColumn);
7129 clang_disposeString(EFileName);
7130 }
7131 clang_disposeString(BFileName);
7132 return *this;
7133}
7134
7135Logger &cxindex::Logger::operator<<(CXString Str) {
7136 *this << clang_getCString(Str);
7137 return *this;
7138}
7139
7140Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7141 LogOS << Fmt;
7142 return *this;
7143}
7144
Chandler Carruth37ad2582014-06-27 15:14:39 +00007145static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7146
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007147cxindex::Logger::~Logger() {
7148 LogOS.flush();
7149
Chandler Carruth37ad2582014-06-27 15:14:39 +00007150 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007151
7152 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7153
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007154 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007155 OS << "[libclang:" << Name << ':';
7156
Alp Toker1a86ad22014-07-06 06:24:00 +00007157#ifdef USE_DARWIN_THREADS
7158 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007159 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7160 OS << tid << ':';
7161#endif
7162
7163 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7164 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7165 OS << Msg.str() << '\n';
7166
7167 if (Trace) {
7168 llvm::sys::PrintStackTrace(stderr);
7169 OS << "--------------------------------------------------\n";
7170 }
7171}