blob: e1219337ac6f57d9e1d59d17a3b03115515ff387 [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"
Saleem Abdulrasool5e03c652016-02-06 22:36:34 +000027#include "clang/AST/VTableBuilder.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000028#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000029#include "clang/Basic/DiagnosticCategories.h"
30#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000031#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000032#include "clang/Basic/Version.h"
33#include "clang/Frontend/ASTUnit.h"
34#include "clang/Frontend/CompilerInstance.h"
35#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000036#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000037#include "clang/Lex/HeaderSearch.h"
38#include "clang/Lex/Lexer.h"
39#include "clang/Lex/PreprocessingRecord.h"
40#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000041#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000042#include "llvm/ADT/Optional.h"
43#include "llvm/ADT/STLExtras.h"
44#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000045#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000046#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000048#include "llvm/Support/Compiler.h"
49#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000050#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000051#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000052#include "llvm/Support/MemoryBuffer.h"
53#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000054#include "llvm/Support/Program.h"
55#include "llvm/Support/SaveAndRestore.h"
56#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000057#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000058#include "llvm/Support/Threading.h"
59#include "llvm/Support/Timer.h"
60#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000061
Alp Toker1a86ad22014-07-06 06:24:00 +000062#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
63#define USE_DARWIN_THREADS
64#endif
65
66#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000067#include <pthread.h>
68#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000069
70using namespace clang;
71using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000072using namespace clang::cxtu;
73using namespace clang::cxindex;
74
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000075CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
76 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000077 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000078 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000079 CXTranslationUnit D = new CXTranslationUnitImpl();
80 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000081 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000082 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000084 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000085 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000086 return D;
87}
88
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000089bool cxtu::isASTReadError(ASTUnit *AU) {
90 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
91 DEnd = AU->stored_diag_end();
92 D != DEnd; ++D) {
93 if (D->getLevel() >= DiagnosticsEngine::Error &&
94 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
95 diag::DiagCat_AST_Deserialization_Issue)
96 return true;
97 }
98 return false;
99}
100
Guy Benyei11169dd2012-12-18 14:30:41 +0000101cxtu::CXTUOwner::~CXTUOwner() {
102 if (TU)
103 clang_disposeTranslationUnit(TU);
104}
105
106/// \brief Compare two source ranges to determine their relative position in
107/// the translation unit.
108static RangeComparisonResult RangeCompare(SourceManager &SM,
109 SourceRange R1,
110 SourceRange R2) {
111 assert(R1.isValid() && "First range is invalid?");
112 assert(R2.isValid() && "Second range is invalid?");
113 if (R1.getEnd() != R2.getBegin() &&
114 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
115 return RangeBefore;
116 if (R2.getEnd() != R1.getBegin() &&
117 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
118 return RangeAfter;
119 return RangeOverlap;
120}
121
122/// \brief Determine if a source location falls within, before, or after a
123/// a given source range.
124static RangeComparisonResult LocationCompare(SourceManager &SM,
125 SourceLocation L, SourceRange R) {
126 assert(R.isValid() && "First range is invalid?");
127 assert(L.isValid() && "Second range is invalid?");
128 if (L == R.getBegin() || L == R.getEnd())
129 return RangeOverlap;
130 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
131 return RangeBefore;
132 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
133 return RangeAfter;
134 return RangeOverlap;
135}
136
137/// \brief Translate a Clang source range into a CIndex source range.
138///
139/// Clang internally represents ranges where the end location points to the
140/// start of the token at the end. However, for external clients it is more
141/// useful to have a CXSourceRange be a proper half-open interval. This routine
142/// does the appropriate translation.
143CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
144 const LangOptions &LangOpts,
145 const CharSourceRange &R) {
146 // We want the last character in this location, so we will adjust the
147 // location accordingly.
148 SourceLocation EndLoc = R.getEnd();
149 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
150 EndLoc = SM.getExpansionRange(EndLoc).second;
Yaron Keren8b563662015-10-03 10:46:20 +0000151 if (R.isTokenRange() && EndLoc.isValid()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000152 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
153 SM, LangOpts);
154 EndLoc = EndLoc.getLocWithOffset(Length);
155 }
156
Bill Wendlingeade3622013-01-23 08:25:41 +0000157 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000158 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000159 R.getBegin().getRawEncoding(),
160 EndLoc.getRawEncoding()
161 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000162 return Result;
163}
164
165//===----------------------------------------------------------------------===//
166// Cursor visitor.
167//===----------------------------------------------------------------------===//
168
169static SourceRange getRawCursorExtent(CXCursor C);
170static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
171
172
173RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
174 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
175}
176
177/// \brief Visit the given cursor and, if requested by the visitor,
178/// its children.
179///
180/// \param Cursor the cursor to visit.
181///
182/// \param CheckedRegionOfInterest if true, then the caller already checked
183/// that this cursor is within the region of interest.
184///
185/// \returns true if the visitation should be aborted, false if it
186/// should continue.
187bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
188 if (clang_isInvalid(Cursor.kind))
189 return false;
190
191 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000192 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000193 if (!D) {
194 assert(0 && "Invalid declaration cursor");
195 return true; // abort.
196 }
197
198 // Ignore implicit declarations, unless it's an objc method because
199 // currently we should report implicit methods for properties when indexing.
200 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
201 return false;
202 }
203
204 // If we have a range of interest, and this cursor doesn't intersect with it,
205 // we're done.
206 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
207 SourceRange Range = getRawCursorExtent(Cursor);
208 if (Range.isInvalid() || CompareRegionOfInterest(Range))
209 return false;
210 }
211
212 switch (Visitor(Cursor, Parent, ClientData)) {
213 case CXChildVisit_Break:
214 return true;
215
216 case CXChildVisit_Continue:
217 return false;
218
219 case CXChildVisit_Recurse: {
220 bool ret = VisitChildren(Cursor);
221 if (PostChildrenVisitor)
222 if (PostChildrenVisitor(Cursor, ClientData))
223 return true;
224 return ret;
225 }
226 }
227
228 llvm_unreachable("Invalid CXChildVisitResult!");
229}
230
231static bool visitPreprocessedEntitiesInRange(SourceRange R,
232 PreprocessingRecord &PPRec,
233 CursorVisitor &Visitor) {
234 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
235 FileID FID;
236
237 if (!Visitor.shouldVisitIncludedEntities()) {
238 // If the begin/end of the range lie in the same FileID, do the optimization
239 // where we skip preprocessed entities that do not come from the same FileID.
240 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
241 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
242 FID = FileID();
243 }
244
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000245 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
246 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000247 PPRec, FID);
248}
249
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000250bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000251 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000252 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000253
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000254 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000255 SourceManager &SM = Unit->getSourceManager();
256
257 std::pair<FileID, unsigned>
258 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
259 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
260
261 if (End.first != Begin.first) {
262 // If the end does not reside in the same file, try to recover by
263 // picking the end of the file of begin location.
264 End.first = Begin.first;
265 End.second = SM.getFileIDSize(Begin.first);
266 }
267
268 assert(Begin.first == End.first);
269 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000270 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000271
272 FileID File = Begin.first;
273 unsigned Offset = Begin.second;
274 unsigned Length = End.second - Begin.second;
275
276 if (!VisitDeclsOnly && !VisitPreprocessorLast)
277 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000278 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000279
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000280 if (visitDeclsFromFileRegion(File, Offset, Length))
281 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000282
283 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000284 return visitPreprocessedEntitiesInRegion();
285
286 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000287}
288
289static bool isInLexicalContext(Decl *D, DeclContext *DC) {
290 if (!DC)
291 return false;
292
293 for (DeclContext *DeclDC = D->getLexicalDeclContext();
294 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
295 if (DeclDC == DC)
296 return true;
297 }
298 return false;
299}
300
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000301bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000302 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000303 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000304 SourceManager &SM = Unit->getSourceManager();
305 SourceRange Range = RegionOfInterest;
306
307 SmallVector<Decl *, 16> Decls;
308 Unit->findFileRegionDecls(File, Offset, Length, Decls);
309
310 // If we didn't find any file level decls for the file, try looking at the
311 // file that it was included from.
312 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
313 bool Invalid = false;
314 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
315 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000316 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000317
318 SourceLocation Outer;
319 if (SLEntry.isFile())
320 Outer = SLEntry.getFile().getIncludeLoc();
321 else
322 Outer = SLEntry.getExpansion().getExpansionLocStart();
323 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000324 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000325
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000326 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000327 Length = 0;
328 Unit->findFileRegionDecls(File, Offset, Length, Decls);
329 }
330
331 assert(!Decls.empty());
332
333 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000334 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000335 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
336 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000337 Decl *D = *DIt;
338 if (D->getSourceRange().isInvalid())
339 continue;
340
341 if (isInLexicalContext(D, CurDC))
342 continue;
343
344 CurDC = dyn_cast<DeclContext>(D);
345
346 if (TagDecl *TD = dyn_cast<TagDecl>(D))
347 if (!TD->isFreeStanding())
348 continue;
349
350 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
351 if (CompRes == RangeBefore)
352 continue;
353 if (CompRes == RangeAfter)
354 break;
355
356 assert(CompRes == RangeOverlap);
357 VisitedAtLeastOnce = true;
358
359 if (isa<ObjCContainerDecl>(D)) {
360 FileDI_current = &DIt;
361 FileDE_current = DE;
362 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000363 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000364 }
365
366 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000367 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000368 }
369
370 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000371 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000372
373 // No Decls overlapped with the range. Move up the lexical context until there
374 // is a context that contains the range or we reach the translation unit
375 // level.
376 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
377 : (*(DIt-1))->getLexicalDeclContext();
378
379 while (DC && !DC->isTranslationUnit()) {
380 Decl *D = cast<Decl>(DC);
381 SourceRange CurDeclRange = D->getSourceRange();
382 if (CurDeclRange.isInvalid())
383 break;
384
385 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000386 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
387 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000388 }
389
390 DC = D->getLexicalDeclContext();
391 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000392
393 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000394}
395
396bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
397 if (!AU->getPreprocessor().getPreprocessingRecord())
398 return false;
399
400 PreprocessingRecord &PPRec
401 = *AU->getPreprocessor().getPreprocessingRecord();
402 SourceManager &SM = AU->getSourceManager();
403
404 if (RegionOfInterest.isValid()) {
405 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
406 SourceLocation B = MappedRange.getBegin();
407 SourceLocation E = MappedRange.getEnd();
408
409 if (AU->isInPreambleFileID(B)) {
410 if (SM.isLoadedSourceLocation(E))
411 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
412 PPRec, *this);
413
414 // Beginning of range lies in the preamble but it also extends beyond
415 // it into the main file. Split the range into 2 parts, one covering
416 // the preamble and another covering the main file. This allows subsequent
417 // calls to visitPreprocessedEntitiesInRange to accept a source range that
418 // lies in the same FileID, allowing it to skip preprocessed entities that
419 // do not come from the same FileID.
420 bool breaked =
421 visitPreprocessedEntitiesInRange(
422 SourceRange(B, AU->getEndOfPreambleFileID()),
423 PPRec, *this);
424 if (breaked) return true;
425 return visitPreprocessedEntitiesInRange(
426 SourceRange(AU->getStartOfMainFileID(), E),
427 PPRec, *this);
428 }
429
430 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
431 }
432
433 bool OnlyLocalDecls
434 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
435
436 if (OnlyLocalDecls)
437 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
438 PPRec);
439
440 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
441}
442
443template<typename InputIterator>
444bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
445 InputIterator Last,
446 PreprocessingRecord &PPRec,
447 FileID FID) {
448 for (; First != Last; ++First) {
449 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
450 continue;
451
452 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000453 if (!PPE)
454 continue;
455
Guy Benyei11169dd2012-12-18 14:30:41 +0000456 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
457 if (Visit(MakeMacroExpansionCursor(ME, TU)))
458 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000459
Guy Benyei11169dd2012-12-18 14:30:41 +0000460 continue;
461 }
Richard Smith66a81862015-05-04 02:25:31 +0000462
463 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000464 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
465 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000466
Guy Benyei11169dd2012-12-18 14:30:41 +0000467 continue;
468 }
469
470 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
471 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
472 return true;
473
474 continue;
475 }
476 }
477
478 return false;
479}
480
481/// \brief Visit the children of the given cursor.
482///
483/// \returns true if the visitation should be aborted, false if it
484/// should continue.
485bool CursorVisitor::VisitChildren(CXCursor Cursor) {
486 if (clang_isReference(Cursor.kind) &&
487 Cursor.kind != CXCursor_CXXBaseSpecifier) {
488 // By definition, references have no children.
489 return false;
490 }
491
492 // Set the Parent field to Cursor, then back to its old value once we're
493 // done.
494 SetParentRAII SetParent(Parent, StmtParent, Cursor);
495
496 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000497 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000498 if (!D)
499 return false;
500
501 return VisitAttributes(D) || Visit(D);
502 }
503
504 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000505 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000506 return Visit(S);
507
508 return false;
509 }
510
511 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000512 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000513 return Visit(E);
514
515 return false;
516 }
517
518 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000519 CXTranslationUnit TU = getCursorTU(Cursor);
520 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000521
522 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
523 for (unsigned I = 0; I != 2; ++I) {
524 if (VisitOrder[I]) {
525 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
526 RegionOfInterest.isInvalid()) {
527 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
528 TLEnd = CXXUnit->top_level_end();
529 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000530 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000531 return true;
532 }
533 } else if (VisitDeclContext(
534 CXXUnit->getASTContext().getTranslationUnitDecl()))
535 return true;
536 continue;
537 }
538
539 // Walk the preprocessing record.
540 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
541 visitPreprocessedEntitiesInRegion();
542 }
543
544 return false;
545 }
546
547 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000548 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000549 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
550 return Visit(BaseTSInfo->getTypeLoc());
551 }
552 }
553 }
554
555 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000556 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000557 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000558 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000559 return Visit(cxcursor::MakeCursorObjCClassRef(
560 ObjT->getInterface(),
561 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000562 }
563
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 // If pointing inside a macro definition, check if the token is an identifier
565 // that was ever defined as a macro. In such a case, create a "pseudo" macro
566 // expansion cursor for that token.
567 SourceLocation BeginLoc = RegionOfInterest.getBegin();
568 if (Cursor.kind == CXCursor_MacroDefinition &&
569 BeginLoc == RegionOfInterest.getEnd()) {
570 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000571 const MacroInfo *MI =
572 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000573 if (MacroDefinitionRecord *MacroDef =
574 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000575 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
576 }
577
Guy Benyei11169dd2012-12-18 14:30:41 +0000578 // Nothing to visit at the moment.
579 return false;
580}
581
582bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
583 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
584 if (Visit(TSInfo->getTypeLoc()))
585 return true;
586
587 if (Stmt *Body = B->getBody())
588 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
589
590 return false;
591}
592
Ted Kremenek03325582013-02-21 01:29:01 +0000593Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000594 if (RegionOfInterest.isValid()) {
595 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
596 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000597 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000598
599 switch (CompareRegionOfInterest(Range)) {
600 case RangeBefore:
601 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000602 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000603
604 case RangeAfter:
605 // This declaration comes after the region of interest; we're done.
606 return false;
607
608 case RangeOverlap:
609 // This declaration overlaps the region of interest; visit it.
610 break;
611 }
612 }
613 return true;
614}
615
616bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
617 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
618
619 // FIXME: Eventually remove. This part of a hack to support proper
620 // iteration over all Decls contained lexically within an ObjC container.
621 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
622 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
623
624 for ( ; I != E; ++I) {
625 Decl *D = *I;
626 if (D->getLexicalDeclContext() != DC)
627 continue;
628 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
629
630 // Ignore synthesized ivars here, otherwise if we have something like:
631 // @synthesize prop = _prop;
632 // and '_prop' is not declared, we will encounter a '_prop' ivar before
633 // encountering the 'prop' synthesize declaration and we will think that
634 // we passed the region-of-interest.
635 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
636 if (ivarD->getSynthesize())
637 continue;
638 }
639
640 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
641 // declarations is a mismatch with the compiler semantics.
642 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
643 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
644 if (!ID->isThisDeclarationADefinition())
645 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
646
647 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
648 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
649 if (!PD->isThisDeclarationADefinition())
650 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
651 }
652
Ted Kremenek03325582013-02-21 01:29:01 +0000653 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000654 if (!V.hasValue())
655 continue;
656 if (!V.getValue())
657 return false;
658 if (Visit(Cursor, true))
659 return true;
660 }
661 return false;
662}
663
664bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
665 llvm_unreachable("Translation units are visited directly by Visit()");
666}
667
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000668bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
669 if (VisitTemplateParameters(D->getTemplateParameters()))
670 return true;
671
672 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
673}
674
Guy Benyei11169dd2012-12-18 14:30:41 +0000675bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
676 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
677 return Visit(TSInfo->getTypeLoc());
678
679 return false;
680}
681
682bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
683 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
684 return Visit(TSInfo->getTypeLoc());
685
686 return false;
687}
688
689bool CursorVisitor::VisitTagDecl(TagDecl *D) {
690 return VisitDeclContext(D);
691}
692
693bool CursorVisitor::VisitClassTemplateSpecializationDecl(
694 ClassTemplateSpecializationDecl *D) {
695 bool ShouldVisitBody = false;
696 switch (D->getSpecializationKind()) {
697 case TSK_Undeclared:
698 case TSK_ImplicitInstantiation:
699 // Nothing to visit
700 return false;
701
702 case TSK_ExplicitInstantiationDeclaration:
703 case TSK_ExplicitInstantiationDefinition:
704 break;
705
706 case TSK_ExplicitSpecialization:
707 ShouldVisitBody = true;
708 break;
709 }
710
711 // Visit the template arguments used in the specialization.
712 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
713 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000714 if (TemplateSpecializationTypeLoc TSTLoc =
715 TL.getAs<TemplateSpecializationTypeLoc>()) {
716 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
717 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000718 return true;
719 }
720 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000721
722 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000723}
724
725bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
726 ClassTemplatePartialSpecializationDecl *D) {
727 // FIXME: Visit the "outer" template parameter lists on the TagDecl
728 // before visiting these template parameters.
729 if (VisitTemplateParameters(D->getTemplateParameters()))
730 return true;
731
732 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000733 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
734 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
735 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000736 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
737 return true;
738
739 return VisitCXXRecordDecl(D);
740}
741
742bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
743 // Visit the default argument.
744 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
745 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
746 if (Visit(DefArg->getTypeLoc()))
747 return true;
748
749 return false;
750}
751
752bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
753 if (Expr *Init = D->getInitExpr())
754 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
755 return false;
756}
757
758bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000759 unsigned NumParamList = DD->getNumTemplateParameterLists();
760 for (unsigned i = 0; i < NumParamList; i++) {
761 TemplateParameterList* Params = DD->getTemplateParameterList(i);
762 if (VisitTemplateParameters(Params))
763 return true;
764 }
765
Guy Benyei11169dd2012-12-18 14:30:41 +0000766 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
767 if (Visit(TSInfo->getTypeLoc()))
768 return true;
769
770 // Visit the nested-name-specifier, if present.
771 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
772 if (VisitNestedNameSpecifierLoc(QualifierLoc))
773 return true;
774
775 return false;
776}
777
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000778/// \brief Compare two base or member initializers based on their source order.
779static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
780 CXXCtorInitializer *const *Y) {
781 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
782}
783
Guy Benyei11169dd2012-12-18 14:30:41 +0000784bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000785 unsigned NumParamList = ND->getNumTemplateParameterLists();
786 for (unsigned i = 0; i < NumParamList; i++) {
787 TemplateParameterList* Params = ND->getTemplateParameterList(i);
788 if (VisitTemplateParameters(Params))
789 return true;
790 }
791
Guy Benyei11169dd2012-12-18 14:30:41 +0000792 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
793 // Visit the function declaration's syntactic components in the order
794 // written. This requires a bit of work.
795 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000796 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000797
798 // If we have a function declared directly (without the use of a typedef),
799 // visit just the return type. Otherwise, just visit the function's type
800 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000801 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000802 (!FTL && Visit(TL)))
803 return true;
804
805 // Visit the nested-name-specifier, if present.
806 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
807 if (VisitNestedNameSpecifierLoc(QualifierLoc))
808 return true;
809
810 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000811 if (!isa<CXXDestructorDecl>(ND))
812 if (VisitDeclarationNameInfo(ND->getNameInfo()))
813 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000814
815 // FIXME: Visit explicitly-specified template arguments!
816
817 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000818 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000819 return true;
820
Bill Wendling44426052012-12-20 19:22:21 +0000821 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000822 }
823
824 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
825 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
826 // Find the initializers that were written in the source.
827 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000828 for (auto *I : Constructor->inits()) {
829 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000830 continue;
831
Aaron Ballman0ad78302014-03-13 17:34:31 +0000832 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000833 }
834
835 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000836 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
837 &CompareCXXCtorInitializers);
838
Guy Benyei11169dd2012-12-18 14:30:41 +0000839 // Visit the initializers in source order
840 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
841 CXXCtorInitializer *Init = WrittenInits[I];
842 if (Init->isAnyMemberInitializer()) {
843 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
844 Init->getMemberLocation(), TU)))
845 return true;
846 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
847 if (Visit(TInfo->getTypeLoc()))
848 return true;
849 }
850
851 // Visit the initializer value.
852 if (Expr *Initializer = Init->getInit())
853 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
854 return true;
855 }
856 }
857
858 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
859 return true;
860 }
861
862 return false;
863}
864
865bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
866 if (VisitDeclaratorDecl(D))
867 return true;
868
869 if (Expr *BitWidth = D->getBitWidth())
870 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
871
872 return false;
873}
874
875bool CursorVisitor::VisitVarDecl(VarDecl *D) {
876 if (VisitDeclaratorDecl(D))
877 return true;
878
879 if (Expr *Init = D->getInit())
880 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
881
882 return false;
883}
884
885bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
886 if (VisitDeclaratorDecl(D))
887 return true;
888
889 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
890 if (Expr *DefArg = D->getDefaultArgument())
891 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
892
893 return false;
894}
895
896bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
897 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
898 // before visiting these template parameters.
899 if (VisitTemplateParameters(D->getTemplateParameters()))
900 return true;
901
902 return VisitFunctionDecl(D->getTemplatedDecl());
903}
904
905bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
906 // FIXME: Visit the "outer" template parameter lists on the TagDecl
907 // before visiting these template parameters.
908 if (VisitTemplateParameters(D->getTemplateParameters()))
909 return true;
910
911 return VisitCXXRecordDecl(D->getTemplatedDecl());
912}
913
914bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
915 if (VisitTemplateParameters(D->getTemplateParameters()))
916 return true;
917
918 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
919 VisitTemplateArgumentLoc(D->getDefaultArgument()))
920 return true;
921
922 return false;
923}
924
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000925bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
926 // Visit the bound, if it's explicit.
927 if (D->hasExplicitBound()) {
928 if (auto TInfo = D->getTypeSourceInfo()) {
929 if (Visit(TInfo->getTypeLoc()))
930 return true;
931 }
932 }
933
934 return false;
935}
936
Guy Benyei11169dd2012-12-18 14:30:41 +0000937bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000938 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000939 if (Visit(TSInfo->getTypeLoc()))
940 return true;
941
Aaron Ballman43b68be2014-03-07 17:50:17 +0000942 for (const auto *P : ND->params()) {
943 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000944 return true;
945 }
946
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000947 return ND->isThisDeclarationADefinition() &&
948 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000949}
950
951template <typename DeclIt>
952static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
953 SourceManager &SM, SourceLocation EndLoc,
954 SmallVectorImpl<Decl *> &Decls) {
955 DeclIt next = *DI_current;
956 while (++next != DE_current) {
957 Decl *D_next = *next;
958 if (!D_next)
959 break;
960 SourceLocation L = D_next->getLocStart();
961 if (!L.isValid())
962 break;
963 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
964 *DI_current = next;
965 Decls.push_back(D_next);
966 continue;
967 }
968 break;
969 }
970}
971
Guy Benyei11169dd2012-12-18 14:30:41 +0000972bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
973 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
974 // an @implementation can lexically contain Decls that are not properly
975 // nested in the AST. When we identify such cases, we need to retrofit
976 // this nesting here.
977 if (!DI_current && !FileDI_current)
978 return VisitDeclContext(D);
979
980 // Scan the Decls that immediately come after the container
981 // in the current DeclContext. If any fall within the
982 // container's lexical region, stash them into a vector
983 // for later processing.
984 SmallVector<Decl *, 24> DeclsInContainer;
985 SourceLocation EndLoc = D->getSourceRange().getEnd();
986 SourceManager &SM = AU->getSourceManager();
987 if (EndLoc.isValid()) {
988 if (DI_current) {
989 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
990 DeclsInContainer);
991 } else {
992 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
993 DeclsInContainer);
994 }
995 }
996
997 // The common case.
998 if (DeclsInContainer.empty())
999 return VisitDeclContext(D);
1000
1001 // Get all the Decls in the DeclContext, and sort them with the
1002 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001003 for (auto *SubDecl : D->decls()) {
1004 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1005 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001007 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001008 }
1009
1010 // Now sort the Decls so that they appear in lexical order.
1011 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001012 [&SM](Decl *A, Decl *B) {
1013 SourceLocation L_A = A->getLocStart();
1014 SourceLocation L_B = B->getLocStart();
1015 assert(L_A.isValid() && L_B.isValid());
1016 return SM.isBeforeInTranslationUnit(L_A, L_B);
1017 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001018
1019 // Now visit the decls.
1020 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1021 E = DeclsInContainer.end(); I != E; ++I) {
1022 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001023 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001024 if (!V.hasValue())
1025 continue;
1026 if (!V.getValue())
1027 return false;
1028 if (Visit(Cursor, true))
1029 return true;
1030 }
1031 return false;
1032}
1033
1034bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1035 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1036 TU)))
1037 return true;
1038
Douglas Gregore9d95f12015-07-07 03:57:35 +00001039 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1040 return true;
1041
Guy Benyei11169dd2012-12-18 14:30:41 +00001042 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1043 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1044 E = ND->protocol_end(); I != E; ++I, ++PL)
1045 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1046 return true;
1047
1048 return VisitObjCContainerDecl(ND);
1049}
1050
1051bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1052 if (!PID->isThisDeclarationADefinition())
1053 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1054
1055 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1056 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1057 E = PID->protocol_end(); I != E; ++I, ++PL)
1058 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1059 return true;
1060
1061 return VisitObjCContainerDecl(PID);
1062}
1063
1064bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1065 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1066 return true;
1067
1068 // FIXME: This implements a workaround with @property declarations also being
1069 // installed in the DeclContext for the @interface. Eventually this code
1070 // should be removed.
1071 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1072 if (!CDecl || !CDecl->IsClassExtension())
1073 return false;
1074
1075 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1076 if (!ID)
1077 return false;
1078
1079 IdentifierInfo *PropertyId = PD->getIdentifier();
1080 ObjCPropertyDecl *prevDecl =
Manman Ren5b786402016-01-28 18:49:28 +00001081 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId,
1082 PD->getQueryKind());
Guy Benyei11169dd2012-12-18 14:30:41 +00001083
1084 if (!prevDecl)
1085 return false;
1086
1087 // Visit synthesized methods since they will be skipped when visiting
1088 // the @interface.
1089 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1090 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1091 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1092 return true;
1093
1094 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1095 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1096 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1097 return true;
1098
1099 return false;
1100}
1101
Douglas Gregore9d95f12015-07-07 03:57:35 +00001102bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1103 if (!typeParamList)
1104 return false;
1105
1106 for (auto *typeParam : *typeParamList) {
1107 // Visit the type parameter.
1108 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1109 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001110 }
1111
1112 return false;
1113}
1114
Guy Benyei11169dd2012-12-18 14:30:41 +00001115bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1116 if (!D->isThisDeclarationADefinition()) {
1117 // Forward declaration is treated like a reference.
1118 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1119 }
1120
Douglas Gregore9d95f12015-07-07 03:57:35 +00001121 // Objective-C type parameters.
1122 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1123 return true;
1124
Guy Benyei11169dd2012-12-18 14:30:41 +00001125 // Issue callbacks for super class.
1126 if (D->getSuperClass() &&
1127 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1128 D->getSuperClassLoc(),
1129 TU)))
1130 return true;
1131
Douglas Gregore9d95f12015-07-07 03:57:35 +00001132 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1133 if (Visit(SuperClassTInfo->getTypeLoc()))
1134 return true;
1135
Guy Benyei11169dd2012-12-18 14:30:41 +00001136 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1137 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1138 E = D->protocol_end(); I != E; ++I, ++PL)
1139 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1140 return true;
1141
1142 return VisitObjCContainerDecl(D);
1143}
1144
1145bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1146 return VisitObjCContainerDecl(D);
1147}
1148
1149bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1150 // 'ID' could be null when dealing with invalid code.
1151 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1152 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1153 return true;
1154
1155 return VisitObjCImplDecl(D);
1156}
1157
1158bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1159#if 0
1160 // Issue callbacks for super class.
1161 // FIXME: No source location information!
1162 if (D->getSuperClass() &&
1163 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1164 D->getSuperClassLoc(),
1165 TU)))
1166 return true;
1167#endif
1168
1169 return VisitObjCImplDecl(D);
1170}
1171
1172bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1173 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1174 if (PD->isIvarNameSpecified())
1175 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1176
1177 return false;
1178}
1179
1180bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1181 return VisitDeclContext(D);
1182}
1183
1184bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1185 // Visit nested-name-specifier.
1186 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1187 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1188 return true;
1189
1190 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1191 D->getTargetNameLoc(), TU));
1192}
1193
1194bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1195 // Visit nested-name-specifier.
1196 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1197 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1198 return true;
1199 }
1200
1201 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1202 return true;
1203
1204 return VisitDeclarationNameInfo(D->getNameInfo());
1205}
1206
1207bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1208 // Visit nested-name-specifier.
1209 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1210 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1211 return true;
1212
1213 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1214 D->getIdentLocation(), TU));
1215}
1216
1217bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1218 // Visit nested-name-specifier.
1219 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1220 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1221 return true;
1222 }
1223
1224 return VisitDeclarationNameInfo(D->getNameInfo());
1225}
1226
1227bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1228 UnresolvedUsingTypenameDecl *D) {
1229 // Visit nested-name-specifier.
1230 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1231 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1232 return true;
1233
1234 return false;
1235}
1236
1237bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1238 switch (Name.getName().getNameKind()) {
1239 case clang::DeclarationName::Identifier:
1240 case clang::DeclarationName::CXXLiteralOperatorName:
1241 case clang::DeclarationName::CXXOperatorName:
1242 case clang::DeclarationName::CXXUsingDirective:
1243 return false;
1244
1245 case clang::DeclarationName::CXXConstructorName:
1246 case clang::DeclarationName::CXXDestructorName:
1247 case clang::DeclarationName::CXXConversionFunctionName:
1248 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1249 return Visit(TSInfo->getTypeLoc());
1250 return false;
1251
1252 case clang::DeclarationName::ObjCZeroArgSelector:
1253 case clang::DeclarationName::ObjCOneArgSelector:
1254 case clang::DeclarationName::ObjCMultiArgSelector:
1255 // FIXME: Per-identifier location info?
1256 return false;
1257 }
1258
1259 llvm_unreachable("Invalid DeclarationName::Kind!");
1260}
1261
1262bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1263 SourceRange Range) {
1264 // FIXME: This whole routine is a hack to work around the lack of proper
1265 // source information in nested-name-specifiers (PR5791). Since we do have
1266 // a beginning source location, we can visit the first component of the
1267 // nested-name-specifier, if it's a single-token component.
1268 if (!NNS)
1269 return false;
1270
1271 // Get the first component in the nested-name-specifier.
1272 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1273 NNS = Prefix;
1274
1275 switch (NNS->getKind()) {
1276 case NestedNameSpecifier::Namespace:
1277 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1278 TU));
1279
1280 case NestedNameSpecifier::NamespaceAlias:
1281 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1282 Range.getBegin(), TU));
1283
1284 case NestedNameSpecifier::TypeSpec: {
1285 // If the type has a form where we know that the beginning of the source
1286 // range matches up with a reference cursor. Visit the appropriate reference
1287 // cursor.
1288 const Type *T = NNS->getAsType();
1289 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1290 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1291 if (const TagType *Tag = dyn_cast<TagType>(T))
1292 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1293 if (const TemplateSpecializationType *TST
1294 = dyn_cast<TemplateSpecializationType>(T))
1295 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1296 break;
1297 }
1298
1299 case NestedNameSpecifier::TypeSpecWithTemplate:
1300 case NestedNameSpecifier::Global:
1301 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001302 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001303 break;
1304 }
1305
1306 return false;
1307}
1308
1309bool
1310CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1311 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1312 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1313 Qualifiers.push_back(Qualifier);
1314
1315 while (!Qualifiers.empty()) {
1316 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1317 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1318 switch (NNS->getKind()) {
1319 case NestedNameSpecifier::Namespace:
1320 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1321 Q.getLocalBeginLoc(),
1322 TU)))
1323 return true;
1324
1325 break;
1326
1327 case NestedNameSpecifier::NamespaceAlias:
1328 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1329 Q.getLocalBeginLoc(),
1330 TU)))
1331 return true;
1332
1333 break;
1334
1335 case NestedNameSpecifier::TypeSpec:
1336 case NestedNameSpecifier::TypeSpecWithTemplate:
1337 if (Visit(Q.getTypeLoc()))
1338 return true;
1339
1340 break;
1341
1342 case NestedNameSpecifier::Global:
1343 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001344 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001345 break;
1346 }
1347 }
1348
1349 return false;
1350}
1351
1352bool CursorVisitor::VisitTemplateParameters(
1353 const TemplateParameterList *Params) {
1354 if (!Params)
1355 return false;
1356
1357 for (TemplateParameterList::const_iterator P = Params->begin(),
1358 PEnd = Params->end();
1359 P != PEnd; ++P) {
1360 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1361 return true;
1362 }
1363
1364 return false;
1365}
1366
1367bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1368 switch (Name.getKind()) {
1369 case TemplateName::Template:
1370 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1371
1372 case TemplateName::OverloadedTemplate:
1373 // Visit the overloaded template set.
1374 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1375 return true;
1376
1377 return false;
1378
1379 case TemplateName::DependentTemplate:
1380 // FIXME: Visit nested-name-specifier.
1381 return false;
1382
1383 case TemplateName::QualifiedTemplate:
1384 // FIXME: Visit nested-name-specifier.
1385 return Visit(MakeCursorTemplateRef(
1386 Name.getAsQualifiedTemplateName()->getDecl(),
1387 Loc, TU));
1388
1389 case TemplateName::SubstTemplateTemplateParm:
1390 return Visit(MakeCursorTemplateRef(
1391 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1392 Loc, TU));
1393
1394 case TemplateName::SubstTemplateTemplateParmPack:
1395 return Visit(MakeCursorTemplateRef(
1396 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1397 Loc, TU));
1398 }
1399
1400 llvm_unreachable("Invalid TemplateName::Kind!");
1401}
1402
1403bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1404 switch (TAL.getArgument().getKind()) {
1405 case TemplateArgument::Null:
1406 case TemplateArgument::Integral:
1407 case TemplateArgument::Pack:
1408 return false;
1409
1410 case TemplateArgument::Type:
1411 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1412 return Visit(TSInfo->getTypeLoc());
1413 return false;
1414
1415 case TemplateArgument::Declaration:
1416 if (Expr *E = TAL.getSourceDeclExpression())
1417 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1418 return false;
1419
1420 case TemplateArgument::NullPtr:
1421 if (Expr *E = TAL.getSourceNullPtrExpression())
1422 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1423 return false;
1424
1425 case TemplateArgument::Expression:
1426 if (Expr *E = TAL.getSourceExpression())
1427 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1428 return false;
1429
1430 case TemplateArgument::Template:
1431 case TemplateArgument::TemplateExpansion:
1432 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1433 return true;
1434
1435 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1436 TAL.getTemplateNameLoc());
1437 }
1438
1439 llvm_unreachable("Invalid TemplateArgument::Kind!");
1440}
1441
1442bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1443 return VisitDeclContext(D);
1444}
1445
1446bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1447 return Visit(TL.getUnqualifiedLoc());
1448}
1449
1450bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1451 ASTContext &Context = AU->getASTContext();
1452
1453 // Some builtin types (such as Objective-C's "id", "sel", and
1454 // "Class") have associated declarations. Create cursors for those.
1455 QualType VisitType;
1456 switch (TL.getTypePtr()->getKind()) {
1457
1458 case BuiltinType::Void:
1459 case BuiltinType::NullPtr:
1460 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001461 case BuiltinType::OCLImage1d:
1462 case BuiltinType::OCLImage1dArray:
1463 case BuiltinType::OCLImage1dBuffer:
1464 case BuiltinType::OCLImage2d:
1465 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001466 case BuiltinType::OCLImage2dDepth:
1467 case BuiltinType::OCLImage2dArrayDepth:
1468 case BuiltinType::OCLImage2dMSAA:
1469 case BuiltinType::OCLImage2dArrayMSAA:
1470 case BuiltinType::OCLImage2dMSAADepth:
1471 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001472 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001473 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001474 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001475 case BuiltinType::OCLClkEvent:
1476 case BuiltinType::OCLQueue:
1477 case BuiltinType::OCLNDRange:
1478 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001479#define BUILTIN_TYPE(Id, SingletonId)
1480#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1481#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1482#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1483#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1484#include "clang/AST/BuiltinTypes.def"
1485 break;
1486
1487 case BuiltinType::ObjCId:
1488 VisitType = Context.getObjCIdType();
1489 break;
1490
1491 case BuiltinType::ObjCClass:
1492 VisitType = Context.getObjCClassType();
1493 break;
1494
1495 case BuiltinType::ObjCSel:
1496 VisitType = Context.getObjCSelType();
1497 break;
1498 }
1499
1500 if (!VisitType.isNull()) {
1501 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1502 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1503 TU));
1504 }
1505
1506 return false;
1507}
1508
1509bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1510 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1511}
1512
1513bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1514 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1515}
1516
1517bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1518 if (TL.isDefinition())
1519 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1520
1521 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1522}
1523
1524bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1525 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1526}
1527
1528bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001529 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001530}
1531
1532bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1533 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1534 return true;
1535
Douglas Gregore9d95f12015-07-07 03:57:35 +00001536 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1537 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1538 return true;
1539 }
1540
Guy Benyei11169dd2012-12-18 14:30:41 +00001541 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1542 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1543 TU)))
1544 return true;
1545 }
1546
1547 return false;
1548}
1549
1550bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1551 return Visit(TL.getPointeeLoc());
1552}
1553
1554bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1555 return Visit(TL.getInnerLoc());
1556}
1557
1558bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1559 return Visit(TL.getPointeeLoc());
1560}
1561
1562bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1563 return Visit(TL.getPointeeLoc());
1564}
1565
1566bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1567 return Visit(TL.getPointeeLoc());
1568}
1569
1570bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1571 return Visit(TL.getPointeeLoc());
1572}
1573
1574bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1575 return Visit(TL.getPointeeLoc());
1576}
1577
1578bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1579 return Visit(TL.getModifiedLoc());
1580}
1581
1582bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1583 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001584 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001585 return true;
1586
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001587 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1588 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001589 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1590 return true;
1591
1592 return false;
1593}
1594
1595bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1596 if (Visit(TL.getElementLoc()))
1597 return true;
1598
1599 if (Expr *Size = TL.getSizeExpr())
1600 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1601
1602 return false;
1603}
1604
Reid Kleckner8a365022013-06-24 17:51:48 +00001605bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1606 return Visit(TL.getOriginalLoc());
1607}
1608
Reid Kleckner0503a872013-12-05 01:23:43 +00001609bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1610 return Visit(TL.getOriginalLoc());
1611}
1612
Guy Benyei11169dd2012-12-18 14:30:41 +00001613bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1614 TemplateSpecializationTypeLoc TL) {
1615 // Visit the template name.
1616 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1617 TL.getTemplateNameLoc()))
1618 return true;
1619
1620 // Visit the template arguments.
1621 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1622 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1623 return true;
1624
1625 return false;
1626}
1627
1628bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1629 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1630}
1631
1632bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1633 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1634 return Visit(TSInfo->getTypeLoc());
1635
1636 return false;
1637}
1638
1639bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1640 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1641 return Visit(TSInfo->getTypeLoc());
1642
1643 return false;
1644}
1645
1646bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001647 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001648}
1649
1650bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1651 DependentTemplateSpecializationTypeLoc TL) {
1652 // Visit the nested-name-specifier, if there is one.
1653 if (TL.getQualifierLoc() &&
1654 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1655 return true;
1656
1657 // Visit the template arguments.
1658 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1659 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1660 return true;
1661
1662 return false;
1663}
1664
1665bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1666 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1667 return true;
1668
1669 return Visit(TL.getNamedTypeLoc());
1670}
1671
1672bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1673 return Visit(TL.getPatternLoc());
1674}
1675
1676bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1677 if (Expr *E = TL.getUnderlyingExpr())
1678 return Visit(MakeCXCursor(E, StmtParent, TU));
1679
1680 return false;
1681}
1682
1683bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1684 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1685}
1686
1687bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1688 return Visit(TL.getValueLoc());
1689}
1690
Xiuli Pan9c14e282016-01-09 12:53:17 +00001691bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1692 return Visit(TL.getValueLoc());
1693}
1694
Guy Benyei11169dd2012-12-18 14:30:41 +00001695#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1696bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1697 return Visit##PARENT##Loc(TL); \
1698}
1699
1700DEFAULT_TYPELOC_IMPL(Complex, Type)
1701DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1702DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1703DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1704DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1705DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1706DEFAULT_TYPELOC_IMPL(Vector, Type)
1707DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1708DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1709DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1710DEFAULT_TYPELOC_IMPL(Record, TagType)
1711DEFAULT_TYPELOC_IMPL(Enum, TagType)
1712DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1713DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1714DEFAULT_TYPELOC_IMPL(Auto, Type)
1715
1716bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1717 // Visit the nested-name-specifier, if present.
1718 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1719 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1720 return true;
1721
1722 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001723 for (const auto &I : D->bases()) {
1724 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001725 return true;
1726 }
1727 }
1728
1729 return VisitTagDecl(D);
1730}
1731
1732bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001733 for (const auto *I : D->attrs())
1734 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 return true;
1736
1737 return false;
1738}
1739
1740//===----------------------------------------------------------------------===//
1741// Data-recursive visitor methods.
1742//===----------------------------------------------------------------------===//
1743
1744namespace {
1745#define DEF_JOB(NAME, DATA, KIND)\
1746class NAME : public VisitorJob {\
1747public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001748 NAME(const DATA *d, CXCursor parent) : \
1749 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001751 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001752};
1753
1754DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1755DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1756DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1757DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001758DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1759DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1760DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1761#undef DEF_JOB
1762
James Y Knight04ec5bf2015-12-24 02:59:37 +00001763class ExplicitTemplateArgsVisit : public VisitorJob {
1764public:
1765 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1766 const TemplateArgumentLoc *End, CXCursor parent)
1767 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1768 End) {}
1769 static bool classof(const VisitorJob *VJ) {
1770 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1771 }
1772 const TemplateArgumentLoc *begin() const {
1773 return static_cast<const TemplateArgumentLoc *>(data[0]);
1774 }
1775 const TemplateArgumentLoc *end() {
1776 return static_cast<const TemplateArgumentLoc *>(data[1]);
1777 }
1778};
Guy Benyei11169dd2012-12-18 14:30:41 +00001779class DeclVisit : public VisitorJob {
1780public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001781 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001783 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001784 static bool classof(const VisitorJob *VJ) {
1785 return VJ->getKind() == DeclVisitKind;
1786 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001787 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001788 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001789};
1790class TypeLocVisit : public VisitorJob {
1791public:
1792 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1793 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1794 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1795
1796 static bool classof(const VisitorJob *VJ) {
1797 return VJ->getKind() == TypeLocVisitKind;
1798 }
1799
1800 TypeLoc get() const {
1801 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001802 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001803 }
1804};
1805
1806class LabelRefVisit : public VisitorJob {
1807public:
1808 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1809 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1810 labelLoc.getPtrEncoding()) {}
1811
1812 static bool classof(const VisitorJob *VJ) {
1813 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1814 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001815 const LabelDecl *get() const {
1816 return static_cast<const LabelDecl *>(data[0]);
1817 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001818 SourceLocation getLoc() const {
1819 return SourceLocation::getFromPtrEncoding(data[1]); }
1820};
1821
1822class NestedNameSpecifierLocVisit : public VisitorJob {
1823public:
1824 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1825 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1826 Qualifier.getNestedNameSpecifier(),
1827 Qualifier.getOpaqueData()) { }
1828
1829 static bool classof(const VisitorJob *VJ) {
1830 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1831 }
1832
1833 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001834 return NestedNameSpecifierLoc(
1835 const_cast<NestedNameSpecifier *>(
1836 static_cast<const NestedNameSpecifier *>(data[0])),
1837 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001838 }
1839};
1840
1841class DeclarationNameInfoVisit : public VisitorJob {
1842public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001843 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001844 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001845 static bool classof(const VisitorJob *VJ) {
1846 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1847 }
1848 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001849 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001850 switch (S->getStmtClass()) {
1851 default:
1852 llvm_unreachable("Unhandled Stmt");
1853 case clang::Stmt::MSDependentExistsStmtClass:
1854 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1855 case Stmt::CXXDependentScopeMemberExprClass:
1856 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1857 case Stmt::DependentScopeDeclRefExprClass:
1858 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001859 case Stmt::OMPCriticalDirectiveClass:
1860 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001861 }
1862 }
1863};
1864class MemberRefVisit : public VisitorJob {
1865public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001866 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001867 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1868 L.getPtrEncoding()) {}
1869 static bool classof(const VisitorJob *VJ) {
1870 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1871 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872 const FieldDecl *get() const {
1873 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001874 }
1875 SourceLocation getLoc() const {
1876 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1877 }
1878};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001879class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001880 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001881 VisitorWorkList &WL;
1882 CXCursor Parent;
1883public:
1884 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1885 : WL(wl), Parent(parent) {}
1886
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1888 void VisitBlockExpr(const BlockExpr *B);
1889 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1890 void VisitCompoundStmt(const CompoundStmt *S);
1891 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1892 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1893 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1894 void VisitCXXNewExpr(const CXXNewExpr *E);
1895 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1896 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1897 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1898 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1899 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1900 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1901 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1902 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001903 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904 void VisitDeclRefExpr(const DeclRefExpr *D);
1905 void VisitDeclStmt(const DeclStmt *S);
1906 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1907 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1908 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1909 void VisitForStmt(const ForStmt *FS);
1910 void VisitGotoStmt(const GotoStmt *GS);
1911 void VisitIfStmt(const IfStmt *If);
1912 void VisitInitListExpr(const InitListExpr *IE);
1913 void VisitMemberExpr(const MemberExpr *M);
1914 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1915 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1916 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1917 void VisitOverloadExpr(const OverloadExpr *E);
1918 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1919 void VisitStmt(const Stmt *S);
1920 void VisitSwitchStmt(const SwitchStmt *S);
1921 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001922 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1923 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1924 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1925 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1926 void VisitVAArgExpr(const VAArgExpr *E);
1927 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1928 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1929 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1930 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001931 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001932 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001933 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001934 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001935 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001936 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001937 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001938 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001939 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001940 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001941 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001942 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001943 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001944 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001945 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001946 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001947 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001948 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001949 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001950 void
1951 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001952 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001953 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001954 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001955 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001956 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001957 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00001958 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00001959 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00001960 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00001961 void
1962 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001963 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001964 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001965 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001966 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001967
Guy Benyei11169dd2012-12-18 14:30:41 +00001968private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001969 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001970 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00001971 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1972 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1974 void AddStmt(const Stmt *S);
1975 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001978 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001979};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001980} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001981
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001983 // 'S' should always be non-null, since it comes from the
1984 // statement we are visiting.
1985 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1986}
1987
1988void
1989EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1990 if (Qualifier)
1991 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1992}
1993
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001994void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001995 if (S)
1996 WL.push_back(StmtVisit(S, Parent));
1997}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001998void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001999 if (D)
2000 WL.push_back(DeclVisit(D, Parent, isFirst));
2001}
James Y Knight04ec5bf2015-12-24 02:59:37 +00002002void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2003 unsigned NumTemplateArgs) {
2004 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002005}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002006void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002007 if (D)
2008 WL.push_back(MemberRefVisit(D, L, Parent));
2009}
2010void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2011 if (TI)
2012 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2013 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002014void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002015 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002016 for (const Stmt *SubStmt : S->children()) {
2017 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002018 }
2019 if (size == WL.size())
2020 return;
2021 // Now reverse the entries we just added. This will match the DFS
2022 // ordering performed by the worklist.
2023 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2024 std::reverse(I, E);
2025}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002026namespace {
2027class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2028 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002029 /// \brief Process clauses with list of variables.
2030 template <typename T>
2031 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002032public:
2033 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2034#define OPENMP_CLAUSE(Name, Class) \
2035 void Visit##Class(const Class *C);
2036#include "clang/Basic/OpenMPKinds.def"
2037};
2038
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002039void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2040 Visitor->AddStmt(C->getCondition());
2041}
2042
Alexey Bataev3778b602014-07-17 07:32:53 +00002043void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2044 Visitor->AddStmt(C->getCondition());
2045}
2046
Alexey Bataev568a8332014-03-06 06:15:19 +00002047void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2048 Visitor->AddStmt(C->getNumThreads());
2049}
2050
Alexey Bataev62c87d22014-03-21 04:51:18 +00002051void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2052 Visitor->AddStmt(C->getSafelen());
2053}
2054
Alexey Bataev66b15b52015-08-21 11:14:16 +00002055void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2056 Visitor->AddStmt(C->getSimdlen());
2057}
2058
Alexander Musman8bd31e62014-05-27 15:12:19 +00002059void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2060 Visitor->AddStmt(C->getNumForLoops());
2061}
2062
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002063void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002064
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002065void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2066
Alexey Bataev56dafe82014-06-20 07:16:17 +00002067void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2068 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002069 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002070}
2071
Alexey Bataev10e775f2015-07-30 11:36:16 +00002072void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2073 Visitor->AddStmt(C->getNumForLoops());
2074}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002075
Alexey Bataev236070f2014-06-20 11:19:47 +00002076void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2077
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002078void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2079
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002080void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2081
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002082void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2083
Alexey Bataevdea47612014-07-23 07:46:59 +00002084void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2085
Alexey Bataev67a4f222014-07-23 10:25:33 +00002086void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2087
Alexey Bataev459dec02014-07-24 06:46:57 +00002088void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2089
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002090void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2091
Alexey Bataev346265e2015-09-25 10:37:12 +00002092void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2093
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002094void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2095
Alexey Bataevb825de12015-12-07 10:51:44 +00002096void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2097
Michael Wonge710d542015-08-07 16:16:36 +00002098void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2099 Visitor->AddStmt(C->getDevice());
2100}
2101
Kelvin Li099bb8c2015-11-24 20:50:12 +00002102void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2103 Visitor->AddStmt(C->getNumTeams());
2104}
2105
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002106void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2107 Visitor->AddStmt(C->getThreadLimit());
2108}
2109
Alexey Bataeva0569352015-12-01 10:17:31 +00002110void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2111 Visitor->AddStmt(C->getPriority());
2112}
2113
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002114void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2115 Visitor->AddStmt(C->getGrainsize());
2116}
2117
Alexey Bataev382967a2015-12-08 12:06:20 +00002118void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2119 Visitor->AddStmt(C->getNumTasks());
2120}
2121
Alexey Bataev28c75412015-12-15 08:19:24 +00002122void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2123 Visitor->AddStmt(C->getHint());
2124}
2125
Alexey Bataev756c1962013-09-24 03:17:45 +00002126template<typename T>
2127void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002128 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002129 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002130 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002131}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002132
2133void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002134 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002135 for (const auto *E : C->private_copies()) {
2136 Visitor->AddStmt(E);
2137 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002138}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002139void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2140 const OMPFirstprivateClause *C) {
2141 VisitOMPClauseList(C);
2142}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002143void OMPClauseEnqueue::VisitOMPLastprivateClause(
2144 const OMPLastprivateClause *C) {
2145 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002146 for (auto *E : C->private_copies()) {
2147 Visitor->AddStmt(E);
2148 }
2149 for (auto *E : C->source_exprs()) {
2150 Visitor->AddStmt(E);
2151 }
2152 for (auto *E : C->destination_exprs()) {
2153 Visitor->AddStmt(E);
2154 }
2155 for (auto *E : C->assignment_ops()) {
2156 Visitor->AddStmt(E);
2157 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002158}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002159void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002160 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002161}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002162void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2163 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002164 for (auto *E : C->privates()) {
2165 Visitor->AddStmt(E);
2166 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002167 for (auto *E : C->lhs_exprs()) {
2168 Visitor->AddStmt(E);
2169 }
2170 for (auto *E : C->rhs_exprs()) {
2171 Visitor->AddStmt(E);
2172 }
2173 for (auto *E : C->reduction_ops()) {
2174 Visitor->AddStmt(E);
2175 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002176}
Alexander Musman8dba6642014-04-22 13:09:42 +00002177void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2178 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002179 for (const auto *E : C->privates()) {
2180 Visitor->AddStmt(E);
2181 }
Alexander Musman3276a272015-03-21 10:12:56 +00002182 for (const auto *E : C->inits()) {
2183 Visitor->AddStmt(E);
2184 }
2185 for (const auto *E : C->updates()) {
2186 Visitor->AddStmt(E);
2187 }
2188 for (const auto *E : C->finals()) {
2189 Visitor->AddStmt(E);
2190 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002191 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002192 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002193}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002194void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2195 VisitOMPClauseList(C);
2196 Visitor->AddStmt(C->getAlignment());
2197}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002198void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2199 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002200 for (auto *E : C->source_exprs()) {
2201 Visitor->AddStmt(E);
2202 }
2203 for (auto *E : C->destination_exprs()) {
2204 Visitor->AddStmt(E);
2205 }
2206 for (auto *E : C->assignment_ops()) {
2207 Visitor->AddStmt(E);
2208 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002209}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002210void
2211OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2212 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002213 for (auto *E : C->source_exprs()) {
2214 Visitor->AddStmt(E);
2215 }
2216 for (auto *E : C->destination_exprs()) {
2217 Visitor->AddStmt(E);
2218 }
2219 for (auto *E : C->assignment_ops()) {
2220 Visitor->AddStmt(E);
2221 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002222}
Alexey Bataev6125da92014-07-21 11:26:11 +00002223void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2224 VisitOMPClauseList(C);
2225}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002226void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2227 VisitOMPClauseList(C);
2228}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002229void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2230 VisitOMPClauseList(C);
2231}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002232void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2233 const OMPDistScheduleClause *C) {
2234 Visitor->AddStmt(C->getChunkSize());
2235 Visitor->AddStmt(C->getHelperChunkSize());
2236}
Arpith Chacko Jacob3cf89042016-01-26 16:37:23 +00002237void OMPClauseEnqueue::VisitOMPDefaultmapClause(const OMPDefaultmapClause *C) {
2238}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002239}
Alexey Bataev756c1962013-09-24 03:17:45 +00002240
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002241void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2242 unsigned size = WL.size();
2243 OMPClauseEnqueue Visitor(this);
2244 Visitor.Visit(S);
2245 if (size == WL.size())
2246 return;
2247 // Now reverse the entries we just added. This will match the DFS
2248 // ordering performed by the worklist.
2249 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2250 std::reverse(I, E);
2251}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002252void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2254}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 AddDecl(B->getBlockDecl());
2257}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002258void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002259 EnqueueChildren(E);
2260 AddTypeLoc(E->getTypeSourceInfo());
2261}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002263 for (auto &I : llvm::reverse(S->body()))
2264 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002265}
2266void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 AddStmt(S->getSubStmt());
2269 AddDeclarationNameInfo(S);
2270 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2271 AddNestedNameSpecifierLoc(QualifierLoc);
2272}
2273
2274void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002275VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002276 if (E->hasExplicitTemplateArgs())
2277 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 AddDeclarationNameInfo(E);
2279 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2280 AddNestedNameSpecifierLoc(QualifierLoc);
2281 if (!E->isImplicitAccess())
2282 AddStmt(E->getBase());
2283}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 // Enqueue the initializer , if any.
2286 AddStmt(E->getInitializer());
2287 // Enqueue the array size, if any.
2288 AddStmt(E->getArraySize());
2289 // Enqueue the allocated type.
2290 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2291 // Enqueue the placement arguments.
2292 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2293 AddStmt(E->getPlacementArg(I-1));
2294}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002295void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002296 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2297 AddStmt(CE->getArg(I-1));
2298 AddStmt(CE->getCallee());
2299 AddStmt(CE->getArg(0));
2300}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002301void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2302 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 // Visit the name of the type being destroyed.
2304 AddTypeLoc(E->getDestroyedTypeInfo());
2305 // Visit the scope type that looks disturbingly like the nested-name-specifier
2306 // but isn't.
2307 AddTypeLoc(E->getScopeTypeInfo());
2308 // Visit the nested-name-specifier.
2309 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2310 AddNestedNameSpecifierLoc(QualifierLoc);
2311 // Visit base expression.
2312 AddStmt(E->getBase());
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2315 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 AddTypeLoc(E->getTypeSourceInfo());
2317}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002318void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2319 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002320 EnqueueChildren(E);
2321 AddTypeLoc(E->getTypeSourceInfo());
2322}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002323void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002324 EnqueueChildren(E);
2325 if (E->isTypeOperand())
2326 AddTypeLoc(E->getTypeOperandSourceInfo());
2327}
2328
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002329void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2330 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002331 EnqueueChildren(E);
2332 AddTypeLoc(E->getTypeSourceInfo());
2333}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002334void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002335 EnqueueChildren(E);
2336 if (E->isTypeOperand())
2337 AddTypeLoc(E->getTypeOperandSourceInfo());
2338}
2339
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002340void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002341 EnqueueChildren(S);
2342 AddDecl(S->getExceptionDecl());
2343}
2344
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002345void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002346 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002347 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002348 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002349}
2350
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002351void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002352 if (DR->hasExplicitTemplateArgs())
2353 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002354 WL.push_back(DeclRefExprParts(DR, Parent));
2355}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002356void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2357 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002358 if (E->hasExplicitTemplateArgs())
2359 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002360 AddDeclarationNameInfo(E);
2361 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2362}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002363void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002364 unsigned size = WL.size();
2365 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002366 for (const auto *D : S->decls()) {
2367 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002368 isFirst = false;
2369 }
2370 if (size == WL.size())
2371 return;
2372 // Now reverse the entries we just added. This will match the DFS
2373 // ordering performed by the worklist.
2374 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2375 std::reverse(I, E);
2376}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002377void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002378 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002379 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002380 D = E->designators_rbegin(), DEnd = E->designators_rend();
2381 D != DEnd; ++D) {
2382 if (D->isFieldDesignator()) {
2383 if (FieldDecl *Field = D->getField())
2384 AddMemberRef(Field, D->getFieldLoc());
2385 continue;
2386 }
2387 if (D->isArrayDesignator()) {
2388 AddStmt(E->getArrayIndex(*D));
2389 continue;
2390 }
2391 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2392 AddStmt(E->getArrayRangeEnd(*D));
2393 AddStmt(E->getArrayRangeStart(*D));
2394 }
2395}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 EnqueueChildren(E);
2398 AddTypeLoc(E->getTypeInfoAsWritten());
2399}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002400void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002401 AddStmt(FS->getBody());
2402 AddStmt(FS->getInc());
2403 AddStmt(FS->getCond());
2404 AddDecl(FS->getConditionVariable());
2405 AddStmt(FS->getInit());
2406}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002407void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002408 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2409}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002410void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002411 AddStmt(If->getElse());
2412 AddStmt(If->getThen());
2413 AddStmt(If->getCond());
2414 AddDecl(If->getConditionVariable());
2415}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002416void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002417 // We care about the syntactic form of the initializer list, only.
2418 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2419 IE = Syntactic;
2420 EnqueueChildren(IE);
2421}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002422void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002423 WL.push_back(MemberExprParts(M, Parent));
2424
2425 // If the base of the member access expression is an implicit 'this', don't
2426 // visit it.
2427 // FIXME: If we ever want to show these implicit accesses, this will be
2428 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002429 if (M->isImplicitAccess())
2430 return;
2431
2432 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2433 // real field that that we are interested in.
2434 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2435 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2436 if (FD->isAnonymousStructOrUnion()) {
2437 AddStmt(SubME->getBase());
2438 return;
2439 }
2440 }
2441 }
2442
2443 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002444}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002445void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 AddTypeLoc(E->getEncodedTypeSourceInfo());
2447}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002448void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002449 EnqueueChildren(M);
2450 AddTypeLoc(M->getClassReceiverTypeInfo());
2451}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002452void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002453 // Visit the components of the offsetof expression.
2454 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002455 const OffsetOfNode &Node = E->getComponent(I-1);
2456 switch (Node.getKind()) {
2457 case OffsetOfNode::Array:
2458 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2459 break;
2460 case OffsetOfNode::Field:
2461 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2462 break;
2463 case OffsetOfNode::Identifier:
2464 case OffsetOfNode::Base:
2465 continue;
2466 }
2467 }
2468 // Visit the type into which we're computing the offset.
2469 AddTypeLoc(E->getTypeSourceInfo());
2470}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002471void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002472 if (E->hasExplicitTemplateArgs())
2473 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002474 WL.push_back(OverloadExprParts(E, Parent));
2475}
2476void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002477 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002478 EnqueueChildren(E);
2479 if (E->isArgumentType())
2480 AddTypeLoc(E->getArgumentTypeInfo());
2481}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002482void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002483 EnqueueChildren(S);
2484}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002485void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002486 AddStmt(S->getBody());
2487 AddStmt(S->getCond());
2488 AddDecl(S->getConditionVariable());
2489}
2490
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002491void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002492 AddStmt(W->getBody());
2493 AddStmt(W->getCond());
2494 AddDecl(W->getConditionVariable());
2495}
2496
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002497void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002498 for (unsigned I = E->getNumArgs(); I > 0; --I)
2499 AddTypeLoc(E->getArg(I-1));
2500}
2501
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002502void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002503 AddTypeLoc(E->getQueriedTypeSourceInfo());
2504}
2505
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002506void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002507 EnqueueChildren(E);
2508}
2509
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002510void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002511 VisitOverloadExpr(U);
2512 if (!U->isImplicitAccess())
2513 AddStmt(U->getBase());
2514}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002515void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002516 AddStmt(E->getSubExpr());
2517 AddTypeLoc(E->getWrittenTypeInfo());
2518}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002519void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002520 WL.push_back(SizeOfPackExprParts(E, Parent));
2521}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002522void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002523 // If the opaque value has a source expression, just transparently
2524 // visit that. This is useful for (e.g.) pseudo-object expressions.
2525 if (Expr *SourceExpr = E->getSourceExpr())
2526 return Visit(SourceExpr);
2527}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002528void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002529 AddStmt(E->getBody());
2530 WL.push_back(LambdaExprParts(E, Parent));
2531}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002532void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002533 // Treat the expression like its syntactic form.
2534 Visit(E->getSyntacticForm());
2535}
2536
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002537void EnqueueVisitor::VisitOMPExecutableDirective(
2538 const OMPExecutableDirective *D) {
2539 EnqueueChildren(D);
2540 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2541 E = D->clauses().end();
2542 I != E; ++I)
2543 EnqueueChildren(*I);
2544}
2545
Alexander Musman3aaab662014-08-19 11:27:13 +00002546void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2547 VisitOMPExecutableDirective(D);
2548}
2549
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002550void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2551 VisitOMPExecutableDirective(D);
2552}
2553
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002554void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002555 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002556}
2557
Alexey Bataevf29276e2014-06-18 04:14:57 +00002558void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002559 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002560}
2561
Alexander Musmanf82886e2014-09-18 05:12:34 +00002562void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2563 VisitOMPLoopDirective(D);
2564}
2565
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002566void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2567 VisitOMPExecutableDirective(D);
2568}
2569
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002570void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2571 VisitOMPExecutableDirective(D);
2572}
2573
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002574void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2575 VisitOMPExecutableDirective(D);
2576}
2577
Alexander Musman80c22892014-07-17 08:54:58 +00002578void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2579 VisitOMPExecutableDirective(D);
2580}
2581
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002582void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2583 VisitOMPExecutableDirective(D);
2584 AddDeclarationNameInfo(D);
2585}
2586
Alexey Bataev4acb8592014-07-07 13:01:15 +00002587void
2588EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002589 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002590}
2591
Alexander Musmane4e893b2014-09-23 09:33:00 +00002592void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2593 const OMPParallelForSimdDirective *D) {
2594 VisitOMPLoopDirective(D);
2595}
2596
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002597void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2598 const OMPParallelSectionsDirective *D) {
2599 VisitOMPExecutableDirective(D);
2600}
2601
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002602void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2603 VisitOMPExecutableDirective(D);
2604}
2605
Alexey Bataev68446b72014-07-18 07:47:19 +00002606void
2607EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2608 VisitOMPExecutableDirective(D);
2609}
2610
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002611void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2612 VisitOMPExecutableDirective(D);
2613}
2614
Alexey Bataev2df347a2014-07-18 10:17:07 +00002615void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2616 VisitOMPExecutableDirective(D);
2617}
2618
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002619void EnqueueVisitor::VisitOMPTaskgroupDirective(
2620 const OMPTaskgroupDirective *D) {
2621 VisitOMPExecutableDirective(D);
2622}
2623
Alexey Bataev6125da92014-07-21 11:26:11 +00002624void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2625 VisitOMPExecutableDirective(D);
2626}
2627
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002628void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2629 VisitOMPExecutableDirective(D);
2630}
2631
Alexey Bataev0162e452014-07-22 10:10:35 +00002632void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2633 VisitOMPExecutableDirective(D);
2634}
2635
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002636void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2637 VisitOMPExecutableDirective(D);
2638}
2639
Michael Wong65f367f2015-07-21 13:44:28 +00002640void EnqueueVisitor::VisitOMPTargetDataDirective(const
2641 OMPTargetDataDirective *D) {
2642 VisitOMPExecutableDirective(D);
2643}
2644
Samuel Antaodf67fc42016-01-19 19:15:56 +00002645void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2646 const OMPTargetEnterDataDirective *D) {
2647 VisitOMPExecutableDirective(D);
2648}
2649
Samuel Antao72590762016-01-19 20:04:50 +00002650void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2651 const OMPTargetExitDataDirective *D) {
2652 VisitOMPExecutableDirective(D);
2653}
2654
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002655void EnqueueVisitor::VisitOMPTargetParallelDirective(
2656 const OMPTargetParallelDirective *D) {
2657 VisitOMPExecutableDirective(D);
2658}
2659
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002660void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2661 const OMPTargetParallelForDirective *D) {
2662 VisitOMPLoopDirective(D);
2663}
2664
Alexey Bataev13314bf2014-10-09 04:18:56 +00002665void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2666 VisitOMPExecutableDirective(D);
2667}
2668
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002669void EnqueueVisitor::VisitOMPCancellationPointDirective(
2670 const OMPCancellationPointDirective *D) {
2671 VisitOMPExecutableDirective(D);
2672}
2673
Alexey Bataev80909872015-07-02 11:25:17 +00002674void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2675 VisitOMPExecutableDirective(D);
2676}
2677
Alexey Bataev49f6e782015-12-01 04:18:41 +00002678void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2679 VisitOMPLoopDirective(D);
2680}
2681
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002682void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2683 const OMPTaskLoopSimdDirective *D) {
2684 VisitOMPLoopDirective(D);
2685}
2686
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002687void EnqueueVisitor::VisitOMPDistributeDirective(
2688 const OMPDistributeDirective *D) {
2689 VisitOMPLoopDirective(D);
2690}
2691
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002692void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002693 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2694}
2695
2696bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2697 if (RegionOfInterest.isValid()) {
2698 SourceRange Range = getRawCursorExtent(C);
2699 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2700 return false;
2701 }
2702 return true;
2703}
2704
2705bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2706 while (!WL.empty()) {
2707 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002708 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002709
2710 // Set the Parent field, then back to its old value once we're done.
2711 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2712
2713 switch (LI.getKind()) {
2714 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002715 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002716 if (!D)
2717 continue;
2718
2719 // For now, perform default visitation for Decls.
2720 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2721 cast<DeclVisit>(&LI)->isFirst())))
2722 return true;
2723
2724 continue;
2725 }
2726 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002727 for (const TemplateArgumentLoc &Arg :
2728 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2729 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002730 return true;
2731 }
2732 continue;
2733 }
2734 case VisitorJob::TypeLocVisitKind: {
2735 // Perform default visitation for TypeLocs.
2736 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2737 return true;
2738 continue;
2739 }
2740 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002741 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002742 if (LabelStmt *stmt = LS->getStmt()) {
2743 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2744 TU))) {
2745 return true;
2746 }
2747 }
2748 continue;
2749 }
2750
2751 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2752 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2753 if (VisitNestedNameSpecifierLoc(V->get()))
2754 return true;
2755 continue;
2756 }
2757
2758 case VisitorJob::DeclarationNameInfoVisitKind: {
2759 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2760 ->get()))
2761 return true;
2762 continue;
2763 }
2764 case VisitorJob::MemberRefVisitKind: {
2765 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2766 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2767 return true;
2768 continue;
2769 }
2770 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002771 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002772 if (!S)
2773 continue;
2774
2775 // Update the current cursor.
2776 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2777 if (!IsInRegionOfInterest(Cursor))
2778 continue;
2779 switch (Visitor(Cursor, Parent, ClientData)) {
2780 case CXChildVisit_Break: return true;
2781 case CXChildVisit_Continue: break;
2782 case CXChildVisit_Recurse:
2783 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002784 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002785 EnqueueWorkList(WL, S);
2786 break;
2787 }
2788 continue;
2789 }
2790 case VisitorJob::MemberExprPartsKind: {
2791 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002792 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002793
2794 // Visit the nested-name-specifier
2795 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2796 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2797 return true;
2798
2799 // Visit the declaration name.
2800 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2801 return true;
2802
2803 // Visit the explicitly-specified template arguments, if any.
2804 if (M->hasExplicitTemplateArgs()) {
2805 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2806 *ArgEnd = Arg + M->getNumTemplateArgs();
2807 Arg != ArgEnd; ++Arg) {
2808 if (VisitTemplateArgumentLoc(*Arg))
2809 return true;
2810 }
2811 }
2812 continue;
2813 }
2814 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002815 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002816 // Visit nested-name-specifier, if present.
2817 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2818 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2819 return true;
2820 // Visit declaration name.
2821 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2822 return true;
2823 continue;
2824 }
2825 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002826 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002827 // Visit the nested-name-specifier.
2828 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2829 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2830 return true;
2831 // Visit the declaration name.
2832 if (VisitDeclarationNameInfo(O->getNameInfo()))
2833 return true;
2834 // Visit the overloaded declaration reference.
2835 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2836 return true;
2837 continue;
2838 }
2839 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002840 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002841 NamedDecl *Pack = E->getPack();
2842 if (isa<TemplateTypeParmDecl>(Pack)) {
2843 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2844 E->getPackLoc(), TU)))
2845 return true;
2846
2847 continue;
2848 }
2849
2850 if (isa<TemplateTemplateParmDecl>(Pack)) {
2851 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2852 E->getPackLoc(), TU)))
2853 return true;
2854
2855 continue;
2856 }
2857
2858 // Non-type template parameter packs and function parameter packs are
2859 // treated like DeclRefExpr cursors.
2860 continue;
2861 }
2862
2863 case VisitorJob::LambdaExprPartsKind: {
2864 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002865 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002866 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2867 CEnd = E->explicit_capture_end();
2868 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002869 // FIXME: Lambda init-captures.
2870 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002871 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002872
Guy Benyei11169dd2012-12-18 14:30:41 +00002873 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2874 C->getLocation(),
2875 TU)))
2876 return true;
2877 }
2878
2879 // Visit parameters and return type, if present.
2880 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2881 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2882 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2883 // Visit the whole type.
2884 if (Visit(TL))
2885 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002886 } else if (FunctionProtoTypeLoc Proto =
2887 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002888 if (E->hasExplicitParameters()) {
2889 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002890 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2891 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002892 return true;
2893 } else {
2894 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002895 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002896 return true;
2897 }
2898 }
2899 }
2900 break;
2901 }
2902
2903 case VisitorJob::PostChildrenVisitKind:
2904 if (PostChildrenVisitor(Parent, ClientData))
2905 return true;
2906 break;
2907 }
2908 }
2909 return false;
2910}
2911
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002912bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002913 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002914 if (!WorkListFreeList.empty()) {
2915 WL = WorkListFreeList.back();
2916 WL->clear();
2917 WorkListFreeList.pop_back();
2918 }
2919 else {
2920 WL = new VisitorWorkList();
2921 WorkListCache.push_back(WL);
2922 }
2923 EnqueueWorkList(*WL, S);
2924 bool result = RunVisitorWorkList(*WL);
2925 WorkListFreeList.push_back(WL);
2926 return result;
2927}
2928
2929namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002930typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002931RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2932 const DeclarationNameInfo &NI, SourceRange QLoc,
2933 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002934 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2935 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2936 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2937
2938 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2939
2940 RefNamePieces Pieces;
2941
2942 if (WantQualifier && QLoc.isValid())
2943 Pieces.push_back(QLoc);
2944
2945 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2946 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002947
2948 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2949 Pieces.push_back(*TemplateArgsLoc);
2950
Guy Benyei11169dd2012-12-18 14:30:41 +00002951 if (Kind == DeclarationName::CXXOperatorName) {
2952 Pieces.push_back(SourceLocation::getFromRawEncoding(
2953 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2954 Pieces.push_back(SourceLocation::getFromRawEncoding(
2955 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2956 }
2957
2958 if (WantSinglePiece) {
2959 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2960 Pieces.clear();
2961 Pieces.push_back(R);
2962 }
2963
2964 return Pieces;
2965}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002966}
Guy Benyei11169dd2012-12-18 14:30:41 +00002967
2968//===----------------------------------------------------------------------===//
2969// Misc. API hooks.
2970//===----------------------------------------------------------------------===//
2971
Chad Rosier05c71aa2013-03-27 18:28:23 +00002972static void fatal_error_handler(void *user_data, const std::string& reason,
2973 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002974 // Write the result out to stderr avoiding errs() because raw_ostreams can
2975 // call report_fatal_error.
2976 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2977 ::abort();
2978}
2979
Chandler Carruth66660742014-06-27 16:37:27 +00002980namespace {
2981struct RegisterFatalErrorHandler {
2982 RegisterFatalErrorHandler() {
2983 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2984 }
2985};
2986}
2987
2988static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2989
Guy Benyei11169dd2012-12-18 14:30:41 +00002990extern "C" {
2991CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2992 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002993 // We use crash recovery to make some of our APIs more reliable, implicitly
2994 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002995 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2996 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002997
Chandler Carruth66660742014-06-27 16:37:27 +00002998 // Look through the managed static to trigger construction of the managed
2999 // static which registers our fatal error handler. This ensures it is only
3000 // registered once.
3001 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003002
Adrian Prantlbc068582015-07-08 01:00:30 +00003003 // Initialize targets for clang module support.
3004 llvm::InitializeAllTargets();
3005 llvm::InitializeAllTargetMCs();
3006 llvm::InitializeAllAsmPrinters();
3007 llvm::InitializeAllAsmParsers();
3008
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003009 CIndexer *CIdxr = new CIndexer();
3010
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 if (excludeDeclarationsFromPCH)
3012 CIdxr->setOnlyLocalDecls();
3013 if (displayDiagnostics)
3014 CIdxr->setDisplayDiagnostics();
3015
3016 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3017 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3018 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3019 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3020 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3021 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3022
3023 return CIdxr;
3024}
3025
3026void clang_disposeIndex(CXIndex CIdx) {
3027 if (CIdx)
3028 delete static_cast<CIndexer *>(CIdx);
3029}
3030
3031void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3032 if (CIdx)
3033 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3034}
3035
3036unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3037 if (CIdx)
3038 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3039 return 0;
3040}
3041
3042void clang_toggleCrashRecovery(unsigned isEnabled) {
3043 if (isEnabled)
3044 llvm::CrashRecoveryContext::Enable();
3045 else
3046 llvm::CrashRecoveryContext::Disable();
3047}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003048
Guy Benyei11169dd2012-12-18 14:30:41 +00003049CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3050 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003051 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003052 enum CXErrorCode Result =
3053 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003054 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003055 assert((TU && Result == CXError_Success) ||
3056 (!TU && Result != CXError_Success));
3057 return TU;
3058}
3059
3060enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3061 const char *ast_filename,
3062 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003063 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003064 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003065
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003066 if (!CIdx || !ast_filename || !out_TU)
3067 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003068
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003069 LOG_FUNC_SECTION {
3070 *Log << ast_filename;
3071 }
3072
Guy Benyei11169dd2012-12-18 14:30:41 +00003073 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3074 FileSystemOptions FileSystemOpts;
3075
Justin Bognerd512c1e2014-10-15 00:33:06 +00003076 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3077 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003078 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003079 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003080 FileSystemOpts, /*UseDebugInfo=*/false,
3081 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003082 /*CaptureDiagnostics=*/true,
3083 /*AllowPCHWithCompilerErrors=*/true,
3084 /*UserFilesAreVolatile=*/true);
3085 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003086 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003087}
3088
3089unsigned clang_defaultEditingTranslationUnitOptions() {
3090 return CXTranslationUnit_PrecompiledPreamble |
3091 CXTranslationUnit_CacheCompletionResults;
3092}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003093
Guy Benyei11169dd2012-12-18 14:30:41 +00003094CXTranslationUnit
3095clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3096 const char *source_filename,
3097 int num_command_line_args,
3098 const char * const *command_line_args,
3099 unsigned num_unsaved_files,
3100 struct CXUnsavedFile *unsaved_files) {
3101 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3102 return clang_parseTranslationUnit(CIdx, source_filename,
3103 command_line_args, num_command_line_args,
3104 unsaved_files, num_unsaved_files,
3105 Options);
3106}
3107
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003108static CXErrorCode
3109clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3110 const char *const *command_line_args,
3111 int num_command_line_args,
3112 ArrayRef<CXUnsavedFile> unsaved_files,
3113 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003114 // Set up the initial return values.
3115 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003116 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003117
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003118 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003119 if (!CIdx || !out_TU)
3120 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003121
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3123
3124 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3125 setThreadBackgroundPriority();
3126
3127 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003128 bool CreatePreambleOnFirstParse =
3129 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 // FIXME: Add a flag for modules.
3131 TranslationUnitKind TUKind
3132 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003133 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003134 = options & CXTranslationUnit_CacheCompletionResults;
3135 bool IncludeBriefCommentsInCodeCompletion
3136 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3137 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3138 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3139
3140 // Configure the diagnostics.
3141 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003142 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003143
3144 // Recover resources if we crash before exiting this function.
3145 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3146 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003147 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003148
Ahmed Charlesb8984322014-03-07 20:03:18 +00003149 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3150 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003151
3152 // Recover resources if we crash before exiting this function.
3153 llvm::CrashRecoveryContextCleanupRegistrar<
3154 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3155
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003156 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003157 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003158 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003159 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003160 }
3161
Ahmed Charlesb8984322014-03-07 20:03:18 +00003162 std::unique_ptr<std::vector<const char *>> Args(
3163 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003164
3165 // Recover resources if we crash before exiting this method.
3166 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3167 ArgsCleanup(Args.get());
3168
3169 // Since the Clang C library is primarily used by batch tools dealing with
3170 // (often very broken) source code, where spell-checking can have a
3171 // significant negative impact on performance (particularly when
3172 // precompiled headers are involved), we disable it by default.
3173 // Only do this if we haven't found a spell-checking-related argument.
3174 bool FoundSpellCheckingArgument = false;
3175 for (int I = 0; I != num_command_line_args; ++I) {
3176 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3177 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3178 FoundSpellCheckingArgument = true;
3179 break;
3180 }
3181 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 Args->insert(Args->end(), command_line_args,
3183 command_line_args + num_command_line_args);
3184
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003185 if (!FoundSpellCheckingArgument)
3186 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3187
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 // The 'source_filename' argument is optional. If the caller does not
3189 // specify it then it is assumed that the source file is specified
3190 // in the actual argument list.
3191 // Put the source file after command_line_args otherwise if '-x' flag is
3192 // present it will be unused.
3193 if (source_filename)
3194 Args->push_back(source_filename);
3195
3196 // Do we need the detailed preprocessing record?
3197 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3198 Args->push_back("-Xclang");
3199 Args->push_back("-detailed-preprocessing-record");
3200 }
3201
3202 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003203 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003204 // Unless the user specified that they want the preamble on the first parse
3205 // set it up to be created on the first reparse. This makes the first parse
3206 // faster, trading for a slower (first) reparse.
3207 unsigned PrecompilePreambleAfterNParses =
3208 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003209 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003210 Args->data(), Args->data() + Args->size(),
3211 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003212 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3213 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003214 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3215 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003216 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003217 /*UserFilesAreVolatile=*/true, ForSerialization,
3218 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3219 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003220
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003221 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003222 if (!Unit && !ErrUnit)
3223 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003224
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 if (NumErrors != Diags->getClient()->getNumErrors()) {
3226 // Make sure to check that 'Unit' is non-NULL.
3227 if (CXXIdx->getDisplayDiagnostics())
3228 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3229 }
3230
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003231 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3232 return CXError_ASTReadError;
3233
3234 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3235 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003236}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003237
3238CXTranslationUnit
3239clang_parseTranslationUnit(CXIndex CIdx,
3240 const char *source_filename,
3241 const char *const *command_line_args,
3242 int num_command_line_args,
3243 struct CXUnsavedFile *unsaved_files,
3244 unsigned num_unsaved_files,
3245 unsigned options) {
3246 CXTranslationUnit TU;
3247 enum CXErrorCode Result = clang_parseTranslationUnit2(
3248 CIdx, source_filename, command_line_args, num_command_line_args,
3249 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003250 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003251 assert((TU && Result == CXError_Success) ||
3252 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003253 return TU;
3254}
3255
3256enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003257 CXIndex CIdx, const char *source_filename,
3258 const char *const *command_line_args, int num_command_line_args,
3259 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3260 unsigned options, CXTranslationUnit *out_TU) {
3261 SmallVector<const char *, 4> Args;
3262 Args.push_back("clang");
3263 Args.append(command_line_args, command_line_args + num_command_line_args);
3264 return clang_parseTranslationUnit2FullArgv(
3265 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3266 num_unsaved_files, options, out_TU);
3267}
3268
3269enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3270 CXIndex CIdx, const char *source_filename,
3271 const char *const *command_line_args, int num_command_line_args,
3272 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3273 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003274 LOG_FUNC_SECTION {
3275 *Log << source_filename << ": ";
3276 for (int i = 0; i != num_command_line_args; ++i)
3277 *Log << command_line_args[i] << " ";
3278 }
3279
Alp Toker9d85b182014-07-07 01:23:14 +00003280 if (num_unsaved_files && !unsaved_files)
3281 return CXError_InvalidArguments;
3282
Alp Toker5c532982014-07-07 22:42:03 +00003283 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003284 auto ParseTranslationUnitImpl = [=, &result] {
3285 result = clang_parseTranslationUnit_Impl(
3286 CIdx, source_filename, command_line_args, num_command_line_args,
3287 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3288 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 llvm::CrashRecoveryContext CRC;
3290
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003291 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003292 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3293 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3294 fprintf(stderr, " 'command_line_args' : [");
3295 for (int i = 0; i != num_command_line_args; ++i) {
3296 if (i)
3297 fprintf(stderr, ", ");
3298 fprintf(stderr, "'%s'", command_line_args[i]);
3299 }
3300 fprintf(stderr, "],\n");
3301 fprintf(stderr, " 'unsaved_files' : [");
3302 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3303 if (i)
3304 fprintf(stderr, ", ");
3305 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3306 unsaved_files[i].Length);
3307 }
3308 fprintf(stderr, "],\n");
3309 fprintf(stderr, " 'options' : %d,\n", options);
3310 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003311
3312 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003314 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003315 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 }
Alp Toker5c532982014-07-07 22:42:03 +00003317
3318 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003319}
3320
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003321CXString clang_Type_getObjCEncoding(CXType CT) {
3322 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3323 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3324 std::string encoding;
3325 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3326 encoding);
3327
3328 return cxstring::createDup(encoding);
3329}
3330
3331static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3332 if (C.kind == CXCursor_MacroDefinition) {
3333 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3334 return MDR->getName();
3335 } else if (C.kind == CXCursor_MacroExpansion) {
3336 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3337 return ME.getName();
3338 }
3339 return nullptr;
3340}
3341
3342unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3343 const IdentifierInfo *II = getMacroIdentifier(C);
3344 if (!II) {
3345 return false;
3346 }
3347 ASTUnit *ASTU = getCursorASTUnit(C);
3348 Preprocessor &PP = ASTU->getPreprocessor();
3349 if (const MacroInfo *MI = PP.getMacroInfo(II))
3350 return MI->isFunctionLike();
3351 return false;
3352}
3353
3354unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3355 const IdentifierInfo *II = getMacroIdentifier(C);
3356 if (!II) {
3357 return false;
3358 }
3359 ASTUnit *ASTU = getCursorASTUnit(C);
3360 Preprocessor &PP = ASTU->getPreprocessor();
3361 if (const MacroInfo *MI = PP.getMacroInfo(II))
3362 return MI->isBuiltinMacro();
3363 return false;
3364}
3365
3366unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3367 const Decl *D = getCursorDecl(C);
3368 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3369 if (!FD) {
3370 return false;
3371 }
3372 return FD->isInlined();
3373}
3374
3375static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3376 if (callExpr->getNumArgs() != 1) {
3377 return nullptr;
3378 }
3379
3380 StringLiteral *S = nullptr;
3381 auto *arg = callExpr->getArg(0);
3382 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3383 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3384 auto *subExpr = I->getSubExprAsWritten();
3385
3386 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3387 return nullptr;
3388 }
3389
3390 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3391 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3392 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3393 } else {
3394 return nullptr;
3395 }
3396 return S;
3397}
3398
3399typedef struct {
3400 CXEvalResultKind EvalType;
3401 union {
3402 int intVal;
3403 double floatVal;
3404 char *stringVal;
3405 } EvalData;
3406} ExprEvalResult;
3407
3408void clang_EvalResult_dispose(CXEvalResult E) {
3409 ExprEvalResult *ER = (ExprEvalResult *)E;
3410 if (ER) {
3411 CXEvalResultKind evalType = ER->EvalType;
3412
3413 if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
3414 evalType != CXEval_Int && ER->EvalData.stringVal) {
3415 free((void *) ER->EvalData.stringVal);
3416 }
3417 free((void *)ER);
3418 }
3419}
3420
3421CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3422 if (!E) {
3423 return CXEval_UnExposed;
3424 }
3425 return ((ExprEvalResult *)E)->EvalType;
3426}
3427
3428int clang_EvalResult_getAsInt(CXEvalResult E) {
3429 if (!E) {
3430 return 0;
3431 }
3432 return ((ExprEvalResult *)E)->EvalData.intVal;
3433}
3434
3435double clang_EvalResult_getAsDouble(CXEvalResult E) {
3436 if (!E) {
3437 return 0;
3438 }
3439 return ((ExprEvalResult *)E)->EvalData.floatVal;
3440}
3441
3442const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3443 if (!E) {
3444 return nullptr;
3445 }
3446 return ((ExprEvalResult *)E)->EvalData.stringVal;
3447}
3448
3449static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3450 Expr::EvalResult ER;
3451 ASTContext &ctx = getCursorContext(C);
3452 if (!expr) {
3453 return nullptr;
3454 }
3455 expr = expr->IgnoreParens();
3456 bool res = expr->EvaluateAsRValue(ER, ctx);
3457 QualType rettype;
3458 CallExpr *callExpr;
3459 ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
3460 if (!result) {
3461 return nullptr;
3462 }
3463 result->EvalType = CXEval_UnExposed;
3464
3465 if (res) {
3466
3467 if (ER.Val.isInt()) {
3468 result->EvalType = CXEval_Int;
3469 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3470 return result;
3471 } else if (ER.Val.isFloat()) {
3472
3473 llvm::SmallVector<char, 100> Buffer;
3474 ER.Val.getFloat().toString(Buffer);
3475 std::string floatStr(Buffer.data(), Buffer.size());
3476 result->EvalType = CXEval_Float;
3477 bool ignored;
3478 llvm::APFloat apFloat = ER.Val.getFloat();
3479 apFloat.convert(llvm::APFloat::IEEEdouble,
3480 llvm::APFloat::rmNearestTiesToEven, &ignored);
3481 result->EvalData.floatVal = apFloat.convertToDouble();
3482 return result;
3483
3484 } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3485
3486 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3487 auto *subExpr = I->getSubExprAsWritten();
3488 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3489 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3490
3491 const StringLiteral *StrE = nullptr;
3492 const ObjCStringLiteral *ObjCExpr;
3493 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3494
3495 if (ObjCExpr) {
3496 StrE = ObjCExpr->getString();
3497 result->EvalType = CXEval_ObjCStrLiteral;
3498 } else {
3499 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3500 result->EvalType = CXEval_StrLiteral;
3501 }
3502
3503 std::string strRef(StrE->getString().str());
3504 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3505 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3506 strRef.size());
3507 result->EvalData.stringVal[strRef.size()] = '\0';
3508 return result;
3509 }
3510
3511 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3512 expr->getStmtClass() == Stmt::StringLiteralClass) {
3513
3514 const StringLiteral *StrE = nullptr;
3515 const ObjCStringLiteral *ObjCExpr;
3516 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3517
3518 if (ObjCExpr) {
3519 StrE = ObjCExpr->getString();
3520 result->EvalType = CXEval_ObjCStrLiteral;
3521 } else {
3522 StrE = cast<StringLiteral>(expr);
3523 result->EvalType = CXEval_StrLiteral;
3524 }
3525
3526 std::string strRef(StrE->getString().str());
3527 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3528 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3529 strRef.size());
3530 result->EvalData.stringVal[strRef.size()] = '\0';
3531 return result;
3532
3533 } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3534
3535 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3536
3537 rettype = CC->getType();
3538 if (rettype.getAsString() == "CFStringRef" &&
3539 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3540
3541 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3542 StringLiteral* S = getCFSTR_value(callExpr);
3543 if (S) {
3544 std::string strLiteral(S->getString().str());
3545 result->EvalType = CXEval_CFStr;
3546
3547 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3548 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3549 strLiteral.size());
3550 result->EvalData.stringVal[strLiteral.size()] = '\0';
3551 return result;
3552 }
3553 }
3554
3555 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3556
3557 callExpr = static_cast<CallExpr *>(expr);
3558 rettype = callExpr->getCallReturnType(ctx);
3559
3560 if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
3561 return nullptr;
3562 }
3563 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3564 if(callExpr->getNumArgs() == 1 &&
3565 !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
3566
3567 return nullptr;
3568 }
3569 } else if(rettype.getAsString() == "CFStringRef") {
3570
3571 StringLiteral* S = getCFSTR_value(callExpr);
3572 if (S) {
3573 std::string strLiteral(S->getString().str());
3574 result->EvalType = CXEval_CFStr;
3575 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3576 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3577 strLiteral.size());
3578 result->EvalData.stringVal[strLiteral.size()] = '\0';
3579 return result;
3580 }
3581 }
3582
3583 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3584
3585 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3586 ValueDecl *V = D->getDecl();
3587 if (V->getKind() == Decl::Function) {
3588 std::string strName(V->getNameAsString());
3589 result->EvalType = CXEval_Other;
3590 result->EvalData.stringVal = (char *)malloc(strName.size()+1);
3591 strncpy((char*)result->EvalData.stringVal, strName.c_str(),
3592 strName.size());
3593 result->EvalData.stringVal[strName.size()] = '\0';
3594 return result;
3595 }
3596 }
3597
3598 }
3599
3600 clang_EvalResult_dispose((CXEvalResult *)result);
3601 return nullptr;
3602}
3603
3604CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3605 const Decl *D = getCursorDecl(C);
3606 if (D) {
3607 const Expr *expr = nullptr;
3608 if (auto *Var = dyn_cast<VarDecl>(D)) {
3609 expr = Var->getInit();
3610 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3611 expr = Field->getInClassInitializer();
3612 }
3613 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003614 return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3615 evaluateExpr(const_cast<Expr *>(expr), C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003616 return nullptr;
3617 }
3618
3619 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3620 if (compoundStmt) {
3621 Expr *expr = nullptr;
3622 for (auto *bodyIterator : compoundStmt->body()) {
3623 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3624 break;
3625 }
3626 }
3627 if (expr)
Aaron Ballman01dc1572016-01-20 15:25:30 +00003628 return const_cast<CXEvalResult>(
3629 reinterpret_cast<const void *>(evaluateExpr(expr, C)));
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003630 }
3631 return nullptr;
3632}
3633
3634unsigned clang_Cursor_hasAttrs(CXCursor C) {
3635 const Decl *D = getCursorDecl(C);
3636 if (!D) {
3637 return 0;
3638 }
3639
3640 if (D->hasAttrs()) {
3641 return 1;
3642 }
3643
3644 return 0;
3645}
Guy Benyei11169dd2012-12-18 14:30:41 +00003646unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3647 return CXSaveTranslationUnit_None;
3648}
3649
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003650static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3651 const char *FileName,
3652 unsigned options) {
3653 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3655 setThreadBackgroundPriority();
3656
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003657 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3658 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003659}
3660
3661int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3662 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003663 LOG_FUNC_SECTION {
3664 *Log << TU << ' ' << FileName;
3665 }
3666
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003667 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003668 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003670 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003671
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003672 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3674 if (!CXXUnit->hasSema())
3675 return CXSaveError_InvalidTU;
3676
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003677 CXSaveError result;
3678 auto SaveTranslationUnitImpl = [=, &result]() {
3679 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3680 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003681
3682 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3683 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003684 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003685
3686 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3687 PrintLibclangResourceUsage(TU);
3688
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003689 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 }
3691
3692 // We have an AST that has invalid nodes due to compiler errors.
3693 // Use a crash recovery thread for protection.
3694
3695 llvm::CrashRecoveryContext CRC;
3696
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003697 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3699 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3700 fprintf(stderr, " 'options' : %d,\n", options);
3701 fprintf(stderr, "}\n");
3702
3703 return CXSaveError_Unknown;
3704
3705 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3706 PrintLibclangResourceUsage(TU);
3707 }
3708
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003709 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003710}
3711
3712void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3713 if (CTUnit) {
3714 // If the translation unit has been marked as unsafe to free, just discard
3715 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003716 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3717 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 return;
3719
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003720 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003721 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3723 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003724 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 delete CTUnit;
3726 }
3727}
3728
3729unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3730 return CXReparse_None;
3731}
3732
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003733static CXErrorCode
3734clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3735 ArrayRef<CXUnsavedFile> unsaved_files,
3736 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003737 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003738 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003739 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003740 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003741 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003742
3743 // Reset the associated diagnostics.
3744 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003745 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003746
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003747 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3749 setThreadBackgroundPriority();
3750
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003751 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003753
3754 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3755 new std::vector<ASTUnit::RemappedFile>());
3756
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 // Recover resources if we crash before exiting this function.
3758 llvm::CrashRecoveryContextCleanupRegistrar<
3759 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003760
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003761 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003762 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003763 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003764 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003766
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003767 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3768 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003769 return CXError_Success;
3770 if (isASTReadError(CXXUnit))
3771 return CXError_ASTReadError;
3772 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003773}
3774
3775int clang_reparseTranslationUnit(CXTranslationUnit TU,
3776 unsigned num_unsaved_files,
3777 struct CXUnsavedFile *unsaved_files,
3778 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003779 LOG_FUNC_SECTION {
3780 *Log << TU;
3781 }
3782
Alp Toker9d85b182014-07-07 01:23:14 +00003783 if (num_unsaved_files && !unsaved_files)
3784 return CXError_InvalidArguments;
3785
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003786 CXErrorCode result;
3787 auto ReparseTranslationUnitImpl = [=, &result]() {
3788 result = clang_reparseTranslationUnit_Impl(
3789 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3790 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003791
3792 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003793 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003794 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 }
3796
3797 llvm::CrashRecoveryContext CRC;
3798
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003799 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003801 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003802 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3804 PrintLibclangResourceUsage(TU);
3805
Alp Toker5c532982014-07-07 22:42:03 +00003806 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003807}
3808
3809
3810CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003811 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003812 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003813 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003814 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003815
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003816 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003817 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003818}
3819
3820CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003821 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003822 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003823 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003824 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003825
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003826 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3828}
3829
3830} // end: extern "C"
3831
3832//===----------------------------------------------------------------------===//
3833// CXFile Operations.
3834//===----------------------------------------------------------------------===//
3835
3836extern "C" {
3837CXString clang_getFileName(CXFile SFile) {
3838 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003839 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003840
3841 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003843}
3844
3845time_t clang_getFileTime(CXFile SFile) {
3846 if (!SFile)
3847 return 0;
3848
3849 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3850 return FEnt->getModificationTime();
3851}
3852
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003853CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003854 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003855 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003856 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003857 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003858
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003859 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003860
3861 FileManager &FMgr = CXXUnit->getFileManager();
3862 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3863}
3864
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003865unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3866 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003867 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003868 LOG_BAD_TU(TU);
3869 return 0;
3870 }
3871
3872 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 return 0;
3874
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003875 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 FileEntry *FEnt = static_cast<FileEntry *>(file);
3877 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3878 .isFileMultipleIncludeGuarded(FEnt);
3879}
3880
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003881int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3882 if (!file || !outID)
3883 return 1;
3884
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003885 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003886 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3887 outID->data[0] = ID.getDevice();
3888 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003889 outID->data[2] = FEnt->getModificationTime();
3890 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003891}
3892
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003893int clang_File_isEqual(CXFile file1, CXFile file2) {
3894 if (file1 == file2)
3895 return true;
3896
3897 if (!file1 || !file2)
3898 return false;
3899
3900 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3901 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3902 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3903}
3904
Guy Benyei11169dd2012-12-18 14:30:41 +00003905} // end: extern "C"
3906
3907//===----------------------------------------------------------------------===//
3908// CXCursor Operations.
3909//===----------------------------------------------------------------------===//
3910
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003911static const Decl *getDeclFromExpr(const Stmt *E) {
3912 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 return getDeclFromExpr(CE->getSubExpr());
3914
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003915 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003917 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003919 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003921 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 if (PRE->isExplicitProperty())
3923 return PRE->getExplicitProperty();
3924 // It could be messaging both getter and setter as in:
3925 // ++myobj.myprop;
3926 // in which case prefer to associate the setter since it is less obvious
3927 // from inspecting the source that the setter is going to get called.
3928 if (PRE->isMessagingSetter())
3929 return PRE->getImplicitPropertySetter();
3930 return PRE->getImplicitPropertyGetter();
3931 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003932 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003934 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003935 if (Expr *Src = OVE->getSourceExpr())
3936 return getDeclFromExpr(Src);
3937
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003938 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003940 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 if (!CE->isElidable())
3942 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003943 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003944 return OME->getMethodDecl();
3945
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003946 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003948 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3950 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003951 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3953 isa<ParmVarDecl>(SizeOfPack->getPack()))
3954 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003955
3956 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003957}
3958
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003959static SourceLocation getLocationFromExpr(const Expr *E) {
3960 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 return getLocationFromExpr(CE->getSubExpr());
3962
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003963 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003965 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003966 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003967 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003969 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003971 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003973 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 return PropRef->getLocation();
3975
3976 return E->getLocStart();
3977}
3978
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003979static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3980 std::unique_ptr<llvm::DataLayout> &DL,
3981 const NamedDecl *ND,
3982 unsigned StructorType) {
3983 std::string FrontendBuf;
3984 llvm::raw_string_ostream FOS(FrontendBuf);
3985
3986 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3987 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3988 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3989 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3990
3991 std::string BackendBuf;
3992 llvm::raw_string_ostream BOS(BackendBuf);
3993
3994 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3995
3996 return BOS.str();
3997}
3998
Guy Benyei11169dd2012-12-18 14:30:41 +00003999extern "C" {
4000
4001unsigned clang_visitChildren(CXCursor parent,
4002 CXCursorVisitor visitor,
4003 CXClientData client_data) {
4004 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4005 /*VisitPreprocessorLast=*/false);
4006 return CursorVis.VisitChildren(parent);
4007}
4008
4009#ifndef __has_feature
4010#define __has_feature(x) 0
4011#endif
4012#if __has_feature(blocks)
4013typedef enum CXChildVisitResult
4014 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
4015
4016static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4017 CXClientData client_data) {
4018 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4019 return block(cursor, parent);
4020}
4021#else
4022// If we are compiled with a compiler that doesn't have native blocks support,
4023// define and call the block manually, so the
4024typedef struct _CXChildVisitResult
4025{
4026 void *isa;
4027 int flags;
4028 int reserved;
4029 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4030 CXCursor);
4031} *CXCursorVisitorBlock;
4032
4033static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4034 CXClientData client_data) {
4035 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4036 return block->invoke(block, cursor, parent);
4037}
4038#endif
4039
4040
4041unsigned clang_visitChildrenWithBlock(CXCursor parent,
4042 CXCursorVisitorBlock block) {
4043 return clang_visitChildren(parent, visitWithBlock, block);
4044}
4045
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004046static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004048 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004049
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004050 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004052 if (const ObjCPropertyImplDecl *PropImpl =
4053 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004055 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004056
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004057 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004059 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004060
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004061 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 }
4063
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004064 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004065 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004066
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004067 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4069 // and returns different names. NamedDecl returns the class name and
4070 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004071 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004072
4073 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004074 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004075
4076 SmallString<1024> S;
4077 llvm::raw_svector_ostream os(S);
4078 ND->printName(os);
4079
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004080 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004081}
4082
4083CXString clang_getCursorSpelling(CXCursor C) {
4084 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004085 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004086
4087 if (clang_isReference(C.kind)) {
4088 switch (C.kind) {
4089 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004090 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004091 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 }
4093 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004094 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004095 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 }
4097 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004098 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 }
4102 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004103 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004104 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 }
4106 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004107 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 assert(Type && "Missing type decl");
4109
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004110 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 getAsString());
4112 }
4113 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004114 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 assert(Template && "Missing template decl");
4116
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004117 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004118 }
4119
4120 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004121 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 assert(NS && "Missing namespace decl");
4123
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004124 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 }
4126
4127 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004128 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 assert(Field && "Missing member decl");
4130
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004131 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 }
4133
4134 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004135 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 assert(Label && "Missing label");
4137
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 }
4140
4141 case CXCursor_OverloadedDeclRef: {
4142 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004143 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4144 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004145 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004146 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004148 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004149 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004150 OverloadedTemplateStorage *Ovl
4151 = Storage.get<OverloadedTemplateStorage*>();
4152 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004153 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004154 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 }
4156
4157 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004158 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 assert(Var && "Missing variable decl");
4160
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004161 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 }
4163
4164 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004165 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 }
4167 }
4168
4169 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004170 const Expr *E = getCursorExpr(C);
4171
4172 if (C.kind == CXCursor_ObjCStringLiteral ||
4173 C.kind == CXCursor_StringLiteral) {
4174 const StringLiteral *SLit;
4175 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4176 SLit = OSL->getString();
4177 } else {
4178 SLit = cast<StringLiteral>(E);
4179 }
4180 SmallString<256> Buf;
4181 llvm::raw_svector_ostream OS(Buf);
4182 SLit->outputString(OS);
4183 return cxstring::createDup(OS.str());
4184 }
4185
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004186 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 if (D)
4188 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004189 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 }
4191
4192 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004193 const Stmt *S = getCursorStmt(C);
4194 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004195 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004196
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004197 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 }
4199
4200 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004201 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 ->getNameStart());
4203
4204 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004205 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 ->getNameStart());
4207
4208 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004209 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004210
4211 if (clang_isDeclaration(C.kind))
4212 return getDeclSpelling(getCursorDecl(C));
4213
4214 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004215 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004216 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 }
4218
4219 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004220 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004221 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 }
4223
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004224 if (C.kind == CXCursor_PackedAttr) {
4225 return cxstring::createRef("packed");
4226 }
4227
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004228 if (C.kind == CXCursor_VisibilityAttr) {
4229 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4230 switch (AA->getVisibility()) {
4231 case VisibilityAttr::VisibilityType::Default:
4232 return cxstring::createRef("default");
4233 case VisibilityAttr::VisibilityType::Hidden:
4234 return cxstring::createRef("hidden");
4235 case VisibilityAttr::VisibilityType::Protected:
4236 return cxstring::createRef("protected");
4237 }
4238 llvm_unreachable("unknown visibility type");
4239 }
4240
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004241 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004242}
4243
4244CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4245 unsigned pieceIndex,
4246 unsigned options) {
4247 if (clang_Cursor_isNull(C))
4248 return clang_getNullRange();
4249
4250 ASTContext &Ctx = getCursorContext(C);
4251
4252 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004253 const Stmt *S = getCursorStmt(C);
4254 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 if (pieceIndex > 0)
4256 return clang_getNullRange();
4257 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4258 }
4259
4260 return clang_getNullRange();
4261 }
4262
4263 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004264 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4266 if (pieceIndex >= ME->getNumSelectorLocs())
4267 return clang_getNullRange();
4268 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4269 }
4270 }
4271
4272 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4273 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004274 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4276 if (pieceIndex >= MD->getNumSelectorLocs())
4277 return clang_getNullRange();
4278 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4279 }
4280 }
4281
4282 if (C.kind == CXCursor_ObjCCategoryDecl ||
4283 C.kind == CXCursor_ObjCCategoryImplDecl) {
4284 if (pieceIndex > 0)
4285 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004286 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4288 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004289 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4291 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4292 }
4293
4294 if (C.kind == CXCursor_ModuleImportDecl) {
4295 if (pieceIndex > 0)
4296 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004297 if (const ImportDecl *ImportD =
4298 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4300 if (!Locs.empty())
4301 return cxloc::translateSourceRange(Ctx,
4302 SourceRange(Locs.front(), Locs.back()));
4303 }
4304 return clang_getNullRange();
4305 }
4306
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004307 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4308 C.kind == CXCursor_ConversionFunction) {
4309 if (pieceIndex > 0)
4310 return clang_getNullRange();
4311 if (const FunctionDecl *FD =
4312 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4313 DeclarationNameInfo FunctionName = FD->getNameInfo();
4314 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4315 }
4316 return clang_getNullRange();
4317 }
4318
Guy Benyei11169dd2012-12-18 14:30:41 +00004319 // FIXME: A CXCursor_InclusionDirective should give the location of the
4320 // filename, but we don't keep track of this.
4321
4322 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4323 // but we don't keep track of this.
4324
4325 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4326 // but we don't keep track of this.
4327
4328 // Default handling, give the location of the cursor.
4329
4330 if (pieceIndex > 0)
4331 return clang_getNullRange();
4332
4333 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4334 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4335 return cxloc::translateSourceRange(Ctx, Loc);
4336}
4337
Eli Bendersky44a206f2014-07-31 18:04:56 +00004338CXString clang_Cursor_getMangling(CXCursor C) {
4339 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4340 return cxstring::createEmpty();
4341
Eli Bendersky44a206f2014-07-31 18:04:56 +00004342 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004343 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004344 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4345 return cxstring::createEmpty();
4346
Eli Bendersky79759592014-08-01 15:01:10 +00004347 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00004348 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00004349 ASTContext &Ctx = ND->getASTContext();
4350 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004351
Eli Bendersky79759592014-08-01 15:01:10 +00004352 std::string FrontendBuf;
4353 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00004354 if (MC->shouldMangleDeclName(ND)) {
4355 MC->mangleName(ND, FrontendBufOS);
4356 } else {
4357 ND->printName(FrontendBufOS);
4358 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00004359
Eli Bendersky79759592014-08-01 15:01:10 +00004360 // Now apply backend mangling.
4361 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00004362 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00004363
4364 std::string FinalBuf;
4365 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00004366 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
4367 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00004368
4369 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004370}
4371
Saleem Abdulrasool5e03c652016-02-06 22:36:34 +00004372static std::string getMangledName(std::unique_ptr<MangleContext> &M,
4373 std::unique_ptr<llvm::DataLayout> &DL,
4374 const NamedDecl *ND) {
4375 std::string FrontendBuf;
4376 llvm::raw_string_ostream FOS(FrontendBuf);
4377
4378 M->mangleName(ND, FOS);
4379
4380 std::string BackendBuf;
4381 llvm::raw_string_ostream BOS(BackendBuf);
4382
4383 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
4384
4385 return BOS.str();
4386}
4387
4388static std::string getMangledThunk(std::unique_ptr<MangleContext> &M,
4389 std::unique_ptr<llvm::DataLayout> &DL,
4390 const CXXMethodDecl *MD, const ThunkInfo &T) {
4391 std::string FrontendBuf;
4392 llvm::raw_string_ostream FOS(FrontendBuf);
4393
4394 M->mangleThunk(MD, T, FOS);
4395
4396 std::string BackendBuf;
4397 llvm::raw_string_ostream BOS(BackendBuf);
4398
4399 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
4400
4401 return BOS.str();
4402}
4403
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004404CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4405 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4406 return nullptr;
4407
4408 const Decl *D = getCursorDecl(C);
4409 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4410 return nullptr;
4411
4412 const NamedDecl *ND = cast<NamedDecl>(D);
4413
4414 ASTContext &Ctx = ND->getASTContext();
4415 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
4416 std::unique_ptr<llvm::DataLayout> DL(
4417 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
4418
4419 std::vector<std::string> Manglings;
4420
4421 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4422 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4423 /*IsCSSMethod=*/true);
4424 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4425 return CC == DefaultCC;
4426 };
4427
4428 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4429 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4430
4431 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4432 if (!CD->getParent()->isAbstract())
4433 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4434
4435 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4436 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4437 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4438 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4439 Ctor_DefaultClosure));
4440 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4441 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4442 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4443 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
Saleem Abdulrasoold5af8ae2015-12-10 06:30:23 +00004444 if (DD->isVirtual())
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004445 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4446 }
Saleem Abdulrasool5e03c652016-02-06 22:36:34 +00004447 } else if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
4448 Manglings.emplace_back(getMangledName(M, DL, ND));
4449 if (MD->isVirtual())
4450 if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD))
4451 for (const auto &T : *TIV)
4452 Manglings.emplace_back(getMangledThunk(M, DL, MD, T));
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004453 }
4454
4455 return cxstring::createSet(Manglings);
4456}
4457
Guy Benyei11169dd2012-12-18 14:30:41 +00004458CXString clang_getCursorDisplayName(CXCursor C) {
4459 if (!clang_isDeclaration(C.kind))
4460 return clang_getCursorSpelling(C);
4461
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004462 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004464 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004465
4466 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004467 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 D = FunTmpl->getTemplatedDecl();
4469
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004470 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 SmallString<64> Str;
4472 llvm::raw_svector_ostream OS(Str);
4473 OS << *Function;
4474 if (Function->getPrimaryTemplate())
4475 OS << "<>";
4476 OS << "(";
4477 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4478 if (I)
4479 OS << ", ";
4480 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4481 }
4482
4483 if (Function->isVariadic()) {
4484 if (Function->getNumParams())
4485 OS << ", ";
4486 OS << "...";
4487 }
4488 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004489 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 }
4491
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004492 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 SmallString<64> Str;
4494 llvm::raw_svector_ostream OS(Str);
4495 OS << *ClassTemplate;
4496 OS << "<";
4497 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4498 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4499 if (I)
4500 OS << ", ";
4501
4502 NamedDecl *Param = Params->getParam(I);
4503 if (Param->getIdentifier()) {
4504 OS << Param->getIdentifier()->getName();
4505 continue;
4506 }
4507
4508 // There is no parameter name, which makes this tricky. Try to come up
4509 // with something useful that isn't too long.
4510 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4511 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4512 else if (NonTypeTemplateParmDecl *NTTP
4513 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4514 OS << NTTP->getType().getAsString(Policy);
4515 else
4516 OS << "template<...> class";
4517 }
4518
4519 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004520 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 }
4522
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004523 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4525 // If the type was explicitly written, use that.
4526 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004527 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004528
Benjamin Kramer9170e912013-02-22 15:46:01 +00004529 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004530 llvm::raw_svector_ostream OS(Str);
4531 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004532 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 ClassSpec->getTemplateArgs().data(),
4534 ClassSpec->getTemplateArgs().size(),
4535 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004536 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 }
4538
4539 return clang_getCursorSpelling(C);
4540}
4541
4542CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4543 switch (Kind) {
4544 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004545 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004547 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004549 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004551 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004553 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004555 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004557 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004559 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004561 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004563 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004565 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004567 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004569 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004571 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004573 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004574 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004575 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004576 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004577 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004579 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004581 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004583 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004585 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004587 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004589 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004591 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004593 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004594 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004595 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004596 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004597 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004599 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004601 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004602 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004603 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004605 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004606 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004607 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004609 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004611 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004613 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004615 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004617 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004619 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004621 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004622 case CXCursor_OMPArraySectionExpr:
4623 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004625 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004626 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004627 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004629 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004631 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004633 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004635 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004637 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004639 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004641 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004642 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004643 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004645 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004647 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004648 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004649 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004651 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004653 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004655 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004656 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004657 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004659 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004660 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004661 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004663 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004665 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004667 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004669 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004671 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004672 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004673 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004674 case CXCursor_ObjCSelfExpr:
4675 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004676 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004677 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004678 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004679 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004680 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004681 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004682 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004683 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004685 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004686 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004687 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004689 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004691 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004692 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004693 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004694 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004695 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004696 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004697 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004698 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004699 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004700 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004701 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004703 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004704 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004705 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004706 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004707 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004708 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004709 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004711 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004713 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004714 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004715 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004716 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004717 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004719 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004720 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004721 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004723 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004724 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004725 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004726 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004727 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004729 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004731 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004733 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004735 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004737 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004739 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004740 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004741 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004743 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004745 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004747 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004749 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004751 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004752 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004753 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004755 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004757 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004758 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004759 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004761 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004762 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004763 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004764 case CXCursor_SEHLeaveStmt:
4765 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004767 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004769 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004771 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004773 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004775 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004776 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004777 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004778 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004779 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004780 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004781 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004782 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004783 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004785 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004787 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004788 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004789 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004790 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004791 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004792 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004793 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004794 case CXCursor_PackedAttr:
4795 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004796 case CXCursor_PureAttr:
4797 return cxstring::createRef("attribute(pure)");
4798 case CXCursor_ConstAttr:
4799 return cxstring::createRef("attribute(const)");
4800 case CXCursor_NoDuplicateAttr:
4801 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004802 case CXCursor_CUDAConstantAttr:
4803 return cxstring::createRef("attribute(constant)");
4804 case CXCursor_CUDADeviceAttr:
4805 return cxstring::createRef("attribute(device)");
4806 case CXCursor_CUDAGlobalAttr:
4807 return cxstring::createRef("attribute(global)");
4808 case CXCursor_CUDAHostAttr:
4809 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004810 case CXCursor_CUDASharedAttr:
4811 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004812 case CXCursor_VisibilityAttr:
4813 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004814 case CXCursor_DLLExport:
4815 return cxstring::createRef("attribute(dllexport)");
4816 case CXCursor_DLLImport:
4817 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004819 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004820 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004821 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004823 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004825 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004826 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004827 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004828 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004829 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004831 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004833 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004834 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004835 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004836 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004837 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004839 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004840 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004841 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004842 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004843 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004845 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004846 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004847 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004848 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004849 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004850 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004851 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004852 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004853 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004854 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004855 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004856 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004857 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004858 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004859 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004860 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004861 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004862 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004863 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004864 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004865 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004866 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004867 return cxstring::createRef("OMPParallelDirective");
4868 case CXCursor_OMPSimdDirective:
4869 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004870 case CXCursor_OMPForDirective:
4871 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004872 case CXCursor_OMPForSimdDirective:
4873 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004874 case CXCursor_OMPSectionsDirective:
4875 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004876 case CXCursor_OMPSectionDirective:
4877 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004878 case CXCursor_OMPSingleDirective:
4879 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004880 case CXCursor_OMPMasterDirective:
4881 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004882 case CXCursor_OMPCriticalDirective:
4883 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004884 case CXCursor_OMPParallelForDirective:
4885 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004886 case CXCursor_OMPParallelForSimdDirective:
4887 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004888 case CXCursor_OMPParallelSectionsDirective:
4889 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004890 case CXCursor_OMPTaskDirective:
4891 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004892 case CXCursor_OMPTaskyieldDirective:
4893 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004894 case CXCursor_OMPBarrierDirective:
4895 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004896 case CXCursor_OMPTaskwaitDirective:
4897 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004898 case CXCursor_OMPTaskgroupDirective:
4899 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004900 case CXCursor_OMPFlushDirective:
4901 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004902 case CXCursor_OMPOrderedDirective:
4903 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004904 case CXCursor_OMPAtomicDirective:
4905 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004906 case CXCursor_OMPTargetDirective:
4907 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004908 case CXCursor_OMPTargetDataDirective:
4909 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004910 case CXCursor_OMPTargetEnterDataDirective:
4911 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004912 case CXCursor_OMPTargetExitDataDirective:
4913 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004914 case CXCursor_OMPTargetParallelDirective:
4915 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004916 case CXCursor_OMPTargetParallelForDirective:
4917 return cxstring::createRef("OMPTargetParallelForDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004918 case CXCursor_OMPTeamsDirective:
4919 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004920 case CXCursor_OMPCancellationPointDirective:
4921 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004922 case CXCursor_OMPCancelDirective:
4923 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004924 case CXCursor_OMPTaskLoopDirective:
4925 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004926 case CXCursor_OMPTaskLoopSimdDirective:
4927 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004928 case CXCursor_OMPDistributeDirective:
4929 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004930 case CXCursor_OverloadCandidate:
4931 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004932 case CXCursor_TypeAliasTemplateDecl:
4933 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004934 }
4935
4936 llvm_unreachable("Unhandled CXCursorKind");
4937}
4938
4939struct GetCursorData {
4940 SourceLocation TokenBeginLoc;
4941 bool PointsAtMacroArgExpansion;
4942 bool VisitedObjCPropertyImplDecl;
4943 SourceLocation VisitedDeclaratorDeclStartLoc;
4944 CXCursor &BestCursor;
4945
4946 GetCursorData(SourceManager &SM,
4947 SourceLocation tokenBegin, CXCursor &outputCursor)
4948 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4949 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4950 VisitedObjCPropertyImplDecl = false;
4951 }
4952};
4953
4954static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4955 CXCursor parent,
4956 CXClientData client_data) {
4957 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4958 CXCursor *BestCursor = &Data->BestCursor;
4959
4960 // If we point inside a macro argument we should provide info of what the
4961 // token is so use the actual cursor, don't replace it with a macro expansion
4962 // cursor.
4963 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4964 return CXChildVisit_Recurse;
4965
4966 if (clang_isDeclaration(cursor.kind)) {
4967 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004968 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004969 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4970 if (MD->isImplicit())
4971 return CXChildVisit_Break;
4972
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004973 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004974 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4975 // Check that when we have multiple @class references in the same line,
4976 // that later ones do not override the previous ones.
4977 // If we have:
4978 // @class Foo, Bar;
4979 // source ranges for both start at '@', so 'Bar' will end up overriding
4980 // 'Foo' even though the cursor location was at 'Foo'.
4981 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4982 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004983 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004984 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4985 if (PrevID != ID &&
4986 !PrevID->isThisDeclarationADefinition() &&
4987 !ID->isThisDeclarationADefinition())
4988 return CXChildVisit_Break;
4989 }
4990
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004991 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4993 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4994 // Check that when we have multiple declarators in the same line,
4995 // that later ones do not override the previous ones.
4996 // If we have:
4997 // int Foo, Bar;
4998 // source ranges for both start at 'int', so 'Bar' will end up overriding
4999 // 'Foo' even though the cursor location was at 'Foo'.
5000 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5001 return CXChildVisit_Break;
5002 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5003
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005004 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
5006 (void)PropImp;
5007 // Check that when we have multiple @synthesize in the same line,
5008 // that later ones do not override the previous ones.
5009 // If we have:
5010 // @synthesize Foo, Bar;
5011 // source ranges for both start at '@', so 'Bar' will end up overriding
5012 // 'Foo' even though the cursor location was at 'Foo'.
5013 if (Data->VisitedObjCPropertyImplDecl)
5014 return CXChildVisit_Break;
5015 Data->VisitedObjCPropertyImplDecl = true;
5016 }
5017 }
5018
5019 if (clang_isExpression(cursor.kind) &&
5020 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005021 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005022 // Avoid having the cursor of an expression replace the declaration cursor
5023 // when the expression source range overlaps the declaration range.
5024 // This can happen for C++ constructor expressions whose range generally
5025 // include the variable declaration, e.g.:
5026 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
5027 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5028 D->getLocation() == Data->TokenBeginLoc)
5029 return CXChildVisit_Break;
5030 }
5031 }
5032
5033 // If our current best cursor is the construction of a temporary object,
5034 // don't replace that cursor with a type reference, because we want
5035 // clang_getCursor() to point at the constructor.
5036 if (clang_isExpression(BestCursor->kind) &&
5037 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5038 cursor.kind == CXCursor_TypeRef) {
5039 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5040 // as having the actual point on the type reference.
5041 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5042 return CXChildVisit_Recurse;
5043 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005044
5045 // If we already have an Objective-C superclass reference, don't
5046 // update it further.
5047 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5048 return CXChildVisit_Break;
5049
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 *BestCursor = cursor;
5051 return CXChildVisit_Recurse;
5052}
5053
5054CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005055 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005056 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005057 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005058 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005059
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005060 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005061 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5062
5063 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5064 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5065
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005066 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 CXFile SearchFile;
5068 unsigned SearchLine, SearchColumn;
5069 CXFile ResultFile;
5070 unsigned ResultLine, ResultColumn;
5071 CXString SearchFileName, ResultFileName, KindSpelling, USR;
5072 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
5073 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005074
5075 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5076 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005077 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00005078 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005079 SearchFileName = clang_getFileName(SearchFile);
5080 ResultFileName = clang_getFileName(ResultFile);
5081 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5082 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005083 *Log << llvm::format("(%s:%d:%d) = %s",
5084 clang_getCString(SearchFileName), SearchLine, SearchColumn,
5085 clang_getCString(KindSpelling))
5086 << llvm::format("(%s:%d:%d):%s%s",
5087 clang_getCString(ResultFileName), ResultLine, ResultColumn,
5088 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005089 clang_disposeString(SearchFileName);
5090 clang_disposeString(ResultFileName);
5091 clang_disposeString(KindSpelling);
5092 clang_disposeString(USR);
5093
5094 CXCursor Definition = clang_getCursorDefinition(Result);
5095 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5096 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5097 CXString DefinitionKindSpelling
5098 = clang_getCursorKindSpelling(Definition.kind);
5099 CXFile DefinitionFile;
5100 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005101 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005102 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005104 *Log << llvm::format(" -> %s(%s:%d:%d)",
5105 clang_getCString(DefinitionKindSpelling),
5106 clang_getCString(DefinitionFileName),
5107 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 clang_disposeString(DefinitionFileName);
5109 clang_disposeString(DefinitionKindSpelling);
5110 }
5111 }
5112
5113 return Result;
5114}
5115
5116CXCursor clang_getNullCursor(void) {
5117 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5118}
5119
5120unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005121 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5122 // can't set consistently. For example, when visiting a DeclStmt we will set
5123 // it but we don't set it on the result of clang_getCursorDefinition for
5124 // a reference of the same declaration.
5125 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5126 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5127 // to provide that kind of info.
5128 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005129 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005130 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005131 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005132
Guy Benyei11169dd2012-12-18 14:30:41 +00005133 return X == Y;
5134}
5135
5136unsigned clang_hashCursor(CXCursor C) {
5137 unsigned Index = 0;
5138 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5139 Index = 1;
5140
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005141 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 std::make_pair(C.kind, C.data[Index]));
5143}
5144
5145unsigned clang_isInvalid(enum CXCursorKind K) {
5146 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5147}
5148
5149unsigned clang_isDeclaration(enum CXCursorKind K) {
5150 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5151 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5152}
5153
5154unsigned clang_isReference(enum CXCursorKind K) {
5155 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5156}
5157
5158unsigned clang_isExpression(enum CXCursorKind K) {
5159 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5160}
5161
5162unsigned clang_isStatement(enum CXCursorKind K) {
5163 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5164}
5165
5166unsigned clang_isAttribute(enum CXCursorKind K) {
5167 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5168}
5169
5170unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5171 return K == CXCursor_TranslationUnit;
5172}
5173
5174unsigned clang_isPreprocessing(enum CXCursorKind K) {
5175 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5176}
5177
5178unsigned clang_isUnexposed(enum CXCursorKind K) {
5179 switch (K) {
5180 case CXCursor_UnexposedDecl:
5181 case CXCursor_UnexposedExpr:
5182 case CXCursor_UnexposedStmt:
5183 case CXCursor_UnexposedAttr:
5184 return true;
5185 default:
5186 return false;
5187 }
5188}
5189
5190CXCursorKind clang_getCursorKind(CXCursor C) {
5191 return C.kind;
5192}
5193
5194CXSourceLocation clang_getCursorLocation(CXCursor C) {
5195 if (clang_isReference(C.kind)) {
5196 switch (C.kind) {
5197 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005198 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005199 = getCursorObjCSuperClassRef(C);
5200 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5201 }
5202
5203 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005204 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 = getCursorObjCProtocolRef(C);
5206 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5207 }
5208
5209 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005210 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 = getCursorObjCClassRef(C);
5212 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5213 }
5214
5215 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005216 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5218 }
5219
5220 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005221 std::pair<const TemplateDecl *, SourceLocation> P =
5222 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005223 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5224 }
5225
5226 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005227 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5229 }
5230
5231 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005232 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005233 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5234 }
5235
5236 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005237 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5239 }
5240
5241 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005242 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005243 if (!BaseSpec)
5244 return clang_getNullLocation();
5245
5246 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5247 return cxloc::translateSourceLocation(getCursorContext(C),
5248 TSInfo->getTypeLoc().getBeginLoc());
5249
5250 return cxloc::translateSourceLocation(getCursorContext(C),
5251 BaseSpec->getLocStart());
5252 }
5253
5254 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005255 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5257 }
5258
5259 case CXCursor_OverloadedDeclRef:
5260 return cxloc::translateSourceLocation(getCursorContext(C),
5261 getCursorOverloadedDeclRef(C).second);
5262
5263 default:
5264 // FIXME: Need a way to enumerate all non-reference cases.
5265 llvm_unreachable("Missed a reference kind");
5266 }
5267 }
5268
5269 if (clang_isExpression(C.kind))
5270 return cxloc::translateSourceLocation(getCursorContext(C),
5271 getLocationFromExpr(getCursorExpr(C)));
5272
5273 if (clang_isStatement(C.kind))
5274 return cxloc::translateSourceLocation(getCursorContext(C),
5275 getCursorStmt(C)->getLocStart());
5276
5277 if (C.kind == CXCursor_PreprocessingDirective) {
5278 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5279 return cxloc::translateSourceLocation(getCursorContext(C), L);
5280 }
5281
5282 if (C.kind == CXCursor_MacroExpansion) {
5283 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005284 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 return cxloc::translateSourceLocation(getCursorContext(C), L);
5286 }
5287
5288 if (C.kind == CXCursor_MacroDefinition) {
5289 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5290 return cxloc::translateSourceLocation(getCursorContext(C), L);
5291 }
5292
5293 if (C.kind == CXCursor_InclusionDirective) {
5294 SourceLocation L
5295 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5296 return cxloc::translateSourceLocation(getCursorContext(C), L);
5297 }
5298
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005299 if (clang_isAttribute(C.kind)) {
5300 SourceLocation L
5301 = cxcursor::getCursorAttr(C)->getLocation();
5302 return cxloc::translateSourceLocation(getCursorContext(C), L);
5303 }
5304
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 if (!clang_isDeclaration(C.kind))
5306 return clang_getNullLocation();
5307
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005308 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005309 if (!D)
5310 return clang_getNullLocation();
5311
5312 SourceLocation Loc = D->getLocation();
5313 // FIXME: Multiple variables declared in a single declaration
5314 // currently lack the information needed to correctly determine their
5315 // ranges when accounting for the type-specifier. We use context
5316 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5317 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005318 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005319 if (!cxcursor::isFirstInDeclGroup(C))
5320 Loc = VD->getLocation();
5321 }
5322
5323 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005324 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005325 Loc = MD->getSelectorStartLoc();
5326
5327 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5328}
5329
5330} // end extern "C"
5331
5332CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5333 assert(TU);
5334
5335 // Guard against an invalid SourceLocation, or we may assert in one
5336 // of the following calls.
5337 if (SLoc.isInvalid())
5338 return clang_getNullCursor();
5339
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005340 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005341
5342 // Translate the given source location to make it point at the beginning of
5343 // the token under the cursor.
5344 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5345 CXXUnit->getASTContext().getLangOpts());
5346
5347 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5348 if (SLoc.isValid()) {
5349 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5350 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5351 /*VisitPreprocessorLast=*/true,
5352 /*VisitIncludedEntities=*/false,
5353 SourceLocation(SLoc));
5354 CursorVis.visitFileRegion();
5355 }
5356
5357 return Result;
5358}
5359
5360static SourceRange getRawCursorExtent(CXCursor C) {
5361 if (clang_isReference(C.kind)) {
5362 switch (C.kind) {
5363 case CXCursor_ObjCSuperClassRef:
5364 return getCursorObjCSuperClassRef(C).second;
5365
5366 case CXCursor_ObjCProtocolRef:
5367 return getCursorObjCProtocolRef(C).second;
5368
5369 case CXCursor_ObjCClassRef:
5370 return getCursorObjCClassRef(C).second;
5371
5372 case CXCursor_TypeRef:
5373 return getCursorTypeRef(C).second;
5374
5375 case CXCursor_TemplateRef:
5376 return getCursorTemplateRef(C).second;
5377
5378 case CXCursor_NamespaceRef:
5379 return getCursorNamespaceRef(C).second;
5380
5381 case CXCursor_MemberRef:
5382 return getCursorMemberRef(C).second;
5383
5384 case CXCursor_CXXBaseSpecifier:
5385 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5386
5387 case CXCursor_LabelRef:
5388 return getCursorLabelRef(C).second;
5389
5390 case CXCursor_OverloadedDeclRef:
5391 return getCursorOverloadedDeclRef(C).second;
5392
5393 case CXCursor_VariableRef:
5394 return getCursorVariableRef(C).second;
5395
5396 default:
5397 // FIXME: Need a way to enumerate all non-reference cases.
5398 llvm_unreachable("Missed a reference kind");
5399 }
5400 }
5401
5402 if (clang_isExpression(C.kind))
5403 return getCursorExpr(C)->getSourceRange();
5404
5405 if (clang_isStatement(C.kind))
5406 return getCursorStmt(C)->getSourceRange();
5407
5408 if (clang_isAttribute(C.kind))
5409 return getCursorAttr(C)->getRange();
5410
5411 if (C.kind == CXCursor_PreprocessingDirective)
5412 return cxcursor::getCursorPreprocessingDirective(C);
5413
5414 if (C.kind == CXCursor_MacroExpansion) {
5415 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005416 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005417 return TU->mapRangeFromPreamble(Range);
5418 }
5419
5420 if (C.kind == CXCursor_MacroDefinition) {
5421 ASTUnit *TU = getCursorASTUnit(C);
5422 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5423 return TU->mapRangeFromPreamble(Range);
5424 }
5425
5426 if (C.kind == CXCursor_InclusionDirective) {
5427 ASTUnit *TU = getCursorASTUnit(C);
5428 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5429 return TU->mapRangeFromPreamble(Range);
5430 }
5431
5432 if (C.kind == CXCursor_TranslationUnit) {
5433 ASTUnit *TU = getCursorASTUnit(C);
5434 FileID MainID = TU->getSourceManager().getMainFileID();
5435 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5436 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5437 return SourceRange(Start, End);
5438 }
5439
5440 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005441 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 if (!D)
5443 return SourceRange();
5444
5445 SourceRange R = D->getSourceRange();
5446 // FIXME: Multiple variables declared in a single declaration
5447 // currently lack the information needed to correctly determine their
5448 // ranges when accounting for the type-specifier. We use context
5449 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5450 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005451 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005452 if (!cxcursor::isFirstInDeclGroup(C))
5453 R.setBegin(VD->getLocation());
5454 }
5455 return R;
5456 }
5457 return SourceRange();
5458}
5459
5460/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5461/// the decl-specifier-seq for declarations.
5462static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5463 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005464 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 if (!D)
5466 return SourceRange();
5467
5468 SourceRange R = D->getSourceRange();
5469
5470 // Adjust the start of the location for declarations preceded by
5471 // declaration specifiers.
5472 SourceLocation StartLoc;
5473 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5474 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5475 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005476 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5478 StartLoc = TI->getTypeLoc().getLocStart();
5479 }
5480
5481 if (StartLoc.isValid() && R.getBegin().isValid() &&
5482 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5483 R.setBegin(StartLoc);
5484
5485 // FIXME: Multiple variables declared in a single declaration
5486 // currently lack the information needed to correctly determine their
5487 // ranges when accounting for the type-specifier. We use context
5488 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5489 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005490 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 if (!cxcursor::isFirstInDeclGroup(C))
5492 R.setBegin(VD->getLocation());
5493 }
5494
5495 return R;
5496 }
5497
5498 return getRawCursorExtent(C);
5499}
5500
5501extern "C" {
5502
5503CXSourceRange clang_getCursorExtent(CXCursor C) {
5504 SourceRange R = getRawCursorExtent(C);
5505 if (R.isInvalid())
5506 return clang_getNullRange();
5507
5508 return cxloc::translateSourceRange(getCursorContext(C), R);
5509}
5510
5511CXCursor clang_getCursorReferenced(CXCursor C) {
5512 if (clang_isInvalid(C.kind))
5513 return clang_getNullCursor();
5514
5515 CXTranslationUnit tu = getCursorTU(C);
5516 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005517 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005518 if (!D)
5519 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005520 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005521 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005522 if (const ObjCPropertyImplDecl *PropImpl =
5523 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005524 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5525 return MakeCXCursor(Property, tu);
5526
5527 return C;
5528 }
5529
5530 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005531 const Expr *E = getCursorExpr(C);
5532 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005533 if (D) {
5534 CXCursor declCursor = MakeCXCursor(D, tu);
5535 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5536 declCursor);
5537 return declCursor;
5538 }
5539
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005540 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005541 return MakeCursorOverloadedDeclRef(Ovl, tu);
5542
5543 return clang_getNullCursor();
5544 }
5545
5546 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005547 const Stmt *S = getCursorStmt(C);
5548 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005549 if (LabelDecl *label = Goto->getLabel())
5550 if (LabelStmt *labelS = label->getStmt())
5551 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5552
5553 return clang_getNullCursor();
5554 }
Richard Smith66a81862015-05-04 02:25:31 +00005555
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005557 if (const MacroDefinitionRecord *Def =
5558 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005559 return MakeMacroDefinitionCursor(Def, tu);
5560 }
5561
5562 if (!clang_isReference(C.kind))
5563 return clang_getNullCursor();
5564
5565 switch (C.kind) {
5566 case CXCursor_ObjCSuperClassRef:
5567 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5568
5569 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005570 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5571 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005572 return MakeCXCursor(Def, tu);
5573
5574 return MakeCXCursor(Prot, tu);
5575 }
5576
5577 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005578 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5579 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005580 return MakeCXCursor(Def, tu);
5581
5582 return MakeCXCursor(Class, tu);
5583 }
5584
5585 case CXCursor_TypeRef:
5586 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5587
5588 case CXCursor_TemplateRef:
5589 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5590
5591 case CXCursor_NamespaceRef:
5592 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5593
5594 case CXCursor_MemberRef:
5595 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5596
5597 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005598 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5600 tu ));
5601 }
5602
5603 case CXCursor_LabelRef:
5604 // FIXME: We end up faking the "parent" declaration here because we
5605 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005606 return MakeCXCursor(getCursorLabelRef(C).first,
5607 cxtu::getASTUnit(tu)->getASTContext()
5608 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005609 tu);
5610
5611 case CXCursor_OverloadedDeclRef:
5612 return C;
5613
5614 case CXCursor_VariableRef:
5615 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5616
5617 default:
5618 // We would prefer to enumerate all non-reference cursor kinds here.
5619 llvm_unreachable("Unhandled reference cursor kind");
5620 }
5621}
5622
5623CXCursor clang_getCursorDefinition(CXCursor C) {
5624 if (clang_isInvalid(C.kind))
5625 return clang_getNullCursor();
5626
5627 CXTranslationUnit TU = getCursorTU(C);
5628
5629 bool WasReference = false;
5630 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5631 C = clang_getCursorReferenced(C);
5632 WasReference = true;
5633 }
5634
5635 if (C.kind == CXCursor_MacroExpansion)
5636 return clang_getCursorReferenced(C);
5637
5638 if (!clang_isDeclaration(C.kind))
5639 return clang_getNullCursor();
5640
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005641 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005642 if (!D)
5643 return clang_getNullCursor();
5644
5645 switch (D->getKind()) {
5646 // Declaration kinds that don't really separate the notions of
5647 // declaration and definition.
5648 case Decl::Namespace:
5649 case Decl::Typedef:
5650 case Decl::TypeAlias:
5651 case Decl::TypeAliasTemplate:
5652 case Decl::TemplateTypeParm:
5653 case Decl::EnumConstant:
5654 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005655 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005656 case Decl::IndirectField:
5657 case Decl::ObjCIvar:
5658 case Decl::ObjCAtDefsField:
5659 case Decl::ImplicitParam:
5660 case Decl::ParmVar:
5661 case Decl::NonTypeTemplateParm:
5662 case Decl::TemplateTemplateParm:
5663 case Decl::ObjCCategoryImpl:
5664 case Decl::ObjCImplementation:
5665 case Decl::AccessSpec:
5666 case Decl::LinkageSpec:
5667 case Decl::ObjCPropertyImpl:
5668 case Decl::FileScopeAsm:
5669 case Decl::StaticAssert:
5670 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005671 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005672 case Decl::Label: // FIXME: Is this right??
5673 case Decl::ClassScopeFunctionSpecialization:
5674 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005675 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005676 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005677 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005678 return C;
5679
5680 // Declaration kinds that don't make any sense here, but are
5681 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005682 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005683 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005684 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005685 break;
5686
5687 // Declaration kinds for which the definition is not resolvable.
5688 case Decl::UnresolvedUsingTypename:
5689 case Decl::UnresolvedUsingValue:
5690 break;
5691
5692 case Decl::UsingDirective:
5693 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5694 TU);
5695
5696 case Decl::NamespaceAlias:
5697 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5698
5699 case Decl::Enum:
5700 case Decl::Record:
5701 case Decl::CXXRecord:
5702 case Decl::ClassTemplateSpecialization:
5703 case Decl::ClassTemplatePartialSpecialization:
5704 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5705 return MakeCXCursor(Def, TU);
5706 return clang_getNullCursor();
5707
5708 case Decl::Function:
5709 case Decl::CXXMethod:
5710 case Decl::CXXConstructor:
5711 case Decl::CXXDestructor:
5712 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005713 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005714 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005715 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005716 return clang_getNullCursor();
5717 }
5718
Larisse Voufo39a1e502013-08-06 01:03:05 +00005719 case Decl::Var:
5720 case Decl::VarTemplateSpecialization:
5721 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005723 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 return MakeCXCursor(Def, TU);
5725 return clang_getNullCursor();
5726 }
5727
5728 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005729 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005730 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5731 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5732 return clang_getNullCursor();
5733 }
5734
5735 case Decl::ClassTemplate: {
5736 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5737 ->getDefinition())
5738 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5739 TU);
5740 return clang_getNullCursor();
5741 }
5742
Larisse Voufo39a1e502013-08-06 01:03:05 +00005743 case Decl::VarTemplate: {
5744 if (VarDecl *Def =
5745 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5746 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5747 return clang_getNullCursor();
5748 }
5749
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 case Decl::Using:
5751 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5752 D->getLocation(), TU);
5753
5754 case Decl::UsingShadow:
5755 return clang_getCursorDefinition(
5756 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5757 TU));
5758
5759 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005760 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 if (Method->isThisDeclarationADefinition())
5762 return C;
5763
5764 // Dig out the method definition in the associated
5765 // @implementation, if we have it.
5766 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005767 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005768 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5769 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5770 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5771 Method->isInstanceMethod()))
5772 if (Def->isThisDeclarationADefinition())
5773 return MakeCXCursor(Def, TU);
5774
5775 return clang_getNullCursor();
5776 }
5777
5778 case Decl::ObjCCategory:
5779 if (ObjCCategoryImplDecl *Impl
5780 = cast<ObjCCategoryDecl>(D)->getImplementation())
5781 return MakeCXCursor(Impl, TU);
5782 return clang_getNullCursor();
5783
5784 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005785 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005786 return MakeCXCursor(Def, TU);
5787 return clang_getNullCursor();
5788
5789 case Decl::ObjCInterface: {
5790 // There are two notions of a "definition" for an Objective-C
5791 // class: the interface and its implementation. When we resolved a
5792 // reference to an Objective-C class, produce the @interface as
5793 // the definition; when we were provided with the interface,
5794 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005795 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005797 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005798 return MakeCXCursor(Def, TU);
5799 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5800 return MakeCXCursor(Impl, TU);
5801 return clang_getNullCursor();
5802 }
5803
5804 case Decl::ObjCProperty:
5805 // FIXME: We don't really know where to find the
5806 // ObjCPropertyImplDecls that implement this property.
5807 return clang_getNullCursor();
5808
5809 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005810 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005811 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005812 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005813 return MakeCXCursor(Def, TU);
5814
5815 return clang_getNullCursor();
5816
5817 case Decl::Friend:
5818 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5819 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5820 return clang_getNullCursor();
5821
5822 case Decl::FriendTemplate:
5823 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5824 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5825 return clang_getNullCursor();
5826 }
5827
5828 return clang_getNullCursor();
5829}
5830
5831unsigned clang_isCursorDefinition(CXCursor C) {
5832 if (!clang_isDeclaration(C.kind))
5833 return 0;
5834
5835 return clang_getCursorDefinition(C) == C;
5836}
5837
5838CXCursor clang_getCanonicalCursor(CXCursor C) {
5839 if (!clang_isDeclaration(C.kind))
5840 return C;
5841
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005842 if (const Decl *D = getCursorDecl(C)) {
5843 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005844 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5845 return MakeCXCursor(CatD, getCursorTU(C));
5846
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005847 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5848 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005849 return MakeCXCursor(IFD, getCursorTU(C));
5850
5851 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5852 }
5853
5854 return C;
5855}
5856
5857int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5858 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5859}
5860
5861unsigned clang_getNumOverloadedDecls(CXCursor C) {
5862 if (C.kind != CXCursor_OverloadedDeclRef)
5863 return 0;
5864
5865 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005866 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005867 return E->getNumDecls();
5868
5869 if (OverloadedTemplateStorage *S
5870 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5871 return S->size();
5872
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005873 const Decl *D = Storage.get<const Decl *>();
5874 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005875 return Using->shadow_size();
5876
5877 return 0;
5878}
5879
5880CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5881 if (cursor.kind != CXCursor_OverloadedDeclRef)
5882 return clang_getNullCursor();
5883
5884 if (index >= clang_getNumOverloadedDecls(cursor))
5885 return clang_getNullCursor();
5886
5887 CXTranslationUnit TU = getCursorTU(cursor);
5888 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005889 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005890 return MakeCXCursor(E->decls_begin()[index], TU);
5891
5892 if (OverloadedTemplateStorage *S
5893 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5894 return MakeCXCursor(S->begin()[index], TU);
5895
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005896 const Decl *D = Storage.get<const Decl *>();
5897 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 // FIXME: This is, unfortunately, linear time.
5899 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5900 std::advance(Pos, index);
5901 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5902 }
5903
5904 return clang_getNullCursor();
5905}
5906
5907void clang_getDefinitionSpellingAndExtent(CXCursor C,
5908 const char **startBuf,
5909 const char **endBuf,
5910 unsigned *startLine,
5911 unsigned *startColumn,
5912 unsigned *endLine,
5913 unsigned *endColumn) {
5914 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005915 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005916 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5917
5918 SourceManager &SM = FD->getASTContext().getSourceManager();
5919 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5920 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5921 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5922 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5923 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5924 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5925}
5926
5927
5928CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5929 unsigned PieceIndex) {
5930 RefNamePieces Pieces;
5931
5932 switch (C.kind) {
5933 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005934 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005935 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5936 E->getQualifierLoc().getSourceRange());
5937 break;
5938
5939 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005940 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5941 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5942 Pieces =
5943 buildPieces(NameFlags, false, E->getNameInfo(),
5944 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5945 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005946 break;
5947
5948 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005949 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005950 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005951 const Expr *Callee = OCE->getCallee();
5952 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005953 Callee = ICE->getSubExpr();
5954
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005955 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005956 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5957 DRE->getQualifierLoc().getSourceRange());
5958 }
5959 break;
5960
5961 default:
5962 break;
5963 }
5964
5965 if (Pieces.empty()) {
5966 if (PieceIndex == 0)
5967 return clang_getCursorExtent(C);
5968 } else if (PieceIndex < Pieces.size()) {
5969 SourceRange R = Pieces[PieceIndex];
5970 if (R.isValid())
5971 return cxloc::translateSourceRange(getCursorContext(C), R);
5972 }
5973
5974 return clang_getNullRange();
5975}
5976
5977void clang_enableStackTraces(void) {
5978 llvm::sys::PrintStackTraceOnErrorSignal();
5979}
5980
5981void clang_executeOnThread(void (*fn)(void*), void *user_data,
5982 unsigned stack_size) {
5983 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5984}
5985
5986} // end: extern "C"
5987
5988//===----------------------------------------------------------------------===//
5989// Token-based Operations.
5990//===----------------------------------------------------------------------===//
5991
5992/* CXToken layout:
5993 * int_data[0]: a CXTokenKind
5994 * int_data[1]: starting token location
5995 * int_data[2]: token length
5996 * int_data[3]: reserved
5997 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5998 * otherwise unused.
5999 */
6000extern "C" {
6001
6002CXTokenKind clang_getTokenKind(CXToken CXTok) {
6003 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6004}
6005
6006CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6007 switch (clang_getTokenKind(CXTok)) {
6008 case CXToken_Identifier:
6009 case CXToken_Keyword:
6010 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00006011 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 ->getNameStart());
6013
6014 case CXToken_Literal: {
6015 // We have stashed the starting pointer in the ptr_data field. Use it.
6016 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006017 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 }
6019
6020 case CXToken_Punctuation:
6021 case CXToken_Comment:
6022 break;
6023 }
6024
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006025 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006026 LOG_BAD_TU(TU);
6027 return cxstring::createEmpty();
6028 }
6029
Guy Benyei11169dd2012-12-18 14:30:41 +00006030 // We have to find the starting buffer pointer the hard way, by
6031 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006032 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006033 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006034 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006035
6036 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
6037 std::pair<FileID, unsigned> LocInfo
6038 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
6039 bool Invalid = false;
6040 StringRef Buffer
6041 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
6042 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006043 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006044
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006045 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006046}
6047
6048CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006049 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006050 LOG_BAD_TU(TU);
6051 return clang_getNullLocation();
6052 }
6053
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006054 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006055 if (!CXXUnit)
6056 return clang_getNullLocation();
6057
6058 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
6059 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6060}
6061
6062CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006063 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006064 LOG_BAD_TU(TU);
6065 return clang_getNullRange();
6066 }
6067
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006068 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006069 if (!CXXUnit)
6070 return clang_getNullRange();
6071
6072 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
6073 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6074}
6075
6076static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6077 SmallVectorImpl<CXToken> &CXTokens) {
6078 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6079 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006080 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006081 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006082 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006083
6084 // Cannot tokenize across files.
6085 if (BeginLocInfo.first != EndLocInfo.first)
6086 return;
6087
6088 // Create a lexer
6089 bool Invalid = false;
6090 StringRef Buffer
6091 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6092 if (Invalid)
6093 return;
6094
6095 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6096 CXXUnit->getASTContext().getLangOpts(),
6097 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6098 Lex.SetCommentRetentionState(true);
6099
6100 // Lex tokens until we hit the end of the range.
6101 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6102 Token Tok;
6103 bool previousWasAt = false;
6104 do {
6105 // Lex the next token
6106 Lex.LexFromRawLexer(Tok);
6107 if (Tok.is(tok::eof))
6108 break;
6109
6110 // Initialize the CXToken.
6111 CXToken CXTok;
6112
6113 // - Common fields
6114 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6115 CXTok.int_data[2] = Tok.getLength();
6116 CXTok.int_data[3] = 0;
6117
6118 // - Kind-specific fields
6119 if (Tok.isLiteral()) {
6120 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006121 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006122 } else if (Tok.is(tok::raw_identifier)) {
6123 // Lookup the identifier to determine whether we have a keyword.
6124 IdentifierInfo *II
6125 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6126
6127 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6128 CXTok.int_data[0] = CXToken_Keyword;
6129 }
6130 else {
6131 CXTok.int_data[0] = Tok.is(tok::identifier)
6132 ? CXToken_Identifier
6133 : CXToken_Keyword;
6134 }
6135 CXTok.ptr_data = II;
6136 } else if (Tok.is(tok::comment)) {
6137 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006138 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 } else {
6140 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006141 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006142 }
6143 CXTokens.push_back(CXTok);
6144 previousWasAt = Tok.is(tok::at);
6145 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6146}
6147
6148void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6149 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006150 LOG_FUNC_SECTION {
6151 *Log << TU << ' ' << Range;
6152 }
6153
Guy Benyei11169dd2012-12-18 14:30:41 +00006154 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006155 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006156 if (NumTokens)
6157 *NumTokens = 0;
6158
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006159 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006160 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006161 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006162 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006163
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006164 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 if (!CXXUnit || !Tokens || !NumTokens)
6166 return;
6167
6168 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6169
6170 SourceRange R = cxloc::translateCXSourceRange(Range);
6171 if (R.isInvalid())
6172 return;
6173
6174 SmallVector<CXToken, 32> CXTokens;
6175 getTokens(CXXUnit, R, CXTokens);
6176
6177 if (CXTokens.empty())
6178 return;
6179
6180 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6181 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6182 *NumTokens = CXTokens.size();
6183}
6184
6185void clang_disposeTokens(CXTranslationUnit TU,
6186 CXToken *Tokens, unsigned NumTokens) {
6187 free(Tokens);
6188}
6189
6190} // end: extern "C"
6191
6192//===----------------------------------------------------------------------===//
6193// Token annotation APIs.
6194//===----------------------------------------------------------------------===//
6195
Guy Benyei11169dd2012-12-18 14:30:41 +00006196static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6197 CXCursor parent,
6198 CXClientData client_data);
6199static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6200 CXClientData client_data);
6201
6202namespace {
6203class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006204 CXToken *Tokens;
6205 CXCursor *Cursors;
6206 unsigned NumTokens;
6207 unsigned TokIdx;
6208 unsigned PreprocessingTokIdx;
6209 CursorVisitor AnnotateVis;
6210 SourceManager &SrcMgr;
6211 bool HasContextSensitiveKeywords;
6212
6213 struct PostChildrenInfo {
6214 CXCursor Cursor;
6215 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006216 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006217 unsigned BeforeChildrenTokenIdx;
6218 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006219 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006220
6221 CXToken &getTok(unsigned Idx) {
6222 assert(Idx < NumTokens);
6223 return Tokens[Idx];
6224 }
6225 const CXToken &getTok(unsigned Idx) const {
6226 assert(Idx < NumTokens);
6227 return Tokens[Idx];
6228 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006229 bool MoreTokens() const { return TokIdx < NumTokens; }
6230 unsigned NextToken() const { return TokIdx; }
6231 void AdvanceToken() { ++TokIdx; }
6232 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006233 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006234 }
6235 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006236 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006237 }
6238 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006239 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006240 }
6241
6242 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006243 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006244 SourceRange);
6245
6246public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006247 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006248 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006249 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006250 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006251 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006252 AnnotateTokensVisitor, this,
6253 /*VisitPreprocessorLast=*/true,
6254 /*VisitIncludedEntities=*/false,
6255 RegionOfInterest,
6256 /*VisitDeclsOnly=*/false,
6257 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006258 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006259 HasContextSensitiveKeywords(false) { }
6260
6261 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6262 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6263 bool postVisitChildren(CXCursor cursor);
6264 void AnnotateTokens();
6265
6266 /// \brief Determine whether the annotator saw any cursors that have
6267 /// context-sensitive keywords.
6268 bool hasContextSensitiveKeywords() const {
6269 return HasContextSensitiveKeywords;
6270 }
6271
6272 ~AnnotateTokensWorker() {
6273 assert(PostChildrenInfos.empty());
6274 }
6275};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006276}
Guy Benyei11169dd2012-12-18 14:30:41 +00006277
6278void AnnotateTokensWorker::AnnotateTokens() {
6279 // Walk the AST within the region of interest, annotating tokens
6280 // along the way.
6281 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006282}
Guy Benyei11169dd2012-12-18 14:30:41 +00006283
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006284static inline void updateCursorAnnotation(CXCursor &Cursor,
6285 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006286 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006287 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006288 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006289}
6290
6291/// \brief It annotates and advances tokens with a cursor until the comparison
6292//// between the cursor location and the source range is the same as
6293/// \arg compResult.
6294///
6295/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6296/// Pass RangeOverlap to annotate tokens inside a range.
6297void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6298 RangeComparisonResult compResult,
6299 SourceRange range) {
6300 while (MoreTokens()) {
6301 const unsigned I = NextToken();
6302 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006303 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6304 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006305
6306 SourceLocation TokLoc = GetTokenLoc(I);
6307 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006308 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006309 AdvanceToken();
6310 continue;
6311 }
6312 break;
6313 }
6314}
6315
6316/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006317/// \returns true if it advanced beyond all macro tokens, false otherwise.
6318bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006319 CXCursor updateC,
6320 RangeComparisonResult compResult,
6321 SourceRange range) {
6322 assert(MoreTokens());
6323 assert(isFunctionMacroToken(NextToken()) &&
6324 "Should be called only for macro arg tokens");
6325
6326 // This works differently than annotateAndAdvanceTokens; because expanded
6327 // macro arguments can have arbitrary translation-unit source order, we do not
6328 // advance the token index one by one until a token fails the range test.
6329 // We only advance once past all of the macro arg tokens if all of them
6330 // pass the range test. If one of them fails we keep the token index pointing
6331 // at the start of the macro arg tokens so that the failing token will be
6332 // annotated by a subsequent annotation try.
6333
6334 bool atLeastOneCompFail = false;
6335
6336 unsigned I = NextToken();
6337 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6338 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6339 if (TokLoc.isFileID())
6340 continue; // not macro arg token, it's parens or comma.
6341 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6342 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6343 Cursors[I] = updateC;
6344 } else
6345 atLeastOneCompFail = true;
6346 }
6347
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006348 if (atLeastOneCompFail)
6349 return false;
6350
6351 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6352 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006353}
6354
6355enum CXChildVisitResult
6356AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006357 SourceRange cursorRange = getRawCursorExtent(cursor);
6358 if (cursorRange.isInvalid())
6359 return CXChildVisit_Recurse;
6360
6361 if (!HasContextSensitiveKeywords) {
6362 // Objective-C properties can have context-sensitive keywords.
6363 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006364 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6366 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6367 }
6368 // Objective-C methods can have context-sensitive keywords.
6369 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6370 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006371 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006372 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6373 if (Method->getObjCDeclQualifier())
6374 HasContextSensitiveKeywords = true;
6375 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006376 for (const auto *P : Method->params()) {
6377 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006378 HasContextSensitiveKeywords = true;
6379 break;
6380 }
6381 }
6382 }
6383 }
6384 }
6385 // C++ methods can have context-sensitive keywords.
6386 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006387 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006388 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6389 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6390 HasContextSensitiveKeywords = true;
6391 }
6392 }
6393 // C++ classes can have context-sensitive keywords.
6394 else if (cursor.kind == CXCursor_StructDecl ||
6395 cursor.kind == CXCursor_ClassDecl ||
6396 cursor.kind == CXCursor_ClassTemplate ||
6397 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006398 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006399 if (D->hasAttr<FinalAttr>())
6400 HasContextSensitiveKeywords = true;
6401 }
6402 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006403
6404 // Don't override a property annotation with its getter/setter method.
6405 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6406 parent.kind == CXCursor_ObjCPropertyDecl)
6407 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006408
6409 if (clang_isPreprocessing(cursor.kind)) {
6410 // Items in the preprocessing record are kept separate from items in
6411 // declarations, so we keep a separate token index.
6412 unsigned SavedTokIdx = TokIdx;
6413 TokIdx = PreprocessingTokIdx;
6414
6415 // Skip tokens up until we catch up to the beginning of the preprocessing
6416 // entry.
6417 while (MoreTokens()) {
6418 const unsigned I = NextToken();
6419 SourceLocation TokLoc = GetTokenLoc(I);
6420 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6421 case RangeBefore:
6422 AdvanceToken();
6423 continue;
6424 case RangeAfter:
6425 case RangeOverlap:
6426 break;
6427 }
6428 break;
6429 }
6430
6431 // Look at all of the tokens within this range.
6432 while (MoreTokens()) {
6433 const unsigned I = NextToken();
6434 SourceLocation TokLoc = GetTokenLoc(I);
6435 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6436 case RangeBefore:
6437 llvm_unreachable("Infeasible");
6438 case RangeAfter:
6439 break;
6440 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006441 // For macro expansions, just note where the beginning of the macro
6442 // expansion occurs.
6443 if (cursor.kind == CXCursor_MacroExpansion) {
6444 if (TokLoc == cursorRange.getBegin())
6445 Cursors[I] = cursor;
6446 AdvanceToken();
6447 break;
6448 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006449 // We may have already annotated macro names inside macro definitions.
6450 if (Cursors[I].kind != CXCursor_MacroExpansion)
6451 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006452 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 continue;
6454 }
6455 break;
6456 }
6457
6458 // Save the preprocessing token index; restore the non-preprocessing
6459 // token index.
6460 PreprocessingTokIdx = TokIdx;
6461 TokIdx = SavedTokIdx;
6462 return CXChildVisit_Recurse;
6463 }
6464
6465 if (cursorRange.isInvalid())
6466 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006467
6468 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006469 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006470 const enum CXCursorKind K = clang_getCursorKind(parent);
6471 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006472 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6473 // Attributes are annotated out-of-order, skip tokens until we reach it.
6474 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006475 ? clang_getNullCursor() : parent;
6476
6477 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6478
6479 // Avoid having the cursor of an expression "overwrite" the annotation of the
6480 // variable declaration that it belongs to.
6481 // This can happen for C++ constructor expressions whose range generally
6482 // include the variable declaration, e.g.:
6483 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006484 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006485 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006486 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006487 const unsigned I = NextToken();
6488 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6489 E->getLocStart() == D->getLocation() &&
6490 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006491 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006492 AdvanceToken();
6493 }
6494 }
6495 }
6496
6497 // Before recursing into the children keep some state that we are going
6498 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6499 // extra work after the child nodes are visited.
6500 // Note that we don't call VisitChildren here to avoid traversing statements
6501 // code-recursively which can blow the stack.
6502
6503 PostChildrenInfo Info;
6504 Info.Cursor = cursor;
6505 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006506 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006507 Info.BeforeChildrenTokenIdx = NextToken();
6508 PostChildrenInfos.push_back(Info);
6509
6510 return CXChildVisit_Recurse;
6511}
6512
6513bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6514 if (PostChildrenInfos.empty())
6515 return false;
6516 const PostChildrenInfo &Info = PostChildrenInfos.back();
6517 if (!clang_equalCursors(Info.Cursor, cursor))
6518 return false;
6519
6520 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6521 const unsigned AfterChildren = NextToken();
6522 SourceRange cursorRange = Info.CursorRange;
6523
6524 // Scan the tokens that are at the end of the cursor, but are not captured
6525 // but the child cursors.
6526 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6527
6528 // Scan the tokens that are at the beginning of the cursor, but are not
6529 // capture by the child cursors.
6530 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6531 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6532 break;
6533
6534 Cursors[I] = cursor;
6535 }
6536
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006537 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6538 // encountered the attribute cursor.
6539 if (clang_isAttribute(cursor.kind))
6540 TokIdx = Info.BeforeReachingCursorIdx;
6541
Guy Benyei11169dd2012-12-18 14:30:41 +00006542 PostChildrenInfos.pop_back();
6543 return false;
6544}
6545
6546static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6547 CXCursor parent,
6548 CXClientData client_data) {
6549 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6550}
6551
6552static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6553 CXClientData client_data) {
6554 return static_cast<AnnotateTokensWorker*>(client_data)->
6555 postVisitChildren(cursor);
6556}
6557
6558namespace {
6559
6560/// \brief Uses the macro expansions in the preprocessing record to find
6561/// and mark tokens that are macro arguments. This info is used by the
6562/// AnnotateTokensWorker.
6563class MarkMacroArgTokensVisitor {
6564 SourceManager &SM;
6565 CXToken *Tokens;
6566 unsigned NumTokens;
6567 unsigned CurIdx;
6568
6569public:
6570 MarkMacroArgTokensVisitor(SourceManager &SM,
6571 CXToken *tokens, unsigned numTokens)
6572 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6573
6574 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6575 if (cursor.kind != CXCursor_MacroExpansion)
6576 return CXChildVisit_Continue;
6577
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006578 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006579 if (macroRange.getBegin() == macroRange.getEnd())
6580 return CXChildVisit_Continue; // it's not a function macro.
6581
6582 for (; CurIdx < NumTokens; ++CurIdx) {
6583 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6584 macroRange.getBegin()))
6585 break;
6586 }
6587
6588 if (CurIdx == NumTokens)
6589 return CXChildVisit_Break;
6590
6591 for (; CurIdx < NumTokens; ++CurIdx) {
6592 SourceLocation tokLoc = getTokenLoc(CurIdx);
6593 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6594 break;
6595
6596 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6597 }
6598
6599 if (CurIdx == NumTokens)
6600 return CXChildVisit_Break;
6601
6602 return CXChildVisit_Continue;
6603 }
6604
6605private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006606 CXToken &getTok(unsigned Idx) {
6607 assert(Idx < NumTokens);
6608 return Tokens[Idx];
6609 }
6610 const CXToken &getTok(unsigned Idx) const {
6611 assert(Idx < NumTokens);
6612 return Tokens[Idx];
6613 }
6614
Guy Benyei11169dd2012-12-18 14:30:41 +00006615 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006616 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006617 }
6618
6619 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6620 // The third field is reserved and currently not used. Use it here
6621 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006622 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006623 }
6624};
6625
6626} // end anonymous namespace
6627
6628static CXChildVisitResult
6629MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6630 CXClientData client_data) {
6631 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6632 parent);
6633}
6634
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006635/// \brief Used by \c annotatePreprocessorTokens.
6636/// \returns true if lexing was finished, false otherwise.
6637static bool lexNext(Lexer &Lex, Token &Tok,
6638 unsigned &NextIdx, unsigned NumTokens) {
6639 if (NextIdx >= NumTokens)
6640 return true;
6641
6642 ++NextIdx;
6643 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006644 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006645}
6646
Guy Benyei11169dd2012-12-18 14:30:41 +00006647static void annotatePreprocessorTokens(CXTranslationUnit TU,
6648 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006649 CXCursor *Cursors,
6650 CXToken *Tokens,
6651 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006652 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006653
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006654 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006655 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6656 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006657 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006658 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006659 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006660
6661 if (BeginLocInfo.first != EndLocInfo.first)
6662 return;
6663
6664 StringRef Buffer;
6665 bool Invalid = false;
6666 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6667 if (Buffer.empty() || Invalid)
6668 return;
6669
6670 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6671 CXXUnit->getASTContext().getLangOpts(),
6672 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6673 Buffer.end());
6674 Lex.SetCommentRetentionState(true);
6675
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006676 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006677 // Lex tokens in raw mode until we hit the end of the range, to avoid
6678 // entering #includes or expanding macros.
6679 while (true) {
6680 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006681 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6682 break;
6683 unsigned TokIdx = NextIdx-1;
6684 assert(Tok.getLocation() ==
6685 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006686
6687 reprocess:
6688 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006689 // We have found a preprocessing directive. Annotate the tokens
6690 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006691 //
6692 // FIXME: Some simple tests here could identify macro definitions and
6693 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006694
6695 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006696 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6697 break;
6698
Craig Topper69186e72014-06-08 08:38:04 +00006699 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006700 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006701 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6702 break;
6703
6704 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006705 IdentifierInfo &II =
6706 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006707 SourceLocation MappedTokLoc =
6708 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6709 MI = getMacroInfo(II, MappedTokLoc, TU);
6710 }
6711 }
6712
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006713 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006714 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006715 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6716 finished = true;
6717 break;
6718 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006719 // If we are in a macro definition, check if the token was ever a
6720 // macro name and annotate it if that's the case.
6721 if (MI) {
6722 SourceLocation SaveLoc = Tok.getLocation();
6723 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006724 MacroDefinitionRecord *MacroDef =
6725 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006726 Tok.setLocation(SaveLoc);
6727 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006728 Cursors[NextIdx - 1] =
6729 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006730 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006731 } while (!Tok.isAtStartOfLine());
6732
6733 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6734 assert(TokIdx <= LastIdx);
6735 SourceLocation EndLoc =
6736 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6737 CXCursor Cursor =
6738 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6739
6740 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006741 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006742
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006743 if (finished)
6744 break;
6745 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006746 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006747 }
6748}
6749
6750// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006751static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6752 CXToken *Tokens, unsigned NumTokens,
6753 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006754 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006755 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6756 setThreadBackgroundPriority();
6757
6758 // Determine the region of interest, which contains all of the tokens.
6759 SourceRange RegionOfInterest;
6760 RegionOfInterest.setBegin(
6761 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6762 RegionOfInterest.setEnd(
6763 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6764 Tokens[NumTokens-1])));
6765
Guy Benyei11169dd2012-12-18 14:30:41 +00006766 // Relex the tokens within the source range to look for preprocessing
6767 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006768 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006769
6770 // If begin location points inside a macro argument, set it to the expansion
6771 // location so we can have the full context when annotating semantically.
6772 {
6773 SourceManager &SM = CXXUnit->getSourceManager();
6774 SourceLocation Loc =
6775 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6776 if (Loc.isMacroID())
6777 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6778 }
6779
Guy Benyei11169dd2012-12-18 14:30:41 +00006780 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6781 // Search and mark tokens that are macro argument expansions.
6782 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6783 Tokens, NumTokens);
6784 CursorVisitor MacroArgMarker(TU,
6785 MarkMacroArgTokensVisitorDelegate, &Visitor,
6786 /*VisitPreprocessorLast=*/true,
6787 /*VisitIncludedEntities=*/false,
6788 RegionOfInterest);
6789 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6790 }
6791
6792 // Annotate all of the source locations in the region of interest that map to
6793 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006794 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006795
6796 // FIXME: We use a ridiculous stack size here because the data-recursion
6797 // algorithm uses a large stack frame than the non-data recursive version,
6798 // and AnnotationTokensWorker currently transforms the data-recursion
6799 // algorithm back into a traditional recursion by explicitly calling
6800 // VisitChildren(). We will need to remove this explicit recursive call.
6801 W.AnnotateTokens();
6802
6803 // If we ran into any entities that involve context-sensitive keywords,
6804 // take another pass through the tokens to mark them as such.
6805 if (W.hasContextSensitiveKeywords()) {
6806 for (unsigned I = 0; I != NumTokens; ++I) {
6807 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6808 continue;
6809
6810 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6811 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006812 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006813 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6814 if (Property->getPropertyAttributesAsWritten() != 0 &&
6815 llvm::StringSwitch<bool>(II->getName())
6816 .Case("readonly", true)
6817 .Case("assign", true)
6818 .Case("unsafe_unretained", true)
6819 .Case("readwrite", true)
6820 .Case("retain", true)
6821 .Case("copy", true)
6822 .Case("nonatomic", true)
6823 .Case("atomic", true)
6824 .Case("getter", true)
6825 .Case("setter", true)
6826 .Case("strong", true)
6827 .Case("weak", true)
6828 .Default(false))
6829 Tokens[I].int_data[0] = CXToken_Keyword;
6830 }
6831 continue;
6832 }
6833
6834 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6835 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6836 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6837 if (llvm::StringSwitch<bool>(II->getName())
6838 .Case("in", true)
6839 .Case("out", true)
6840 .Case("inout", true)
6841 .Case("oneway", true)
6842 .Case("bycopy", true)
6843 .Case("byref", true)
6844 .Default(false))
6845 Tokens[I].int_data[0] = CXToken_Keyword;
6846 continue;
6847 }
6848
6849 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6850 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6851 Tokens[I].int_data[0] = CXToken_Keyword;
6852 continue;
6853 }
6854 }
6855 }
6856}
6857
6858extern "C" {
6859
6860void clang_annotateTokens(CXTranslationUnit TU,
6861 CXToken *Tokens, unsigned NumTokens,
6862 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006863 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006864 LOG_BAD_TU(TU);
6865 return;
6866 }
6867 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006868 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006869 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006870 }
6871
6872 LOG_FUNC_SECTION {
6873 *Log << TU << ' ';
6874 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6875 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6876 *Log << clang_getRange(bloc, eloc);
6877 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006878
6879 // Any token we don't specifically annotate will have a NULL cursor.
6880 CXCursor C = clang_getNullCursor();
6881 for (unsigned I = 0; I != NumTokens; ++I)
6882 Cursors[I] = C;
6883
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006884 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006885 if (!CXXUnit)
6886 return;
6887
6888 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006889
6890 auto AnnotateTokensImpl = [=]() {
6891 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6892 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006893 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006894 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006895 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6896 }
6897}
6898
6899} // end: extern "C"
6900
6901//===----------------------------------------------------------------------===//
6902// Operations for querying linkage of a cursor.
6903//===----------------------------------------------------------------------===//
6904
6905extern "C" {
6906CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6907 if (!clang_isDeclaration(cursor.kind))
6908 return CXLinkage_Invalid;
6909
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006910 const Decl *D = cxcursor::getCursorDecl(cursor);
6911 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006912 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006913 case NoLinkage:
6914 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006915 case InternalLinkage: return CXLinkage_Internal;
6916 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6917 case ExternalLinkage: return CXLinkage_External;
6918 };
6919
6920 return CXLinkage_Invalid;
6921}
6922} // end: extern "C"
6923
6924//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006925// Operations for querying visibility of a cursor.
6926//===----------------------------------------------------------------------===//
6927
6928extern "C" {
6929CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6930 if (!clang_isDeclaration(cursor.kind))
6931 return CXVisibility_Invalid;
6932
6933 const Decl *D = cxcursor::getCursorDecl(cursor);
6934 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6935 switch (ND->getVisibility()) {
6936 case HiddenVisibility: return CXVisibility_Hidden;
6937 case ProtectedVisibility: return CXVisibility_Protected;
6938 case DefaultVisibility: return CXVisibility_Default;
6939 };
6940
6941 return CXVisibility_Invalid;
6942}
6943} // end: extern "C"
6944
6945//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006946// Operations for querying language of a cursor.
6947//===----------------------------------------------------------------------===//
6948
6949static CXLanguageKind getDeclLanguage(const Decl *D) {
6950 if (!D)
6951 return CXLanguage_C;
6952
6953 switch (D->getKind()) {
6954 default:
6955 break;
6956 case Decl::ImplicitParam:
6957 case Decl::ObjCAtDefsField:
6958 case Decl::ObjCCategory:
6959 case Decl::ObjCCategoryImpl:
6960 case Decl::ObjCCompatibleAlias:
6961 case Decl::ObjCImplementation:
6962 case Decl::ObjCInterface:
6963 case Decl::ObjCIvar:
6964 case Decl::ObjCMethod:
6965 case Decl::ObjCProperty:
6966 case Decl::ObjCPropertyImpl:
6967 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006968 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006969 return CXLanguage_ObjC;
6970 case Decl::CXXConstructor:
6971 case Decl::CXXConversion:
6972 case Decl::CXXDestructor:
6973 case Decl::CXXMethod:
6974 case Decl::CXXRecord:
6975 case Decl::ClassTemplate:
6976 case Decl::ClassTemplatePartialSpecialization:
6977 case Decl::ClassTemplateSpecialization:
6978 case Decl::Friend:
6979 case Decl::FriendTemplate:
6980 case Decl::FunctionTemplate:
6981 case Decl::LinkageSpec:
6982 case Decl::Namespace:
6983 case Decl::NamespaceAlias:
6984 case Decl::NonTypeTemplateParm:
6985 case Decl::StaticAssert:
6986 case Decl::TemplateTemplateParm:
6987 case Decl::TemplateTypeParm:
6988 case Decl::UnresolvedUsingTypename:
6989 case Decl::UnresolvedUsingValue:
6990 case Decl::Using:
6991 case Decl::UsingDirective:
6992 case Decl::UsingShadow:
6993 return CXLanguage_CPlusPlus;
6994 }
6995
6996 return CXLanguage_C;
6997}
6998
6999extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007000
7001static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7002 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007003 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00007004
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007005 switch (D->getAvailability()) {
7006 case AR_Available:
7007 case AR_NotYetIntroduced:
7008 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007009 return getCursorAvailabilityForDecl(
7010 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007011 return CXAvailability_Available;
7012
7013 case AR_Deprecated:
7014 return CXAvailability_Deprecated;
7015
7016 case AR_Unavailable:
7017 return CXAvailability_NotAvailable;
7018 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007019
7020 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007021}
7022
Guy Benyei11169dd2012-12-18 14:30:41 +00007023enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7024 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007025 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7026 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007027
7028 return CXAvailability_Available;
7029}
7030
7031static CXVersion convertVersion(VersionTuple In) {
7032 CXVersion Out = { -1, -1, -1 };
7033 if (In.empty())
7034 return Out;
7035
7036 Out.Major = In.getMajor();
7037
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007038 Optional<unsigned> Minor = In.getMinor();
7039 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007040 Out.Minor = *Minor;
7041 else
7042 return Out;
7043
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007044 Optional<unsigned> Subminor = In.getSubminor();
7045 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007046 Out.Subminor = *Subminor;
7047
7048 return Out;
7049}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007050
7051static int getCursorPlatformAvailabilityForDecl(const Decl *D,
7052 int *always_deprecated,
7053 CXString *deprecated_message,
7054 int *always_unavailable,
7055 CXString *unavailable_message,
7056 CXPlatformAvailability *availability,
7057 int availability_size) {
7058 bool HadAvailAttr = false;
7059 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007060 for (auto A : D->attrs()) {
7061 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007062 HadAvailAttr = true;
7063 if (always_deprecated)
7064 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007065 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007066 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007067 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007068 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007069 continue;
7070 }
7071
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007072 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007073 HadAvailAttr = true;
7074 if (always_unavailable)
7075 *always_unavailable = 1;
7076 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007077 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007078 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7079 }
7080 continue;
7081 }
7082
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007083 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007084 HadAvailAttr = true;
7085 if (N < availability_size) {
7086 availability[N].Platform
7087 = cxstring::createDup(Avail->getPlatform()->getName());
7088 availability[N].Introduced = convertVersion(Avail->getIntroduced());
7089 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7090 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7091 availability[N].Unavailable = Avail->getUnavailable();
7092 availability[N].Message = cxstring::createDup(Avail->getMessage());
7093 }
7094 ++N;
7095 }
7096 }
7097
7098 if (!HadAvailAttr)
7099 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7100 return getCursorPlatformAvailabilityForDecl(
7101 cast<Decl>(EnumConst->getDeclContext()),
7102 always_deprecated,
7103 deprecated_message,
7104 always_unavailable,
7105 unavailable_message,
7106 availability,
7107 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007108
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007109 return N;
7110}
7111
Guy Benyei11169dd2012-12-18 14:30:41 +00007112int clang_getCursorPlatformAvailability(CXCursor cursor,
7113 int *always_deprecated,
7114 CXString *deprecated_message,
7115 int *always_unavailable,
7116 CXString *unavailable_message,
7117 CXPlatformAvailability *availability,
7118 int availability_size) {
7119 if (always_deprecated)
7120 *always_deprecated = 0;
7121 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007122 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007123 if (always_unavailable)
7124 *always_unavailable = 0;
7125 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007126 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007127
Guy Benyei11169dd2012-12-18 14:30:41 +00007128 if (!clang_isDeclaration(cursor.kind))
7129 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007130
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007131 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007132 if (!D)
7133 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007134
7135 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7136 deprecated_message,
7137 always_unavailable,
7138 unavailable_message,
7139 availability,
7140 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007141}
7142
7143void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7144 clang_disposeString(availability->Platform);
7145 clang_disposeString(availability->Message);
7146}
7147
7148CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7149 if (clang_isDeclaration(cursor.kind))
7150 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7151
7152 return CXLanguage_Invalid;
7153}
7154
7155 /// \brief If the given cursor is the "templated" declaration
7156 /// descibing a class or function template, return the class or
7157 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007158static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007159 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007160 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007161
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007162 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007163 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7164 return FunTmpl;
7165
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007166 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007167 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7168 return ClassTmpl;
7169
7170 return D;
7171}
7172
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007173
7174enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7175 StorageClass sc = SC_None;
7176 const Decl *D = getCursorDecl(C);
7177 if (D) {
7178 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7179 sc = FD->getStorageClass();
7180 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7181 sc = VD->getStorageClass();
7182 } else {
7183 return CX_SC_Invalid;
7184 }
7185 } else {
7186 return CX_SC_Invalid;
7187 }
7188 switch (sc) {
7189 case SC_None:
7190 return CX_SC_None;
7191 case SC_Extern:
7192 return CX_SC_Extern;
7193 case SC_Static:
7194 return CX_SC_Static;
7195 case SC_PrivateExtern:
7196 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007197 case SC_Auto:
7198 return CX_SC_Auto;
7199 case SC_Register:
7200 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007201 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007202 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007203}
7204
Guy Benyei11169dd2012-12-18 14:30:41 +00007205CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7206 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007207 if (const Decl *D = getCursorDecl(cursor)) {
7208 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007209 if (!DC)
7210 return clang_getNullCursor();
7211
7212 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7213 getCursorTU(cursor));
7214 }
7215 }
7216
7217 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007218 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007219 return MakeCXCursor(D, getCursorTU(cursor));
7220 }
7221
7222 return clang_getNullCursor();
7223}
7224
7225CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7226 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007227 if (const Decl *D = getCursorDecl(cursor)) {
7228 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007229 if (!DC)
7230 return clang_getNullCursor();
7231
7232 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7233 getCursorTU(cursor));
7234 }
7235 }
7236
7237 // FIXME: Note that we can't easily compute the lexical context of a
7238 // statement or expression, so we return nothing.
7239 return clang_getNullCursor();
7240}
7241
7242CXFile clang_getIncludedFile(CXCursor cursor) {
7243 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007244 return nullptr;
7245
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007246 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007247 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007248}
7249
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007250unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7251 if (C.kind != CXCursor_ObjCPropertyDecl)
7252 return CXObjCPropertyAttr_noattr;
7253
7254 unsigned Result = CXObjCPropertyAttr_noattr;
7255 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7256 ObjCPropertyDecl::PropertyAttributeKind Attr =
7257 PD->getPropertyAttributesAsWritten();
7258
7259#define SET_CXOBJCPROP_ATTR(A) \
7260 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7261 Result |= CXObjCPropertyAttr_##A
7262 SET_CXOBJCPROP_ATTR(readonly);
7263 SET_CXOBJCPROP_ATTR(getter);
7264 SET_CXOBJCPROP_ATTR(assign);
7265 SET_CXOBJCPROP_ATTR(readwrite);
7266 SET_CXOBJCPROP_ATTR(retain);
7267 SET_CXOBJCPROP_ATTR(copy);
7268 SET_CXOBJCPROP_ATTR(nonatomic);
7269 SET_CXOBJCPROP_ATTR(setter);
7270 SET_CXOBJCPROP_ATTR(atomic);
7271 SET_CXOBJCPROP_ATTR(weak);
7272 SET_CXOBJCPROP_ATTR(strong);
7273 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7274#undef SET_CXOBJCPROP_ATTR
7275
7276 return Result;
7277}
7278
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007279unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7280 if (!clang_isDeclaration(C.kind))
7281 return CXObjCDeclQualifier_None;
7282
7283 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7284 const Decl *D = getCursorDecl(C);
7285 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7286 QT = MD->getObjCDeclQualifier();
7287 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7288 QT = PD->getObjCDeclQualifier();
7289 if (QT == Decl::OBJC_TQ_None)
7290 return CXObjCDeclQualifier_None;
7291
7292 unsigned Result = CXObjCDeclQualifier_None;
7293 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7294 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7295 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7296 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7297 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7298 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7299
7300 return Result;
7301}
7302
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007303unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7304 if (!clang_isDeclaration(C.kind))
7305 return 0;
7306
7307 const Decl *D = getCursorDecl(C);
7308 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7309 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7310 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7311 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7312
7313 return 0;
7314}
7315
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007316unsigned clang_Cursor_isVariadic(CXCursor C) {
7317 if (!clang_isDeclaration(C.kind))
7318 return 0;
7319
7320 const Decl *D = getCursorDecl(C);
7321 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7322 return FD->isVariadic();
7323 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7324 return MD->isVariadic();
7325
7326 return 0;
7327}
7328
Guy Benyei11169dd2012-12-18 14:30:41 +00007329CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7330 if (!clang_isDeclaration(C.kind))
7331 return clang_getNullRange();
7332
7333 const Decl *D = getCursorDecl(C);
7334 ASTContext &Context = getCursorContext(C);
7335 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7336 if (!RC)
7337 return clang_getNullRange();
7338
7339 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7340}
7341
7342CXString clang_Cursor_getRawCommentText(CXCursor C) {
7343 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007344 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007345
7346 const Decl *D = getCursorDecl(C);
7347 ASTContext &Context = getCursorContext(C);
7348 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7349 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7350 StringRef();
7351
7352 // Don't duplicate the string because RawText points directly into source
7353 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007354 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007355}
7356
7357CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7358 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007359 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007360
7361 const Decl *D = getCursorDecl(C);
7362 const ASTContext &Context = getCursorContext(C);
7363 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7364
7365 if (RC) {
7366 StringRef BriefText = RC->getBriefText(Context);
7367
7368 // Don't duplicate the string because RawComment ensures that this memory
7369 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007370 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007371 }
7372
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007373 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007374}
7375
Guy Benyei11169dd2012-12-18 14:30:41 +00007376CXModule clang_Cursor_getModule(CXCursor C) {
7377 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007378 if (const ImportDecl *ImportD =
7379 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007380 return ImportD->getImportedModule();
7381 }
7382
Craig Topper69186e72014-06-08 08:38:04 +00007383 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007384}
7385
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007386CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7387 if (isNotUsableTU(TU)) {
7388 LOG_BAD_TU(TU);
7389 return nullptr;
7390 }
7391 if (!File)
7392 return nullptr;
7393 FileEntry *FE = static_cast<FileEntry *>(File);
7394
7395 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7396 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7397 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7398
Richard Smithfeb54b62014-10-23 02:01:19 +00007399 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007400}
7401
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007402CXFile clang_Module_getASTFile(CXModule CXMod) {
7403 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007404 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007405 Module *Mod = static_cast<Module*>(CXMod);
7406 return const_cast<FileEntry *>(Mod->getASTFile());
7407}
7408
Guy Benyei11169dd2012-12-18 14:30:41 +00007409CXModule clang_Module_getParent(CXModule CXMod) {
7410 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007411 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007412 Module *Mod = static_cast<Module*>(CXMod);
7413 return Mod->Parent;
7414}
7415
7416CXString clang_Module_getName(CXModule CXMod) {
7417 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007418 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007419 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007420 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007421}
7422
7423CXString clang_Module_getFullName(CXModule CXMod) {
7424 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007425 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007426 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007427 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007428}
7429
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007430int clang_Module_isSystem(CXModule CXMod) {
7431 if (!CXMod)
7432 return 0;
7433 Module *Mod = static_cast<Module*>(CXMod);
7434 return Mod->IsSystem;
7435}
7436
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007437unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7438 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007439 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007440 LOG_BAD_TU(TU);
7441 return 0;
7442 }
7443 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007444 return 0;
7445 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007446 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7447 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7448 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007449}
7450
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007451CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7452 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007453 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007454 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007455 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007456 }
7457 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007458 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007459 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007460 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007461
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007462 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7463 if (Index < TopHeaders.size())
7464 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007465
Craig Topper69186e72014-06-08 08:38:04 +00007466 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007467}
7468
7469} // end: extern "C"
7470
7471//===----------------------------------------------------------------------===//
7472// C++ AST instrospection.
7473//===----------------------------------------------------------------------===//
7474
7475extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007476unsigned clang_CXXField_isMutable(CXCursor C) {
7477 if (!clang_isDeclaration(C.kind))
7478 return 0;
7479
7480 if (const auto D = cxcursor::getCursorDecl(C))
7481 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7482 return FD->isMutable() ? 1 : 0;
7483 return 0;
7484}
7485
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007486unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7487 if (!clang_isDeclaration(C.kind))
7488 return 0;
7489
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007490 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007491 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007492 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007493 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7494}
7495
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007496unsigned clang_CXXMethod_isConst(CXCursor C) {
7497 if (!clang_isDeclaration(C.kind))
7498 return 0;
7499
7500 const Decl *D = cxcursor::getCursorDecl(C);
7501 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007502 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007503 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7504}
7505
Guy Benyei11169dd2012-12-18 14:30:41 +00007506unsigned clang_CXXMethod_isStatic(CXCursor C) {
7507 if (!clang_isDeclaration(C.kind))
7508 return 0;
7509
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007510 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007511 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007512 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007513 return (Method && Method->isStatic()) ? 1 : 0;
7514}
7515
7516unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7517 if (!clang_isDeclaration(C.kind))
7518 return 0;
7519
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007520 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007521 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007522 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007523 return (Method && Method->isVirtual()) ? 1 : 0;
7524}
7525} // end: extern "C"
7526
7527//===----------------------------------------------------------------------===//
7528// Attribute introspection.
7529//===----------------------------------------------------------------------===//
7530
7531extern "C" {
7532CXType clang_getIBOutletCollectionType(CXCursor C) {
7533 if (C.kind != CXCursor_IBOutletCollectionAttr)
7534 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7535
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007536 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007537 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7538
7539 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7540}
7541} // end: extern "C"
7542
7543//===----------------------------------------------------------------------===//
7544// Inspecting memory usage.
7545//===----------------------------------------------------------------------===//
7546
7547typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7548
7549static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7550 enum CXTUResourceUsageKind k,
7551 unsigned long amount) {
7552 CXTUResourceUsageEntry entry = { k, amount };
7553 entries.push_back(entry);
7554}
7555
7556extern "C" {
7557
7558const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7559 const char *str = "";
7560 switch (kind) {
7561 case CXTUResourceUsage_AST:
7562 str = "ASTContext: expressions, declarations, and types";
7563 break;
7564 case CXTUResourceUsage_Identifiers:
7565 str = "ASTContext: identifiers";
7566 break;
7567 case CXTUResourceUsage_Selectors:
7568 str = "ASTContext: selectors";
7569 break;
7570 case CXTUResourceUsage_GlobalCompletionResults:
7571 str = "Code completion: cached global results";
7572 break;
7573 case CXTUResourceUsage_SourceManagerContentCache:
7574 str = "SourceManager: content cache allocator";
7575 break;
7576 case CXTUResourceUsage_AST_SideTables:
7577 str = "ASTContext: side tables";
7578 break;
7579 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7580 str = "SourceManager: malloc'ed memory buffers";
7581 break;
7582 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7583 str = "SourceManager: mmap'ed memory buffers";
7584 break;
7585 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7586 str = "ExternalASTSource: malloc'ed memory buffers";
7587 break;
7588 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7589 str = "ExternalASTSource: mmap'ed memory buffers";
7590 break;
7591 case CXTUResourceUsage_Preprocessor:
7592 str = "Preprocessor: malloc'ed memory";
7593 break;
7594 case CXTUResourceUsage_PreprocessingRecord:
7595 str = "Preprocessor: PreprocessingRecord";
7596 break;
7597 case CXTUResourceUsage_SourceManager_DataStructures:
7598 str = "SourceManager: data structures and tables";
7599 break;
7600 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7601 str = "Preprocessor: header search tables";
7602 break;
7603 }
7604 return str;
7605}
7606
7607CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007608 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007609 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007610 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007611 return usage;
7612 }
7613
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007614 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007615 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007616 ASTContext &astContext = astUnit->getASTContext();
7617
7618 // How much memory is used by AST nodes and types?
7619 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7620 (unsigned long) astContext.getASTAllocatedMemory());
7621
7622 // How much memory is used by identifiers?
7623 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7624 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7625
7626 // How much memory is used for selectors?
7627 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7628 (unsigned long) astContext.Selectors.getTotalMemory());
7629
7630 // How much memory is used by ASTContext's side tables?
7631 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7632 (unsigned long) astContext.getSideTableAllocatedMemory());
7633
7634 // How much memory is used for caching global code completion results?
7635 unsigned long completionBytes = 0;
7636 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007637 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007638 completionBytes = completionAllocator->getTotalMemory();
7639 }
7640 createCXTUResourceUsageEntry(*entries,
7641 CXTUResourceUsage_GlobalCompletionResults,
7642 completionBytes);
7643
7644 // How much memory is being used by SourceManager's content cache?
7645 createCXTUResourceUsageEntry(*entries,
7646 CXTUResourceUsage_SourceManagerContentCache,
7647 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7648
7649 // How much memory is being used by the MemoryBuffer's in SourceManager?
7650 const SourceManager::MemoryBufferSizes &srcBufs =
7651 astUnit->getSourceManager().getMemoryBufferSizes();
7652
7653 createCXTUResourceUsageEntry(*entries,
7654 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7655 (unsigned long) srcBufs.malloc_bytes);
7656 createCXTUResourceUsageEntry(*entries,
7657 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7658 (unsigned long) srcBufs.mmap_bytes);
7659 createCXTUResourceUsageEntry(*entries,
7660 CXTUResourceUsage_SourceManager_DataStructures,
7661 (unsigned long) astContext.getSourceManager()
7662 .getDataStructureSizes());
7663
7664 // How much memory is being used by the ExternalASTSource?
7665 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7666 const ExternalASTSource::MemoryBufferSizes &sizes =
7667 esrc->getMemoryBufferSizes();
7668
7669 createCXTUResourceUsageEntry(*entries,
7670 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7671 (unsigned long) sizes.malloc_bytes);
7672 createCXTUResourceUsageEntry(*entries,
7673 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7674 (unsigned long) sizes.mmap_bytes);
7675 }
7676
7677 // How much memory is being used by the Preprocessor?
7678 Preprocessor &pp = astUnit->getPreprocessor();
7679 createCXTUResourceUsageEntry(*entries,
7680 CXTUResourceUsage_Preprocessor,
7681 pp.getTotalMemory());
7682
7683 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7684 createCXTUResourceUsageEntry(*entries,
7685 CXTUResourceUsage_PreprocessingRecord,
7686 pRec->getTotalMemory());
7687 }
7688
7689 createCXTUResourceUsageEntry(*entries,
7690 CXTUResourceUsage_Preprocessor_HeaderSearch,
7691 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007692
Guy Benyei11169dd2012-12-18 14:30:41 +00007693 CXTUResourceUsage usage = { (void*) entries.get(),
7694 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007695 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007696 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007697 return usage;
7698}
7699
7700void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7701 if (usage.data)
7702 delete (MemUsageEntries*) usage.data;
7703}
7704
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007705CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7706 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007707 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007708 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007709
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007710 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007711 LOG_BAD_TU(TU);
7712 return skipped;
7713 }
7714
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007715 if (!file)
7716 return skipped;
7717
7718 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7719 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7720 if (!ppRec)
7721 return skipped;
7722
7723 ASTContext &Ctx = astUnit->getASTContext();
7724 SourceManager &sm = Ctx.getSourceManager();
7725 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7726 FileID wantedFileID = sm.translateFile(fileEntry);
7727
7728 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7729 std::vector<SourceRange> wantedRanges;
7730 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7731 i != ei; ++i) {
7732 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7733 wantedRanges.push_back(*i);
7734 }
7735
7736 skipped->count = wantedRanges.size();
7737 skipped->ranges = new CXSourceRange[skipped->count];
7738 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7739 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7740
7741 return skipped;
7742}
7743
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007744void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7745 if (ranges) {
7746 delete[] ranges->ranges;
7747 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007748 }
7749}
7750
Guy Benyei11169dd2012-12-18 14:30:41 +00007751} // end extern "C"
7752
7753void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7754 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7755 for (unsigned I = 0; I != Usage.numEntries; ++I)
7756 fprintf(stderr, " %s: %lu\n",
7757 clang_getTUResourceUsageName(Usage.entries[I].kind),
7758 Usage.entries[I].amount);
7759
7760 clang_disposeCXTUResourceUsage(Usage);
7761}
7762
7763//===----------------------------------------------------------------------===//
7764// Misc. utility functions.
7765//===----------------------------------------------------------------------===//
7766
7767/// Default to using an 8 MB stack size on "safety" threads.
7768static unsigned SafetyStackThreadSize = 8 << 20;
7769
7770namespace clang {
7771
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007772bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007773 unsigned Size) {
7774 if (!Size)
7775 Size = GetSafetyThreadStackSize();
7776 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007777 return CRC.RunSafelyOnThread(Fn, Size);
7778 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007779}
7780
7781unsigned GetSafetyThreadStackSize() {
7782 return SafetyStackThreadSize;
7783}
7784
7785void SetSafetyThreadStackSize(unsigned Value) {
7786 SafetyStackThreadSize = Value;
7787}
7788
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007789}
Guy Benyei11169dd2012-12-18 14:30:41 +00007790
7791void clang::setThreadBackgroundPriority() {
7792 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7793 return;
7794
Alp Toker1a86ad22014-07-06 06:24:00 +00007795#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007796 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7797#endif
7798}
7799
7800void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7801 if (!Unit)
7802 return;
7803
7804 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7805 DEnd = Unit->stored_diag_end();
7806 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007807 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007808 CXString Msg = clang_formatDiagnostic(&Diag,
7809 clang_defaultDiagnosticDisplayOptions());
7810 fprintf(stderr, "%s\n", clang_getCString(Msg));
7811 clang_disposeString(Msg);
7812 }
7813#ifdef LLVM_ON_WIN32
7814 // On Windows, force a flush, since there may be multiple copies of
7815 // stderr and stdout in the file system, all with different buffers
7816 // but writing to the same device.
7817 fflush(stderr);
7818#endif
7819}
7820
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007821MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7822 SourceLocation MacroDefLoc,
7823 CXTranslationUnit TU){
7824 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007825 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007826 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007827 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007828
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007829 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007830 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007831 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007832 if (MD) {
7833 for (MacroDirective::DefInfo
7834 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7835 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7836 return Def.getMacroInfo();
7837 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007838 }
7839
Craig Topper69186e72014-06-08 08:38:04 +00007840 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007841}
7842
Richard Smith66a81862015-05-04 02:25:31 +00007843const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007844 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007845 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007846 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007847 const IdentifierInfo *II = MacroDef->getName();
7848 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007849 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007850
7851 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7852}
7853
Richard Smith66a81862015-05-04 02:25:31 +00007854MacroDefinitionRecord *
7855cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7856 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007857 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007858 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007859 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007860 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007861
7862 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007863 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007864 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7865 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007866 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007867
7868 // Check that the token is inside the definition and not its argument list.
7869 SourceManager &SM = Unit->getSourceManager();
7870 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007871 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007872 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007873 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007874
7875 Preprocessor &PP = Unit->getPreprocessor();
7876 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7877 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007878 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007879
Alp Toker2d57cea2014-05-17 04:53:25 +00007880 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007881 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007882 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007883
7884 // Check that the identifier is not one of the macro arguments.
7885 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007886 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007887
Richard Smith20e883e2015-04-29 23:20:19 +00007888 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007889 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007890 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007891
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007892 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007893}
7894
Richard Smith66a81862015-05-04 02:25:31 +00007895MacroDefinitionRecord *
7896cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7897 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007898 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007899 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007900
7901 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007902 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007903 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007904 Preprocessor &PP = Unit->getPreprocessor();
7905 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007906 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007907 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7908 Token Tok;
7909 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007910 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007911
7912 return checkForMacroInMacroDefinition(MI, Tok, TU);
7913}
7914
Guy Benyei11169dd2012-12-18 14:30:41 +00007915extern "C" {
7916
7917CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007918 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007919}
7920
7921} // end: extern "C"
7922
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007923Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7924 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007925 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007926 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007927 if (Unit->isMainFileAST())
7928 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007929 return *this;
7930 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007931 } else {
7932 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007933 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007934 return *this;
7935}
7936
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007937Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7938 *this << FE->getName();
7939 return *this;
7940}
7941
7942Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7943 CXString cursorName = clang_getCursorDisplayName(cursor);
7944 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7945 clang_disposeString(cursorName);
7946 return *this;
7947}
7948
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007949Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7950 CXFile File;
7951 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007952 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007953 CXString FileName = clang_getFileName(File);
7954 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7955 clang_disposeString(FileName);
7956 return *this;
7957}
7958
7959Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7960 CXSourceLocation BLoc = clang_getRangeStart(range);
7961 CXSourceLocation ELoc = clang_getRangeEnd(range);
7962
7963 CXFile BFile;
7964 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007965 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007966
7967 CXFile EFile;
7968 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007969 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007970
7971 CXString BFileName = clang_getFileName(BFile);
7972 if (BFile == EFile) {
7973 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7974 BLine, BColumn, ELine, EColumn);
7975 } else {
7976 CXString EFileName = clang_getFileName(EFile);
7977 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7978 BLine, BColumn)
7979 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7980 ELine, EColumn);
7981 clang_disposeString(EFileName);
7982 }
7983 clang_disposeString(BFileName);
7984 return *this;
7985}
7986
7987Logger &cxindex::Logger::operator<<(CXString Str) {
7988 *this << clang_getCString(Str);
7989 return *this;
7990}
7991
7992Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7993 LogOS << Fmt;
7994 return *this;
7995}
7996
Chandler Carruth37ad2582014-06-27 15:14:39 +00007997static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7998
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007999cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00008000 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008001
8002 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
8003
Dmitri Gribenkof8579502013-01-12 19:30:44 +00008004 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008005 OS << "[libclang:" << Name << ':';
8006
Alp Toker1a86ad22014-07-06 06:24:00 +00008007#ifdef USE_DARWIN_THREADS
8008 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008009 mach_port_t tid = pthread_mach_thread_np(pthread_self());
8010 OS << tid << ':';
8011#endif
8012
8013 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
8014 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00008015 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008016
8017 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00008018 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008019 OS << "--------------------------------------------------\n";
8020 }
8021}