blob: 6f2800514a7a960a9ede608ba39ad97d672a81bb [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
Aaron Ballman774e8fe2016-02-08 15:52:13 +00003999static std::string getMangledName(std::unique_ptr<MangleContext> &M,
4000 std::unique_ptr<llvm::DataLayout> &DL,
4001 const NamedDecl *ND) {
4002 std::string FrontendBuf;
4003 llvm::raw_string_ostream FOS(FrontendBuf);
4004
4005 M->mangleName(ND, FOS);
4006
4007 std::string BackendBuf;
4008 llvm::raw_string_ostream BOS(BackendBuf);
4009
4010 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
4011
4012 return BOS.str();
4013}
4014
4015static std::string getMangledThunk(std::unique_ptr<MangleContext> &M,
4016 std::unique_ptr<llvm::DataLayout> &DL,
4017 const CXXMethodDecl *MD,
4018 const ThunkInfo &T) {
4019 std::string FrontendBuf;
4020 llvm::raw_string_ostream FOS(FrontendBuf);
4021
4022 M->mangleThunk(MD, T, FOS);
4023
4024 std::string BackendBuf;
4025 llvm::raw_string_ostream BOS(BackendBuf);
4026
4027 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
4028
4029 return BOS.str();
4030}
4031
Guy Benyei11169dd2012-12-18 14:30:41 +00004032extern "C" {
4033
4034unsigned clang_visitChildren(CXCursor parent,
4035 CXCursorVisitor visitor,
4036 CXClientData client_data) {
4037 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4038 /*VisitPreprocessorLast=*/false);
4039 return CursorVis.VisitChildren(parent);
4040}
4041
4042#ifndef __has_feature
4043#define __has_feature(x) 0
4044#endif
4045#if __has_feature(blocks)
4046typedef enum CXChildVisitResult
4047 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
4048
4049static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4050 CXClientData client_data) {
4051 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4052 return block(cursor, parent);
4053}
4054#else
4055// If we are compiled with a compiler that doesn't have native blocks support,
4056// define and call the block manually, so the
4057typedef struct _CXChildVisitResult
4058{
4059 void *isa;
4060 int flags;
4061 int reserved;
4062 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4063 CXCursor);
4064} *CXCursorVisitorBlock;
4065
4066static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4067 CXClientData client_data) {
4068 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4069 return block->invoke(block, cursor, parent);
4070}
4071#endif
4072
4073
4074unsigned clang_visitChildrenWithBlock(CXCursor parent,
4075 CXCursorVisitorBlock block) {
4076 return clang_visitChildren(parent, visitWithBlock, block);
4077}
4078
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004079static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004081 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004082
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004083 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004085 if (const ObjCPropertyImplDecl *PropImpl =
4086 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004088 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004089
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004090 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004092 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004093
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004094 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 }
4096
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004097 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004098 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004099
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004100 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4102 // and returns different names. NamedDecl returns the class name and
4103 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004105
4106 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004107 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004108
4109 SmallString<1024> S;
4110 llvm::raw_svector_ostream os(S);
4111 ND->printName(os);
4112
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004113 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004114}
4115
4116CXString clang_getCursorSpelling(CXCursor C) {
4117 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004118 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004119
4120 if (clang_isReference(C.kind)) {
4121 switch (C.kind) {
4122 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004123 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 }
4126 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004127 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 }
4130 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004131 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004133 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 }
4135 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004136 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004137 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004138 }
4139 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004140 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 assert(Type && "Missing type decl");
4142
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004143 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004144 getAsString());
4145 }
4146 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004147 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 assert(Template && "Missing template decl");
4149
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004150 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 }
4152
4153 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004154 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 assert(NS && "Missing namespace decl");
4156
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004157 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004158 }
4159
4160 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004161 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 assert(Field && "Missing member decl");
4163
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004164 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 }
4166
4167 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004168 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 assert(Label && "Missing label");
4170
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004171 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 }
4173
4174 case CXCursor_OverloadedDeclRef: {
4175 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004176 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4177 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004178 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004179 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004181 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004182 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 OverloadedTemplateStorage *Ovl
4184 = Storage.get<OverloadedTemplateStorage*>();
4185 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004186 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004187 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 }
4189
4190 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004191 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 assert(Var && "Missing variable decl");
4193
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004194 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 }
4196
4197 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 }
4200 }
4201
4202 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004203 const Expr *E = getCursorExpr(C);
4204
4205 if (C.kind == CXCursor_ObjCStringLiteral ||
4206 C.kind == CXCursor_StringLiteral) {
4207 const StringLiteral *SLit;
4208 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4209 SLit = OSL->getString();
4210 } else {
4211 SLit = cast<StringLiteral>(E);
4212 }
4213 SmallString<256> Buf;
4214 llvm::raw_svector_ostream OS(Buf);
4215 SLit->outputString(OS);
4216 return cxstring::createDup(OS.str());
4217 }
4218
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004219 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 if (D)
4221 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004222 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 }
4224
4225 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004226 const Stmt *S = getCursorStmt(C);
4227 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004229
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004230 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 }
4232
4233 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004234 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 ->getNameStart());
4236
4237 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004238 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 ->getNameStart());
4240
4241 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004242 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004243
4244 if (clang_isDeclaration(C.kind))
4245 return getDeclSpelling(getCursorDecl(C));
4246
4247 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004248 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004249 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 }
4251
4252 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004253 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004254 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004255 }
4256
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004257 if (C.kind == CXCursor_PackedAttr) {
4258 return cxstring::createRef("packed");
4259 }
4260
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004261 if (C.kind == CXCursor_VisibilityAttr) {
4262 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4263 switch (AA->getVisibility()) {
4264 case VisibilityAttr::VisibilityType::Default:
4265 return cxstring::createRef("default");
4266 case VisibilityAttr::VisibilityType::Hidden:
4267 return cxstring::createRef("hidden");
4268 case VisibilityAttr::VisibilityType::Protected:
4269 return cxstring::createRef("protected");
4270 }
4271 llvm_unreachable("unknown visibility type");
4272 }
4273
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004274 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004275}
4276
4277CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4278 unsigned pieceIndex,
4279 unsigned options) {
4280 if (clang_Cursor_isNull(C))
4281 return clang_getNullRange();
4282
4283 ASTContext &Ctx = getCursorContext(C);
4284
4285 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004286 const Stmt *S = getCursorStmt(C);
4287 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 if (pieceIndex > 0)
4289 return clang_getNullRange();
4290 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4291 }
4292
4293 return clang_getNullRange();
4294 }
4295
4296 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004297 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4299 if (pieceIndex >= ME->getNumSelectorLocs())
4300 return clang_getNullRange();
4301 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4302 }
4303 }
4304
4305 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4306 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004307 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4309 if (pieceIndex >= MD->getNumSelectorLocs())
4310 return clang_getNullRange();
4311 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4312 }
4313 }
4314
4315 if (C.kind == CXCursor_ObjCCategoryDecl ||
4316 C.kind == CXCursor_ObjCCategoryImplDecl) {
4317 if (pieceIndex > 0)
4318 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004319 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004320 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4321 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004322 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004323 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4324 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4325 }
4326
4327 if (C.kind == CXCursor_ModuleImportDecl) {
4328 if (pieceIndex > 0)
4329 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004330 if (const ImportDecl *ImportD =
4331 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4333 if (!Locs.empty())
4334 return cxloc::translateSourceRange(Ctx,
4335 SourceRange(Locs.front(), Locs.back()));
4336 }
4337 return clang_getNullRange();
4338 }
4339
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004340 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4341 C.kind == CXCursor_ConversionFunction) {
4342 if (pieceIndex > 0)
4343 return clang_getNullRange();
4344 if (const FunctionDecl *FD =
4345 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4346 DeclarationNameInfo FunctionName = FD->getNameInfo();
4347 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4348 }
4349 return clang_getNullRange();
4350 }
4351
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 // FIXME: A CXCursor_InclusionDirective should give the location of the
4353 // filename, but we don't keep track of this.
4354
4355 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4356 // but we don't keep track of this.
4357
4358 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4359 // but we don't keep track of this.
4360
4361 // Default handling, give the location of the cursor.
4362
4363 if (pieceIndex > 0)
4364 return clang_getNullRange();
4365
4366 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4367 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4368 return cxloc::translateSourceRange(Ctx, Loc);
4369}
4370
Eli Bendersky44a206f2014-07-31 18:04:56 +00004371CXString clang_Cursor_getMangling(CXCursor C) {
4372 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4373 return cxstring::createEmpty();
4374
Eli Bendersky44a206f2014-07-31 18:04:56 +00004375 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004376 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004377 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4378 return cxstring::createEmpty();
4379
Eli Bendersky79759592014-08-01 15:01:10 +00004380 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00004381 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00004382 ASTContext &Ctx = ND->getASTContext();
4383 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004384
Eli Bendersky79759592014-08-01 15:01:10 +00004385 std::string FrontendBuf;
4386 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00004387 if (MC->shouldMangleDeclName(ND)) {
4388 MC->mangleName(ND, FrontendBufOS);
4389 } else {
4390 ND->printName(FrontendBufOS);
4391 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00004392
Eli Bendersky79759592014-08-01 15:01:10 +00004393 // Now apply backend mangling.
4394 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00004395 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00004396
4397 std::string FinalBuf;
4398 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00004399 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
4400 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00004401
4402 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004403}
4404
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004405CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4406 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4407 return nullptr;
4408
4409 const Decl *D = getCursorDecl(C);
4410 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4411 return nullptr;
4412
4413 const NamedDecl *ND = cast<NamedDecl>(D);
4414
4415 ASTContext &Ctx = ND->getASTContext();
4416 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
4417 std::unique_ptr<llvm::DataLayout> DL(
4418 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
4419
4420 std::vector<std::string> Manglings;
4421
4422 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4423 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4424 /*IsCSSMethod=*/true);
4425 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4426 return CC == DefaultCC;
4427 };
4428
4429 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4430 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4431
4432 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4433 if (!CD->getParent()->isAbstract())
4434 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4435
4436 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4437 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4438 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4439 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4440 Ctor_DefaultClosure));
4441 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4442 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4443 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4444 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
Saleem Abdulrasoold5af8ae2015-12-10 06:30:23 +00004445 if (DD->isVirtual())
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004446 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4447 }
Saleem Abdulrasool5e03c652016-02-06 22:36:34 +00004448 } else if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) {
4449 Manglings.emplace_back(getMangledName(M, DL, ND));
4450 if (MD->isVirtual())
4451 if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD))
4452 for (const auto &T : *TIV)
4453 Manglings.emplace_back(getMangledThunk(M, DL, MD, T));
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004454 }
4455
4456 return cxstring::createSet(Manglings);
4457}
4458
Guy Benyei11169dd2012-12-18 14:30:41 +00004459CXString clang_getCursorDisplayName(CXCursor C) {
4460 if (!clang_isDeclaration(C.kind))
4461 return clang_getCursorSpelling(C);
4462
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004463 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004465 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004466
4467 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004468 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004469 D = FunTmpl->getTemplatedDecl();
4470
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004471 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 SmallString<64> Str;
4473 llvm::raw_svector_ostream OS(Str);
4474 OS << *Function;
4475 if (Function->getPrimaryTemplate())
4476 OS << "<>";
4477 OS << "(";
4478 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4479 if (I)
4480 OS << ", ";
4481 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4482 }
4483
4484 if (Function->isVariadic()) {
4485 if (Function->getNumParams())
4486 OS << ", ";
4487 OS << "...";
4488 }
4489 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004490 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 }
4492
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004493 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 SmallString<64> Str;
4495 llvm::raw_svector_ostream OS(Str);
4496 OS << *ClassTemplate;
4497 OS << "<";
4498 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4499 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4500 if (I)
4501 OS << ", ";
4502
4503 NamedDecl *Param = Params->getParam(I);
4504 if (Param->getIdentifier()) {
4505 OS << Param->getIdentifier()->getName();
4506 continue;
4507 }
4508
4509 // There is no parameter name, which makes this tricky. Try to come up
4510 // with something useful that isn't too long.
4511 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4512 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4513 else if (NonTypeTemplateParmDecl *NTTP
4514 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4515 OS << NTTP->getType().getAsString(Policy);
4516 else
4517 OS << "template<...> class";
4518 }
4519
4520 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004521 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 }
4523
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004524 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4526 // If the type was explicitly written, use that.
4527 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004528 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004529
Benjamin Kramer9170e912013-02-22 15:46:01 +00004530 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 llvm::raw_svector_ostream OS(Str);
4532 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004533 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 ClassSpec->getTemplateArgs().data(),
4535 ClassSpec->getTemplateArgs().size(),
4536 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004537 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 }
4539
4540 return clang_getCursorSpelling(C);
4541}
4542
4543CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4544 switch (Kind) {
4545 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004550 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004552 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004554 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004556 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004558 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004560 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004562 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004564 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004566 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004570 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004572 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004574 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004576 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004578 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004580 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004582 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004584 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004588 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004596 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004600 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004602 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004606 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004608 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004610 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004612 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004614 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004616 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004618 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004620 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004622 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004623 case CXCursor_OMPArraySectionExpr:
4624 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004626 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004628 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004632 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004634 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004636 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004638 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004640 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004642 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004644 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004646 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004648 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004650 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004652 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004654 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004656 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004658 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004660 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004662 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004666 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004668 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004670 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004672 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004674 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004675 case CXCursor_ObjCSelfExpr:
4676 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004678 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004680 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004682 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004684 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004686 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004688 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004690 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004692 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004694 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004696 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004698 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004700 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004702 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004704 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004706 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004707 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004708 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004710 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004712 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004714 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004716 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004718 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004720 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004722 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004724 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004726 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004728 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004730 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004732 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004734 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004736 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004738 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004740 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004742 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004744 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004746 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004748 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004750 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004752 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004754 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004756 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004758 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004759 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004760 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004762 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004764 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004765 case CXCursor_SEHLeaveStmt:
4766 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004768 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004770 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004772 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004774 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004776 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004778 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004780 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004782 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004784 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004786 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004788 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004790 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004792 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004794 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004795 case CXCursor_PackedAttr:
4796 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004797 case CXCursor_PureAttr:
4798 return cxstring::createRef("attribute(pure)");
4799 case CXCursor_ConstAttr:
4800 return cxstring::createRef("attribute(const)");
4801 case CXCursor_NoDuplicateAttr:
4802 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004803 case CXCursor_CUDAConstantAttr:
4804 return cxstring::createRef("attribute(constant)");
4805 case CXCursor_CUDADeviceAttr:
4806 return cxstring::createRef("attribute(device)");
4807 case CXCursor_CUDAGlobalAttr:
4808 return cxstring::createRef("attribute(global)");
4809 case CXCursor_CUDAHostAttr:
4810 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004811 case CXCursor_CUDASharedAttr:
4812 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004813 case CXCursor_VisibilityAttr:
4814 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004815 case CXCursor_DLLExport:
4816 return cxstring::createRef("attribute(dllexport)");
4817 case CXCursor_DLLImport:
4818 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004820 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004821 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004822 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004824 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004825 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004826 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004827 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004828 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004829 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004830 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004831 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004832 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004833 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004834 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004836 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004838 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004839 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004840 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004841 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004842 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004843 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004844 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004846 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004847 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004848 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004849 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004850 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004852 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004854 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004855 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004856 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004858 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004860 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004862 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004863 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004864 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004866 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004867 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004868 return cxstring::createRef("OMPParallelDirective");
4869 case CXCursor_OMPSimdDirective:
4870 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004871 case CXCursor_OMPForDirective:
4872 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004873 case CXCursor_OMPForSimdDirective:
4874 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004875 case CXCursor_OMPSectionsDirective:
4876 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004877 case CXCursor_OMPSectionDirective:
4878 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004879 case CXCursor_OMPSingleDirective:
4880 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004881 case CXCursor_OMPMasterDirective:
4882 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004883 case CXCursor_OMPCriticalDirective:
4884 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004885 case CXCursor_OMPParallelForDirective:
4886 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004887 case CXCursor_OMPParallelForSimdDirective:
4888 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004889 case CXCursor_OMPParallelSectionsDirective:
4890 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004891 case CXCursor_OMPTaskDirective:
4892 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004893 case CXCursor_OMPTaskyieldDirective:
4894 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004895 case CXCursor_OMPBarrierDirective:
4896 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004897 case CXCursor_OMPTaskwaitDirective:
4898 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004899 case CXCursor_OMPTaskgroupDirective:
4900 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004901 case CXCursor_OMPFlushDirective:
4902 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004903 case CXCursor_OMPOrderedDirective:
4904 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004905 case CXCursor_OMPAtomicDirective:
4906 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004907 case CXCursor_OMPTargetDirective:
4908 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004909 case CXCursor_OMPTargetDataDirective:
4910 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004911 case CXCursor_OMPTargetEnterDataDirective:
4912 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004913 case CXCursor_OMPTargetExitDataDirective:
4914 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00004915 case CXCursor_OMPTargetParallelDirective:
4916 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00004917 case CXCursor_OMPTargetParallelForDirective:
4918 return cxstring::createRef("OMPTargetParallelForDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004919 case CXCursor_OMPTeamsDirective:
4920 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004921 case CXCursor_OMPCancellationPointDirective:
4922 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004923 case CXCursor_OMPCancelDirective:
4924 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004925 case CXCursor_OMPTaskLoopDirective:
4926 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004927 case CXCursor_OMPTaskLoopSimdDirective:
4928 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004929 case CXCursor_OMPDistributeDirective:
4930 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004931 case CXCursor_OverloadCandidate:
4932 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004933 case CXCursor_TypeAliasTemplateDecl:
4934 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 }
4936
4937 llvm_unreachable("Unhandled CXCursorKind");
4938}
4939
4940struct GetCursorData {
4941 SourceLocation TokenBeginLoc;
4942 bool PointsAtMacroArgExpansion;
4943 bool VisitedObjCPropertyImplDecl;
4944 SourceLocation VisitedDeclaratorDeclStartLoc;
4945 CXCursor &BestCursor;
4946
4947 GetCursorData(SourceManager &SM,
4948 SourceLocation tokenBegin, CXCursor &outputCursor)
4949 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4950 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4951 VisitedObjCPropertyImplDecl = false;
4952 }
4953};
4954
4955static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4956 CXCursor parent,
4957 CXClientData client_data) {
4958 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4959 CXCursor *BestCursor = &Data->BestCursor;
4960
4961 // If we point inside a macro argument we should provide info of what the
4962 // token is so use the actual cursor, don't replace it with a macro expansion
4963 // cursor.
4964 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4965 return CXChildVisit_Recurse;
4966
4967 if (clang_isDeclaration(cursor.kind)) {
4968 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004969 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004970 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4971 if (MD->isImplicit())
4972 return CXChildVisit_Break;
4973
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004974 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004975 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4976 // Check that when we have multiple @class references in the same line,
4977 // that later ones do not override the previous ones.
4978 // If we have:
4979 // @class Foo, Bar;
4980 // source ranges for both start at '@', so 'Bar' will end up overriding
4981 // 'Foo' even though the cursor location was at 'Foo'.
4982 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4983 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004984 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4986 if (PrevID != ID &&
4987 !PrevID->isThisDeclarationADefinition() &&
4988 !ID->isThisDeclarationADefinition())
4989 return CXChildVisit_Break;
4990 }
4991
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004992 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4994 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4995 // Check that when we have multiple declarators in the same line,
4996 // that later ones do not override the previous ones.
4997 // If we have:
4998 // int Foo, Bar;
4999 // source ranges for both start at 'int', so 'Bar' will end up overriding
5000 // 'Foo' even though the cursor location was at 'Foo'.
5001 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5002 return CXChildVisit_Break;
5003 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5004
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005005 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
5007 (void)PropImp;
5008 // Check that when we have multiple @synthesize in the same line,
5009 // that later ones do not override the previous ones.
5010 // If we have:
5011 // @synthesize Foo, Bar;
5012 // source ranges for both start at '@', so 'Bar' will end up overriding
5013 // 'Foo' even though the cursor location was at 'Foo'.
5014 if (Data->VisitedObjCPropertyImplDecl)
5015 return CXChildVisit_Break;
5016 Data->VisitedObjCPropertyImplDecl = true;
5017 }
5018 }
5019
5020 if (clang_isExpression(cursor.kind) &&
5021 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005022 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005023 // Avoid having the cursor of an expression replace the declaration cursor
5024 // when the expression source range overlaps the declaration range.
5025 // This can happen for C++ constructor expressions whose range generally
5026 // include the variable declaration, e.g.:
5027 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
5028 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5029 D->getLocation() == Data->TokenBeginLoc)
5030 return CXChildVisit_Break;
5031 }
5032 }
5033
5034 // If our current best cursor is the construction of a temporary object,
5035 // don't replace that cursor with a type reference, because we want
5036 // clang_getCursor() to point at the constructor.
5037 if (clang_isExpression(BestCursor->kind) &&
5038 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5039 cursor.kind == CXCursor_TypeRef) {
5040 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5041 // as having the actual point on the type reference.
5042 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5043 return CXChildVisit_Recurse;
5044 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005045
5046 // If we already have an Objective-C superclass reference, don't
5047 // update it further.
5048 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5049 return CXChildVisit_Break;
5050
Guy Benyei11169dd2012-12-18 14:30:41 +00005051 *BestCursor = cursor;
5052 return CXChildVisit_Recurse;
5053}
5054
5055CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005056 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005057 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005058 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005059 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005060
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005061 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005062 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5063
5064 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5065 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5066
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005067 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005068 CXFile SearchFile;
5069 unsigned SearchLine, SearchColumn;
5070 CXFile ResultFile;
5071 unsigned ResultLine, ResultColumn;
5072 CXString SearchFileName, ResultFileName, KindSpelling, USR;
5073 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
5074 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005075
5076 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5077 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005078 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00005079 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005080 SearchFileName = clang_getFileName(SearchFile);
5081 ResultFileName = clang_getFileName(ResultFile);
5082 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5083 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005084 *Log << llvm::format("(%s:%d:%d) = %s",
5085 clang_getCString(SearchFileName), SearchLine, SearchColumn,
5086 clang_getCString(KindSpelling))
5087 << llvm::format("(%s:%d:%d):%s%s",
5088 clang_getCString(ResultFileName), ResultLine, ResultColumn,
5089 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005090 clang_disposeString(SearchFileName);
5091 clang_disposeString(ResultFileName);
5092 clang_disposeString(KindSpelling);
5093 clang_disposeString(USR);
5094
5095 CXCursor Definition = clang_getCursorDefinition(Result);
5096 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5097 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5098 CXString DefinitionKindSpelling
5099 = clang_getCursorKindSpelling(Definition.kind);
5100 CXFile DefinitionFile;
5101 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005102 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005103 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005104 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005105 *Log << llvm::format(" -> %s(%s:%d:%d)",
5106 clang_getCString(DefinitionKindSpelling),
5107 clang_getCString(DefinitionFileName),
5108 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 clang_disposeString(DefinitionFileName);
5110 clang_disposeString(DefinitionKindSpelling);
5111 }
5112 }
5113
5114 return Result;
5115}
5116
5117CXCursor clang_getNullCursor(void) {
5118 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5119}
5120
5121unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005122 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5123 // can't set consistently. For example, when visiting a DeclStmt we will set
5124 // it but we don't set it on the result of clang_getCursorDefinition for
5125 // a reference of the same declaration.
5126 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5127 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5128 // to provide that kind of info.
5129 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005130 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005131 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005132 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005133
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 return X == Y;
5135}
5136
5137unsigned clang_hashCursor(CXCursor C) {
5138 unsigned Index = 0;
5139 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5140 Index = 1;
5141
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005142 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 std::make_pair(C.kind, C.data[Index]));
5144}
5145
5146unsigned clang_isInvalid(enum CXCursorKind K) {
5147 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5148}
5149
5150unsigned clang_isDeclaration(enum CXCursorKind K) {
5151 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5152 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5153}
5154
5155unsigned clang_isReference(enum CXCursorKind K) {
5156 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5157}
5158
5159unsigned clang_isExpression(enum CXCursorKind K) {
5160 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5161}
5162
5163unsigned clang_isStatement(enum CXCursorKind K) {
5164 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5165}
5166
5167unsigned clang_isAttribute(enum CXCursorKind K) {
5168 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5169}
5170
5171unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5172 return K == CXCursor_TranslationUnit;
5173}
5174
5175unsigned clang_isPreprocessing(enum CXCursorKind K) {
5176 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5177}
5178
5179unsigned clang_isUnexposed(enum CXCursorKind K) {
5180 switch (K) {
5181 case CXCursor_UnexposedDecl:
5182 case CXCursor_UnexposedExpr:
5183 case CXCursor_UnexposedStmt:
5184 case CXCursor_UnexposedAttr:
5185 return true;
5186 default:
5187 return false;
5188 }
5189}
5190
5191CXCursorKind clang_getCursorKind(CXCursor C) {
5192 return C.kind;
5193}
5194
5195CXSourceLocation clang_getCursorLocation(CXCursor C) {
5196 if (clang_isReference(C.kind)) {
5197 switch (C.kind) {
5198 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005199 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 = getCursorObjCSuperClassRef(C);
5201 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5202 }
5203
5204 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005205 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 = getCursorObjCProtocolRef(C);
5207 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5208 }
5209
5210 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005211 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 = getCursorObjCClassRef(C);
5213 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5214 }
5215
5216 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005217 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5219 }
5220
5221 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005222 std::pair<const TemplateDecl *, SourceLocation> P =
5223 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5225 }
5226
5227 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005228 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005229 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5230 }
5231
5232 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005233 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5235 }
5236
5237 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005238 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005239 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5240 }
5241
5242 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005243 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 if (!BaseSpec)
5245 return clang_getNullLocation();
5246
5247 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5248 return cxloc::translateSourceLocation(getCursorContext(C),
5249 TSInfo->getTypeLoc().getBeginLoc());
5250
5251 return cxloc::translateSourceLocation(getCursorContext(C),
5252 BaseSpec->getLocStart());
5253 }
5254
5255 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005256 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005257 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5258 }
5259
5260 case CXCursor_OverloadedDeclRef:
5261 return cxloc::translateSourceLocation(getCursorContext(C),
5262 getCursorOverloadedDeclRef(C).second);
5263
5264 default:
5265 // FIXME: Need a way to enumerate all non-reference cases.
5266 llvm_unreachable("Missed a reference kind");
5267 }
5268 }
5269
5270 if (clang_isExpression(C.kind))
5271 return cxloc::translateSourceLocation(getCursorContext(C),
5272 getLocationFromExpr(getCursorExpr(C)));
5273
5274 if (clang_isStatement(C.kind))
5275 return cxloc::translateSourceLocation(getCursorContext(C),
5276 getCursorStmt(C)->getLocStart());
5277
5278 if (C.kind == CXCursor_PreprocessingDirective) {
5279 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5280 return cxloc::translateSourceLocation(getCursorContext(C), L);
5281 }
5282
5283 if (C.kind == CXCursor_MacroExpansion) {
5284 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005285 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 return cxloc::translateSourceLocation(getCursorContext(C), L);
5287 }
5288
5289 if (C.kind == CXCursor_MacroDefinition) {
5290 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5291 return cxloc::translateSourceLocation(getCursorContext(C), L);
5292 }
5293
5294 if (C.kind == CXCursor_InclusionDirective) {
5295 SourceLocation L
5296 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5297 return cxloc::translateSourceLocation(getCursorContext(C), L);
5298 }
5299
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005300 if (clang_isAttribute(C.kind)) {
5301 SourceLocation L
5302 = cxcursor::getCursorAttr(C)->getLocation();
5303 return cxloc::translateSourceLocation(getCursorContext(C), L);
5304 }
5305
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 if (!clang_isDeclaration(C.kind))
5307 return clang_getNullLocation();
5308
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005309 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 if (!D)
5311 return clang_getNullLocation();
5312
5313 SourceLocation Loc = D->getLocation();
5314 // FIXME: Multiple variables declared in a single declaration
5315 // currently lack the information needed to correctly determine their
5316 // ranges when accounting for the type-specifier. We use context
5317 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5318 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005319 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 if (!cxcursor::isFirstInDeclGroup(C))
5321 Loc = VD->getLocation();
5322 }
5323
5324 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005325 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 Loc = MD->getSelectorStartLoc();
5327
5328 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5329}
5330
5331} // end extern "C"
5332
5333CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5334 assert(TU);
5335
5336 // Guard against an invalid SourceLocation, or we may assert in one
5337 // of the following calls.
5338 if (SLoc.isInvalid())
5339 return clang_getNullCursor();
5340
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005341 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005342
5343 // Translate the given source location to make it point at the beginning of
5344 // the token under the cursor.
5345 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5346 CXXUnit->getASTContext().getLangOpts());
5347
5348 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5349 if (SLoc.isValid()) {
5350 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5351 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5352 /*VisitPreprocessorLast=*/true,
5353 /*VisitIncludedEntities=*/false,
5354 SourceLocation(SLoc));
5355 CursorVis.visitFileRegion();
5356 }
5357
5358 return Result;
5359}
5360
5361static SourceRange getRawCursorExtent(CXCursor C) {
5362 if (clang_isReference(C.kind)) {
5363 switch (C.kind) {
5364 case CXCursor_ObjCSuperClassRef:
5365 return getCursorObjCSuperClassRef(C).second;
5366
5367 case CXCursor_ObjCProtocolRef:
5368 return getCursorObjCProtocolRef(C).second;
5369
5370 case CXCursor_ObjCClassRef:
5371 return getCursorObjCClassRef(C).second;
5372
5373 case CXCursor_TypeRef:
5374 return getCursorTypeRef(C).second;
5375
5376 case CXCursor_TemplateRef:
5377 return getCursorTemplateRef(C).second;
5378
5379 case CXCursor_NamespaceRef:
5380 return getCursorNamespaceRef(C).second;
5381
5382 case CXCursor_MemberRef:
5383 return getCursorMemberRef(C).second;
5384
5385 case CXCursor_CXXBaseSpecifier:
5386 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5387
5388 case CXCursor_LabelRef:
5389 return getCursorLabelRef(C).second;
5390
5391 case CXCursor_OverloadedDeclRef:
5392 return getCursorOverloadedDeclRef(C).second;
5393
5394 case CXCursor_VariableRef:
5395 return getCursorVariableRef(C).second;
5396
5397 default:
5398 // FIXME: Need a way to enumerate all non-reference cases.
5399 llvm_unreachable("Missed a reference kind");
5400 }
5401 }
5402
5403 if (clang_isExpression(C.kind))
5404 return getCursorExpr(C)->getSourceRange();
5405
5406 if (clang_isStatement(C.kind))
5407 return getCursorStmt(C)->getSourceRange();
5408
5409 if (clang_isAttribute(C.kind))
5410 return getCursorAttr(C)->getRange();
5411
5412 if (C.kind == CXCursor_PreprocessingDirective)
5413 return cxcursor::getCursorPreprocessingDirective(C);
5414
5415 if (C.kind == CXCursor_MacroExpansion) {
5416 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005417 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005418 return TU->mapRangeFromPreamble(Range);
5419 }
5420
5421 if (C.kind == CXCursor_MacroDefinition) {
5422 ASTUnit *TU = getCursorASTUnit(C);
5423 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5424 return TU->mapRangeFromPreamble(Range);
5425 }
5426
5427 if (C.kind == CXCursor_InclusionDirective) {
5428 ASTUnit *TU = getCursorASTUnit(C);
5429 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5430 return TU->mapRangeFromPreamble(Range);
5431 }
5432
5433 if (C.kind == CXCursor_TranslationUnit) {
5434 ASTUnit *TU = getCursorASTUnit(C);
5435 FileID MainID = TU->getSourceManager().getMainFileID();
5436 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5437 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5438 return SourceRange(Start, End);
5439 }
5440
5441 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005442 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 if (!D)
5444 return SourceRange();
5445
5446 SourceRange R = D->getSourceRange();
5447 // FIXME: Multiple variables declared in a single declaration
5448 // currently lack the information needed to correctly determine their
5449 // ranges when accounting for the type-specifier. We use context
5450 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5451 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005452 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 if (!cxcursor::isFirstInDeclGroup(C))
5454 R.setBegin(VD->getLocation());
5455 }
5456 return R;
5457 }
5458 return SourceRange();
5459}
5460
5461/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5462/// the decl-specifier-seq for declarations.
5463static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5464 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005465 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005466 if (!D)
5467 return SourceRange();
5468
5469 SourceRange R = D->getSourceRange();
5470
5471 // Adjust the start of the location for declarations preceded by
5472 // declaration specifiers.
5473 SourceLocation StartLoc;
5474 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5475 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5476 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005477 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005478 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5479 StartLoc = TI->getTypeLoc().getLocStart();
5480 }
5481
5482 if (StartLoc.isValid() && R.getBegin().isValid() &&
5483 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5484 R.setBegin(StartLoc);
5485
5486 // FIXME: Multiple variables declared in a single declaration
5487 // currently lack the information needed to correctly determine their
5488 // ranges when accounting for the type-specifier. We use context
5489 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5490 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005491 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005492 if (!cxcursor::isFirstInDeclGroup(C))
5493 R.setBegin(VD->getLocation());
5494 }
5495
5496 return R;
5497 }
5498
5499 return getRawCursorExtent(C);
5500}
5501
5502extern "C" {
5503
5504CXSourceRange clang_getCursorExtent(CXCursor C) {
5505 SourceRange R = getRawCursorExtent(C);
5506 if (R.isInvalid())
5507 return clang_getNullRange();
5508
5509 return cxloc::translateSourceRange(getCursorContext(C), R);
5510}
5511
5512CXCursor clang_getCursorReferenced(CXCursor C) {
5513 if (clang_isInvalid(C.kind))
5514 return clang_getNullCursor();
5515
5516 CXTranslationUnit tu = getCursorTU(C);
5517 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005518 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005519 if (!D)
5520 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005521 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005522 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005523 if (const ObjCPropertyImplDecl *PropImpl =
5524 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5526 return MakeCXCursor(Property, tu);
5527
5528 return C;
5529 }
5530
5531 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005532 const Expr *E = getCursorExpr(C);
5533 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005534 if (D) {
5535 CXCursor declCursor = MakeCXCursor(D, tu);
5536 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5537 declCursor);
5538 return declCursor;
5539 }
5540
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005541 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005542 return MakeCursorOverloadedDeclRef(Ovl, tu);
5543
5544 return clang_getNullCursor();
5545 }
5546
5547 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005548 const Stmt *S = getCursorStmt(C);
5549 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005550 if (LabelDecl *label = Goto->getLabel())
5551 if (LabelStmt *labelS = label->getStmt())
5552 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5553
5554 return clang_getNullCursor();
5555 }
Richard Smith66a81862015-05-04 02:25:31 +00005556
Guy Benyei11169dd2012-12-18 14:30:41 +00005557 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005558 if (const MacroDefinitionRecord *Def =
5559 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005560 return MakeMacroDefinitionCursor(Def, tu);
5561 }
5562
5563 if (!clang_isReference(C.kind))
5564 return clang_getNullCursor();
5565
5566 switch (C.kind) {
5567 case CXCursor_ObjCSuperClassRef:
5568 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5569
5570 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005571 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5572 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005573 return MakeCXCursor(Def, tu);
5574
5575 return MakeCXCursor(Prot, tu);
5576 }
5577
5578 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005579 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5580 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005581 return MakeCXCursor(Def, tu);
5582
5583 return MakeCXCursor(Class, tu);
5584 }
5585
5586 case CXCursor_TypeRef:
5587 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5588
5589 case CXCursor_TemplateRef:
5590 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5591
5592 case CXCursor_NamespaceRef:
5593 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5594
5595 case CXCursor_MemberRef:
5596 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5597
5598 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005599 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005600 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5601 tu ));
5602 }
5603
5604 case CXCursor_LabelRef:
5605 // FIXME: We end up faking the "parent" declaration here because we
5606 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005607 return MakeCXCursor(getCursorLabelRef(C).first,
5608 cxtu::getASTUnit(tu)->getASTContext()
5609 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005610 tu);
5611
5612 case CXCursor_OverloadedDeclRef:
5613 return C;
5614
5615 case CXCursor_VariableRef:
5616 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5617
5618 default:
5619 // We would prefer to enumerate all non-reference cursor kinds here.
5620 llvm_unreachable("Unhandled reference cursor kind");
5621 }
5622}
5623
5624CXCursor clang_getCursorDefinition(CXCursor C) {
5625 if (clang_isInvalid(C.kind))
5626 return clang_getNullCursor();
5627
5628 CXTranslationUnit TU = getCursorTU(C);
5629
5630 bool WasReference = false;
5631 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5632 C = clang_getCursorReferenced(C);
5633 WasReference = true;
5634 }
5635
5636 if (C.kind == CXCursor_MacroExpansion)
5637 return clang_getCursorReferenced(C);
5638
5639 if (!clang_isDeclaration(C.kind))
5640 return clang_getNullCursor();
5641
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005642 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 if (!D)
5644 return clang_getNullCursor();
5645
5646 switch (D->getKind()) {
5647 // Declaration kinds that don't really separate the notions of
5648 // declaration and definition.
5649 case Decl::Namespace:
5650 case Decl::Typedef:
5651 case Decl::TypeAlias:
5652 case Decl::TypeAliasTemplate:
5653 case Decl::TemplateTypeParm:
5654 case Decl::EnumConstant:
5655 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005656 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 case Decl::IndirectField:
5658 case Decl::ObjCIvar:
5659 case Decl::ObjCAtDefsField:
5660 case Decl::ImplicitParam:
5661 case Decl::ParmVar:
5662 case Decl::NonTypeTemplateParm:
5663 case Decl::TemplateTemplateParm:
5664 case Decl::ObjCCategoryImpl:
5665 case Decl::ObjCImplementation:
5666 case Decl::AccessSpec:
5667 case Decl::LinkageSpec:
5668 case Decl::ObjCPropertyImpl:
5669 case Decl::FileScopeAsm:
5670 case Decl::StaticAssert:
5671 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005672 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00005673 case Decl::OMPCapturedExpr:
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 case Decl::Label: // FIXME: Is this right??
5675 case Decl::ClassScopeFunctionSpecialization:
5676 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005677 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005678 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005679 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005680 return C;
5681
5682 // Declaration kinds that don't make any sense here, but are
5683 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005684 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005685 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005686 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005687 break;
5688
5689 // Declaration kinds for which the definition is not resolvable.
5690 case Decl::UnresolvedUsingTypename:
5691 case Decl::UnresolvedUsingValue:
5692 break;
5693
5694 case Decl::UsingDirective:
5695 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5696 TU);
5697
5698 case Decl::NamespaceAlias:
5699 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5700
5701 case Decl::Enum:
5702 case Decl::Record:
5703 case Decl::CXXRecord:
5704 case Decl::ClassTemplateSpecialization:
5705 case Decl::ClassTemplatePartialSpecialization:
5706 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5707 return MakeCXCursor(Def, TU);
5708 return clang_getNullCursor();
5709
5710 case Decl::Function:
5711 case Decl::CXXMethod:
5712 case Decl::CXXConstructor:
5713 case Decl::CXXDestructor:
5714 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005715 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005716 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005717 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005718 return clang_getNullCursor();
5719 }
5720
Larisse Voufo39a1e502013-08-06 01:03:05 +00005721 case Decl::Var:
5722 case Decl::VarTemplateSpecialization:
5723 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005725 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005726 return MakeCXCursor(Def, TU);
5727 return clang_getNullCursor();
5728 }
5729
5730 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005731 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005732 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5733 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5734 return clang_getNullCursor();
5735 }
5736
5737 case Decl::ClassTemplate: {
5738 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5739 ->getDefinition())
5740 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5741 TU);
5742 return clang_getNullCursor();
5743 }
5744
Larisse Voufo39a1e502013-08-06 01:03:05 +00005745 case Decl::VarTemplate: {
5746 if (VarDecl *Def =
5747 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5748 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5749 return clang_getNullCursor();
5750 }
5751
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 case Decl::Using:
5753 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5754 D->getLocation(), TU);
5755
5756 case Decl::UsingShadow:
5757 return clang_getCursorDefinition(
5758 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5759 TU));
5760
5761 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005762 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005763 if (Method->isThisDeclarationADefinition())
5764 return C;
5765
5766 // Dig out the method definition in the associated
5767 // @implementation, if we have it.
5768 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005769 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5771 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5772 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5773 Method->isInstanceMethod()))
5774 if (Def->isThisDeclarationADefinition())
5775 return MakeCXCursor(Def, TU);
5776
5777 return clang_getNullCursor();
5778 }
5779
5780 case Decl::ObjCCategory:
5781 if (ObjCCategoryImplDecl *Impl
5782 = cast<ObjCCategoryDecl>(D)->getImplementation())
5783 return MakeCXCursor(Impl, TU);
5784 return clang_getNullCursor();
5785
5786 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005787 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 return MakeCXCursor(Def, TU);
5789 return clang_getNullCursor();
5790
5791 case Decl::ObjCInterface: {
5792 // There are two notions of a "definition" for an Objective-C
5793 // class: the interface and its implementation. When we resolved a
5794 // reference to an Objective-C class, produce the @interface as
5795 // the definition; when we were provided with the interface,
5796 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005797 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005798 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005799 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005800 return MakeCXCursor(Def, TU);
5801 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5802 return MakeCXCursor(Impl, TU);
5803 return clang_getNullCursor();
5804 }
5805
5806 case Decl::ObjCProperty:
5807 // FIXME: We don't really know where to find the
5808 // ObjCPropertyImplDecls that implement this property.
5809 return clang_getNullCursor();
5810
5811 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005812 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005813 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005814 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005815 return MakeCXCursor(Def, TU);
5816
5817 return clang_getNullCursor();
5818
5819 case Decl::Friend:
5820 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5821 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5822 return clang_getNullCursor();
5823
5824 case Decl::FriendTemplate:
5825 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5826 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5827 return clang_getNullCursor();
5828 }
5829
5830 return clang_getNullCursor();
5831}
5832
5833unsigned clang_isCursorDefinition(CXCursor C) {
5834 if (!clang_isDeclaration(C.kind))
5835 return 0;
5836
5837 return clang_getCursorDefinition(C) == C;
5838}
5839
5840CXCursor clang_getCanonicalCursor(CXCursor C) {
5841 if (!clang_isDeclaration(C.kind))
5842 return C;
5843
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005844 if (const Decl *D = getCursorDecl(C)) {
5845 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005846 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5847 return MakeCXCursor(CatD, getCursorTU(C));
5848
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005849 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5850 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005851 return MakeCXCursor(IFD, getCursorTU(C));
5852
5853 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5854 }
5855
5856 return C;
5857}
5858
5859int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5860 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5861}
5862
5863unsigned clang_getNumOverloadedDecls(CXCursor C) {
5864 if (C.kind != CXCursor_OverloadedDeclRef)
5865 return 0;
5866
5867 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005868 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005869 return E->getNumDecls();
5870
5871 if (OverloadedTemplateStorage *S
5872 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5873 return S->size();
5874
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005875 const Decl *D = Storage.get<const Decl *>();
5876 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005877 return Using->shadow_size();
5878
5879 return 0;
5880}
5881
5882CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5883 if (cursor.kind != CXCursor_OverloadedDeclRef)
5884 return clang_getNullCursor();
5885
5886 if (index >= clang_getNumOverloadedDecls(cursor))
5887 return clang_getNullCursor();
5888
5889 CXTranslationUnit TU = getCursorTU(cursor);
5890 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005891 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005892 return MakeCXCursor(E->decls_begin()[index], TU);
5893
5894 if (OverloadedTemplateStorage *S
5895 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5896 return MakeCXCursor(S->begin()[index], TU);
5897
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005898 const Decl *D = Storage.get<const Decl *>();
5899 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005900 // FIXME: This is, unfortunately, linear time.
5901 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5902 std::advance(Pos, index);
5903 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5904 }
5905
5906 return clang_getNullCursor();
5907}
5908
5909void clang_getDefinitionSpellingAndExtent(CXCursor C,
5910 const char **startBuf,
5911 const char **endBuf,
5912 unsigned *startLine,
5913 unsigned *startColumn,
5914 unsigned *endLine,
5915 unsigned *endColumn) {
5916 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005917 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005918 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5919
5920 SourceManager &SM = FD->getASTContext().getSourceManager();
5921 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5922 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5923 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5924 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5925 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5926 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5927}
5928
5929
5930CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5931 unsigned PieceIndex) {
5932 RefNamePieces Pieces;
5933
5934 switch (C.kind) {
5935 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005936 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005937 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5938 E->getQualifierLoc().getSourceRange());
5939 break;
5940
5941 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005942 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5943 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5944 Pieces =
5945 buildPieces(NameFlags, false, E->getNameInfo(),
5946 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5947 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005948 break;
5949
5950 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005951 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005952 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005953 const Expr *Callee = OCE->getCallee();
5954 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005955 Callee = ICE->getSubExpr();
5956
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005957 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005958 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5959 DRE->getQualifierLoc().getSourceRange());
5960 }
5961 break;
5962
5963 default:
5964 break;
5965 }
5966
5967 if (Pieces.empty()) {
5968 if (PieceIndex == 0)
5969 return clang_getCursorExtent(C);
5970 } else if (PieceIndex < Pieces.size()) {
5971 SourceRange R = Pieces[PieceIndex];
5972 if (R.isValid())
5973 return cxloc::translateSourceRange(getCursorContext(C), R);
5974 }
5975
5976 return clang_getNullRange();
5977}
5978
5979void clang_enableStackTraces(void) {
5980 llvm::sys::PrintStackTraceOnErrorSignal();
5981}
5982
5983void clang_executeOnThread(void (*fn)(void*), void *user_data,
5984 unsigned stack_size) {
5985 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5986}
5987
5988} // end: extern "C"
5989
5990//===----------------------------------------------------------------------===//
5991// Token-based Operations.
5992//===----------------------------------------------------------------------===//
5993
5994/* CXToken layout:
5995 * int_data[0]: a CXTokenKind
5996 * int_data[1]: starting token location
5997 * int_data[2]: token length
5998 * int_data[3]: reserved
5999 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6000 * otherwise unused.
6001 */
6002extern "C" {
6003
6004CXTokenKind clang_getTokenKind(CXToken CXTok) {
6005 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6006}
6007
6008CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6009 switch (clang_getTokenKind(CXTok)) {
6010 case CXToken_Identifier:
6011 case CXToken_Keyword:
6012 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00006013 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00006014 ->getNameStart());
6015
6016 case CXToken_Literal: {
6017 // We have stashed the starting pointer in the ptr_data field. Use it.
6018 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006019 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006020 }
6021
6022 case CXToken_Punctuation:
6023 case CXToken_Comment:
6024 break;
6025 }
6026
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006027 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006028 LOG_BAD_TU(TU);
6029 return cxstring::createEmpty();
6030 }
6031
Guy Benyei11169dd2012-12-18 14:30:41 +00006032 // We have to find the starting buffer pointer the hard way, by
6033 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006034 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006035 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006036 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006037
6038 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
6039 std::pair<FileID, unsigned> LocInfo
6040 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
6041 bool Invalid = false;
6042 StringRef Buffer
6043 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
6044 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006045 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006046
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006047 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006048}
6049
6050CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006051 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006052 LOG_BAD_TU(TU);
6053 return clang_getNullLocation();
6054 }
6055
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006056 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006057 if (!CXXUnit)
6058 return clang_getNullLocation();
6059
6060 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
6061 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6062}
6063
6064CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006065 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006066 LOG_BAD_TU(TU);
6067 return clang_getNullRange();
6068 }
6069
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006070 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006071 if (!CXXUnit)
6072 return clang_getNullRange();
6073
6074 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
6075 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6076}
6077
6078static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6079 SmallVectorImpl<CXToken> &CXTokens) {
6080 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6081 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006082 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006083 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006084 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006085
6086 // Cannot tokenize across files.
6087 if (BeginLocInfo.first != EndLocInfo.first)
6088 return;
6089
6090 // Create a lexer
6091 bool Invalid = false;
6092 StringRef Buffer
6093 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6094 if (Invalid)
6095 return;
6096
6097 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6098 CXXUnit->getASTContext().getLangOpts(),
6099 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6100 Lex.SetCommentRetentionState(true);
6101
6102 // Lex tokens until we hit the end of the range.
6103 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6104 Token Tok;
6105 bool previousWasAt = false;
6106 do {
6107 // Lex the next token
6108 Lex.LexFromRawLexer(Tok);
6109 if (Tok.is(tok::eof))
6110 break;
6111
6112 // Initialize the CXToken.
6113 CXToken CXTok;
6114
6115 // - Common fields
6116 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6117 CXTok.int_data[2] = Tok.getLength();
6118 CXTok.int_data[3] = 0;
6119
6120 // - Kind-specific fields
6121 if (Tok.isLiteral()) {
6122 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006123 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006124 } else if (Tok.is(tok::raw_identifier)) {
6125 // Lookup the identifier to determine whether we have a keyword.
6126 IdentifierInfo *II
6127 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6128
6129 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6130 CXTok.int_data[0] = CXToken_Keyword;
6131 }
6132 else {
6133 CXTok.int_data[0] = Tok.is(tok::identifier)
6134 ? CXToken_Identifier
6135 : CXToken_Keyword;
6136 }
6137 CXTok.ptr_data = II;
6138 } else if (Tok.is(tok::comment)) {
6139 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006140 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006141 } else {
6142 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006143 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006144 }
6145 CXTokens.push_back(CXTok);
6146 previousWasAt = Tok.is(tok::at);
6147 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6148}
6149
6150void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6151 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006152 LOG_FUNC_SECTION {
6153 *Log << TU << ' ' << Range;
6154 }
6155
Guy Benyei11169dd2012-12-18 14:30:41 +00006156 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006157 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006158 if (NumTokens)
6159 *NumTokens = 0;
6160
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006161 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006162 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006163 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006164 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006165
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006166 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006167 if (!CXXUnit || !Tokens || !NumTokens)
6168 return;
6169
6170 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6171
6172 SourceRange R = cxloc::translateCXSourceRange(Range);
6173 if (R.isInvalid())
6174 return;
6175
6176 SmallVector<CXToken, 32> CXTokens;
6177 getTokens(CXXUnit, R, CXTokens);
6178
6179 if (CXTokens.empty())
6180 return;
6181
6182 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6183 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6184 *NumTokens = CXTokens.size();
6185}
6186
6187void clang_disposeTokens(CXTranslationUnit TU,
6188 CXToken *Tokens, unsigned NumTokens) {
6189 free(Tokens);
6190}
6191
6192} // end: extern "C"
6193
6194//===----------------------------------------------------------------------===//
6195// Token annotation APIs.
6196//===----------------------------------------------------------------------===//
6197
Guy Benyei11169dd2012-12-18 14:30:41 +00006198static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6199 CXCursor parent,
6200 CXClientData client_data);
6201static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6202 CXClientData client_data);
6203
6204namespace {
6205class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006206 CXToken *Tokens;
6207 CXCursor *Cursors;
6208 unsigned NumTokens;
6209 unsigned TokIdx;
6210 unsigned PreprocessingTokIdx;
6211 CursorVisitor AnnotateVis;
6212 SourceManager &SrcMgr;
6213 bool HasContextSensitiveKeywords;
6214
6215 struct PostChildrenInfo {
6216 CXCursor Cursor;
6217 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006218 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006219 unsigned BeforeChildrenTokenIdx;
6220 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006221 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006222
6223 CXToken &getTok(unsigned Idx) {
6224 assert(Idx < NumTokens);
6225 return Tokens[Idx];
6226 }
6227 const CXToken &getTok(unsigned Idx) const {
6228 assert(Idx < NumTokens);
6229 return Tokens[Idx];
6230 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006231 bool MoreTokens() const { return TokIdx < NumTokens; }
6232 unsigned NextToken() const { return TokIdx; }
6233 void AdvanceToken() { ++TokIdx; }
6234 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006235 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006236 }
6237 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006238 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006239 }
6240 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006241 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006242 }
6243
6244 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006245 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006246 SourceRange);
6247
6248public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006249 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006250 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006251 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006252 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006253 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006254 AnnotateTokensVisitor, this,
6255 /*VisitPreprocessorLast=*/true,
6256 /*VisitIncludedEntities=*/false,
6257 RegionOfInterest,
6258 /*VisitDeclsOnly=*/false,
6259 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006260 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006261 HasContextSensitiveKeywords(false) { }
6262
6263 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6264 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6265 bool postVisitChildren(CXCursor cursor);
6266 void AnnotateTokens();
6267
6268 /// \brief Determine whether the annotator saw any cursors that have
6269 /// context-sensitive keywords.
6270 bool hasContextSensitiveKeywords() const {
6271 return HasContextSensitiveKeywords;
6272 }
6273
6274 ~AnnotateTokensWorker() {
6275 assert(PostChildrenInfos.empty());
6276 }
6277};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006278}
Guy Benyei11169dd2012-12-18 14:30:41 +00006279
6280void AnnotateTokensWorker::AnnotateTokens() {
6281 // Walk the AST within the region of interest, annotating tokens
6282 // along the way.
6283 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006284}
Guy Benyei11169dd2012-12-18 14:30:41 +00006285
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006286static inline void updateCursorAnnotation(CXCursor &Cursor,
6287 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006288 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006289 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006290 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006291}
6292
6293/// \brief It annotates and advances tokens with a cursor until the comparison
6294//// between the cursor location and the source range is the same as
6295/// \arg compResult.
6296///
6297/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6298/// Pass RangeOverlap to annotate tokens inside a range.
6299void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6300 RangeComparisonResult compResult,
6301 SourceRange range) {
6302 while (MoreTokens()) {
6303 const unsigned I = NextToken();
6304 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006305 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6306 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006307
6308 SourceLocation TokLoc = GetTokenLoc(I);
6309 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006310 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006311 AdvanceToken();
6312 continue;
6313 }
6314 break;
6315 }
6316}
6317
6318/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006319/// \returns true if it advanced beyond all macro tokens, false otherwise.
6320bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006321 CXCursor updateC,
6322 RangeComparisonResult compResult,
6323 SourceRange range) {
6324 assert(MoreTokens());
6325 assert(isFunctionMacroToken(NextToken()) &&
6326 "Should be called only for macro arg tokens");
6327
6328 // This works differently than annotateAndAdvanceTokens; because expanded
6329 // macro arguments can have arbitrary translation-unit source order, we do not
6330 // advance the token index one by one until a token fails the range test.
6331 // We only advance once past all of the macro arg tokens if all of them
6332 // pass the range test. If one of them fails we keep the token index pointing
6333 // at the start of the macro arg tokens so that the failing token will be
6334 // annotated by a subsequent annotation try.
6335
6336 bool atLeastOneCompFail = false;
6337
6338 unsigned I = NextToken();
6339 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6340 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6341 if (TokLoc.isFileID())
6342 continue; // not macro arg token, it's parens or comma.
6343 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6344 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6345 Cursors[I] = updateC;
6346 } else
6347 atLeastOneCompFail = true;
6348 }
6349
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006350 if (atLeastOneCompFail)
6351 return false;
6352
6353 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6354 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006355}
6356
6357enum CXChildVisitResult
6358AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006359 SourceRange cursorRange = getRawCursorExtent(cursor);
6360 if (cursorRange.isInvalid())
6361 return CXChildVisit_Recurse;
6362
6363 if (!HasContextSensitiveKeywords) {
6364 // Objective-C properties can have context-sensitive keywords.
6365 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006366 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006367 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6368 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6369 }
6370 // Objective-C methods can have context-sensitive keywords.
6371 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6372 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006373 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006374 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6375 if (Method->getObjCDeclQualifier())
6376 HasContextSensitiveKeywords = true;
6377 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006378 for (const auto *P : Method->params()) {
6379 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006380 HasContextSensitiveKeywords = true;
6381 break;
6382 }
6383 }
6384 }
6385 }
6386 }
6387 // C++ methods can have context-sensitive keywords.
6388 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006389 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006390 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6391 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6392 HasContextSensitiveKeywords = true;
6393 }
6394 }
6395 // C++ classes can have context-sensitive keywords.
6396 else if (cursor.kind == CXCursor_StructDecl ||
6397 cursor.kind == CXCursor_ClassDecl ||
6398 cursor.kind == CXCursor_ClassTemplate ||
6399 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006400 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006401 if (D->hasAttr<FinalAttr>())
6402 HasContextSensitiveKeywords = true;
6403 }
6404 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006405
6406 // Don't override a property annotation with its getter/setter method.
6407 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6408 parent.kind == CXCursor_ObjCPropertyDecl)
6409 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006410
6411 if (clang_isPreprocessing(cursor.kind)) {
6412 // Items in the preprocessing record are kept separate from items in
6413 // declarations, so we keep a separate token index.
6414 unsigned SavedTokIdx = TokIdx;
6415 TokIdx = PreprocessingTokIdx;
6416
6417 // Skip tokens up until we catch up to the beginning of the preprocessing
6418 // entry.
6419 while (MoreTokens()) {
6420 const unsigned I = NextToken();
6421 SourceLocation TokLoc = GetTokenLoc(I);
6422 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6423 case RangeBefore:
6424 AdvanceToken();
6425 continue;
6426 case RangeAfter:
6427 case RangeOverlap:
6428 break;
6429 }
6430 break;
6431 }
6432
6433 // Look at all of the tokens within this range.
6434 while (MoreTokens()) {
6435 const unsigned I = NextToken();
6436 SourceLocation TokLoc = GetTokenLoc(I);
6437 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6438 case RangeBefore:
6439 llvm_unreachable("Infeasible");
6440 case RangeAfter:
6441 break;
6442 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006443 // For macro expansions, just note where the beginning of the macro
6444 // expansion occurs.
6445 if (cursor.kind == CXCursor_MacroExpansion) {
6446 if (TokLoc == cursorRange.getBegin())
6447 Cursors[I] = cursor;
6448 AdvanceToken();
6449 break;
6450 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006451 // We may have already annotated macro names inside macro definitions.
6452 if (Cursors[I].kind != CXCursor_MacroExpansion)
6453 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006454 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006455 continue;
6456 }
6457 break;
6458 }
6459
6460 // Save the preprocessing token index; restore the non-preprocessing
6461 // token index.
6462 PreprocessingTokIdx = TokIdx;
6463 TokIdx = SavedTokIdx;
6464 return CXChildVisit_Recurse;
6465 }
6466
6467 if (cursorRange.isInvalid())
6468 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006469
6470 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006471 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006472 const enum CXCursorKind K = clang_getCursorKind(parent);
6473 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006474 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6475 // Attributes are annotated out-of-order, skip tokens until we reach it.
6476 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006477 ? clang_getNullCursor() : parent;
6478
6479 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6480
6481 // Avoid having the cursor of an expression "overwrite" the annotation of the
6482 // variable declaration that it belongs to.
6483 // This can happen for C++ constructor expressions whose range generally
6484 // include the variable declaration, e.g.:
6485 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006486 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006487 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006488 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006489 const unsigned I = NextToken();
6490 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6491 E->getLocStart() == D->getLocation() &&
6492 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006493 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006494 AdvanceToken();
6495 }
6496 }
6497 }
6498
6499 // Before recursing into the children keep some state that we are going
6500 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6501 // extra work after the child nodes are visited.
6502 // Note that we don't call VisitChildren here to avoid traversing statements
6503 // code-recursively which can blow the stack.
6504
6505 PostChildrenInfo Info;
6506 Info.Cursor = cursor;
6507 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006508 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006509 Info.BeforeChildrenTokenIdx = NextToken();
6510 PostChildrenInfos.push_back(Info);
6511
6512 return CXChildVisit_Recurse;
6513}
6514
6515bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6516 if (PostChildrenInfos.empty())
6517 return false;
6518 const PostChildrenInfo &Info = PostChildrenInfos.back();
6519 if (!clang_equalCursors(Info.Cursor, cursor))
6520 return false;
6521
6522 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6523 const unsigned AfterChildren = NextToken();
6524 SourceRange cursorRange = Info.CursorRange;
6525
6526 // Scan the tokens that are at the end of the cursor, but are not captured
6527 // but the child cursors.
6528 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6529
6530 // Scan the tokens that are at the beginning of the cursor, but are not
6531 // capture by the child cursors.
6532 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6533 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6534 break;
6535
6536 Cursors[I] = cursor;
6537 }
6538
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006539 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6540 // encountered the attribute cursor.
6541 if (clang_isAttribute(cursor.kind))
6542 TokIdx = Info.BeforeReachingCursorIdx;
6543
Guy Benyei11169dd2012-12-18 14:30:41 +00006544 PostChildrenInfos.pop_back();
6545 return false;
6546}
6547
6548static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6549 CXCursor parent,
6550 CXClientData client_data) {
6551 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6552}
6553
6554static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6555 CXClientData client_data) {
6556 return static_cast<AnnotateTokensWorker*>(client_data)->
6557 postVisitChildren(cursor);
6558}
6559
6560namespace {
6561
6562/// \brief Uses the macro expansions in the preprocessing record to find
6563/// and mark tokens that are macro arguments. This info is used by the
6564/// AnnotateTokensWorker.
6565class MarkMacroArgTokensVisitor {
6566 SourceManager &SM;
6567 CXToken *Tokens;
6568 unsigned NumTokens;
6569 unsigned CurIdx;
6570
6571public:
6572 MarkMacroArgTokensVisitor(SourceManager &SM,
6573 CXToken *tokens, unsigned numTokens)
6574 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6575
6576 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6577 if (cursor.kind != CXCursor_MacroExpansion)
6578 return CXChildVisit_Continue;
6579
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006580 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006581 if (macroRange.getBegin() == macroRange.getEnd())
6582 return CXChildVisit_Continue; // it's not a function macro.
6583
6584 for (; CurIdx < NumTokens; ++CurIdx) {
6585 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6586 macroRange.getBegin()))
6587 break;
6588 }
6589
6590 if (CurIdx == NumTokens)
6591 return CXChildVisit_Break;
6592
6593 for (; CurIdx < NumTokens; ++CurIdx) {
6594 SourceLocation tokLoc = getTokenLoc(CurIdx);
6595 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6596 break;
6597
6598 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6599 }
6600
6601 if (CurIdx == NumTokens)
6602 return CXChildVisit_Break;
6603
6604 return CXChildVisit_Continue;
6605 }
6606
6607private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006608 CXToken &getTok(unsigned Idx) {
6609 assert(Idx < NumTokens);
6610 return Tokens[Idx];
6611 }
6612 const CXToken &getTok(unsigned Idx) const {
6613 assert(Idx < NumTokens);
6614 return Tokens[Idx];
6615 }
6616
Guy Benyei11169dd2012-12-18 14:30:41 +00006617 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006618 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006619 }
6620
6621 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6622 // The third field is reserved and currently not used. Use it here
6623 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006624 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006625 }
6626};
6627
6628} // end anonymous namespace
6629
6630static CXChildVisitResult
6631MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6632 CXClientData client_data) {
6633 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6634 parent);
6635}
6636
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006637/// \brief Used by \c annotatePreprocessorTokens.
6638/// \returns true if lexing was finished, false otherwise.
6639static bool lexNext(Lexer &Lex, Token &Tok,
6640 unsigned &NextIdx, unsigned NumTokens) {
6641 if (NextIdx >= NumTokens)
6642 return true;
6643
6644 ++NextIdx;
6645 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006646 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006647}
6648
Guy Benyei11169dd2012-12-18 14:30:41 +00006649static void annotatePreprocessorTokens(CXTranslationUnit TU,
6650 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006651 CXCursor *Cursors,
6652 CXToken *Tokens,
6653 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006654 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006655
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006656 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006657 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6658 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006659 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006660 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006661 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006662
6663 if (BeginLocInfo.first != EndLocInfo.first)
6664 return;
6665
6666 StringRef Buffer;
6667 bool Invalid = false;
6668 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6669 if (Buffer.empty() || Invalid)
6670 return;
6671
6672 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6673 CXXUnit->getASTContext().getLangOpts(),
6674 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6675 Buffer.end());
6676 Lex.SetCommentRetentionState(true);
6677
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006678 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006679 // Lex tokens in raw mode until we hit the end of the range, to avoid
6680 // entering #includes or expanding macros.
6681 while (true) {
6682 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006683 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6684 break;
6685 unsigned TokIdx = NextIdx-1;
6686 assert(Tok.getLocation() ==
6687 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006688
6689 reprocess:
6690 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006691 // We have found a preprocessing directive. Annotate the tokens
6692 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006693 //
6694 // FIXME: Some simple tests here could identify macro definitions and
6695 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006696
6697 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006698 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6699 break;
6700
Craig Topper69186e72014-06-08 08:38:04 +00006701 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006702 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006703 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6704 break;
6705
6706 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006707 IdentifierInfo &II =
6708 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006709 SourceLocation MappedTokLoc =
6710 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6711 MI = getMacroInfo(II, MappedTokLoc, TU);
6712 }
6713 }
6714
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006715 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006716 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006717 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6718 finished = true;
6719 break;
6720 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006721 // If we are in a macro definition, check if the token was ever a
6722 // macro name and annotate it if that's the case.
6723 if (MI) {
6724 SourceLocation SaveLoc = Tok.getLocation();
6725 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006726 MacroDefinitionRecord *MacroDef =
6727 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006728 Tok.setLocation(SaveLoc);
6729 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006730 Cursors[NextIdx - 1] =
6731 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006732 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006733 } while (!Tok.isAtStartOfLine());
6734
6735 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6736 assert(TokIdx <= LastIdx);
6737 SourceLocation EndLoc =
6738 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6739 CXCursor Cursor =
6740 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6741
6742 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006743 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006744
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006745 if (finished)
6746 break;
6747 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006748 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006749 }
6750}
6751
6752// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006753static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6754 CXToken *Tokens, unsigned NumTokens,
6755 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006756 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006757 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6758 setThreadBackgroundPriority();
6759
6760 // Determine the region of interest, which contains all of the tokens.
6761 SourceRange RegionOfInterest;
6762 RegionOfInterest.setBegin(
6763 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6764 RegionOfInterest.setEnd(
6765 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6766 Tokens[NumTokens-1])));
6767
Guy Benyei11169dd2012-12-18 14:30:41 +00006768 // Relex the tokens within the source range to look for preprocessing
6769 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006770 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006771
6772 // If begin location points inside a macro argument, set it to the expansion
6773 // location so we can have the full context when annotating semantically.
6774 {
6775 SourceManager &SM = CXXUnit->getSourceManager();
6776 SourceLocation Loc =
6777 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6778 if (Loc.isMacroID())
6779 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6780 }
6781
Guy Benyei11169dd2012-12-18 14:30:41 +00006782 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6783 // Search and mark tokens that are macro argument expansions.
6784 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6785 Tokens, NumTokens);
6786 CursorVisitor MacroArgMarker(TU,
6787 MarkMacroArgTokensVisitorDelegate, &Visitor,
6788 /*VisitPreprocessorLast=*/true,
6789 /*VisitIncludedEntities=*/false,
6790 RegionOfInterest);
6791 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6792 }
6793
6794 // Annotate all of the source locations in the region of interest that map to
6795 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006796 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006797
6798 // FIXME: We use a ridiculous stack size here because the data-recursion
6799 // algorithm uses a large stack frame than the non-data recursive version,
6800 // and AnnotationTokensWorker currently transforms the data-recursion
6801 // algorithm back into a traditional recursion by explicitly calling
6802 // VisitChildren(). We will need to remove this explicit recursive call.
6803 W.AnnotateTokens();
6804
6805 // If we ran into any entities that involve context-sensitive keywords,
6806 // take another pass through the tokens to mark them as such.
6807 if (W.hasContextSensitiveKeywords()) {
6808 for (unsigned I = 0; I != NumTokens; ++I) {
6809 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6810 continue;
6811
6812 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6813 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006814 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006815 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6816 if (Property->getPropertyAttributesAsWritten() != 0 &&
6817 llvm::StringSwitch<bool>(II->getName())
6818 .Case("readonly", true)
6819 .Case("assign", true)
6820 .Case("unsafe_unretained", true)
6821 .Case("readwrite", true)
6822 .Case("retain", true)
6823 .Case("copy", true)
6824 .Case("nonatomic", true)
6825 .Case("atomic", true)
6826 .Case("getter", true)
6827 .Case("setter", true)
6828 .Case("strong", true)
6829 .Case("weak", true)
6830 .Default(false))
6831 Tokens[I].int_data[0] = CXToken_Keyword;
6832 }
6833 continue;
6834 }
6835
6836 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6837 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6838 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6839 if (llvm::StringSwitch<bool>(II->getName())
6840 .Case("in", true)
6841 .Case("out", true)
6842 .Case("inout", true)
6843 .Case("oneway", true)
6844 .Case("bycopy", true)
6845 .Case("byref", true)
6846 .Default(false))
6847 Tokens[I].int_data[0] = CXToken_Keyword;
6848 continue;
6849 }
6850
6851 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6852 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6853 Tokens[I].int_data[0] = CXToken_Keyword;
6854 continue;
6855 }
6856 }
6857 }
6858}
6859
6860extern "C" {
6861
6862void clang_annotateTokens(CXTranslationUnit TU,
6863 CXToken *Tokens, unsigned NumTokens,
6864 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006865 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006866 LOG_BAD_TU(TU);
6867 return;
6868 }
6869 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006870 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006871 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006872 }
6873
6874 LOG_FUNC_SECTION {
6875 *Log << TU << ' ';
6876 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6877 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6878 *Log << clang_getRange(bloc, eloc);
6879 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006880
6881 // Any token we don't specifically annotate will have a NULL cursor.
6882 CXCursor C = clang_getNullCursor();
6883 for (unsigned I = 0; I != NumTokens; ++I)
6884 Cursors[I] = C;
6885
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006886 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006887 if (!CXXUnit)
6888 return;
6889
6890 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006891
6892 auto AnnotateTokensImpl = [=]() {
6893 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6894 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006895 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006896 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006897 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6898 }
6899}
6900
6901} // end: extern "C"
6902
6903//===----------------------------------------------------------------------===//
6904// Operations for querying linkage of a cursor.
6905//===----------------------------------------------------------------------===//
6906
6907extern "C" {
6908CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6909 if (!clang_isDeclaration(cursor.kind))
6910 return CXLinkage_Invalid;
6911
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006912 const Decl *D = cxcursor::getCursorDecl(cursor);
6913 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006914 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006915 case NoLinkage:
6916 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006917 case InternalLinkage: return CXLinkage_Internal;
6918 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6919 case ExternalLinkage: return CXLinkage_External;
6920 };
6921
6922 return CXLinkage_Invalid;
6923}
6924} // end: extern "C"
6925
6926//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006927// Operations for querying visibility of a cursor.
6928//===----------------------------------------------------------------------===//
6929
6930extern "C" {
6931CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6932 if (!clang_isDeclaration(cursor.kind))
6933 return CXVisibility_Invalid;
6934
6935 const Decl *D = cxcursor::getCursorDecl(cursor);
6936 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6937 switch (ND->getVisibility()) {
6938 case HiddenVisibility: return CXVisibility_Hidden;
6939 case ProtectedVisibility: return CXVisibility_Protected;
6940 case DefaultVisibility: return CXVisibility_Default;
6941 };
6942
6943 return CXVisibility_Invalid;
6944}
6945} // end: extern "C"
6946
6947//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006948// Operations for querying language of a cursor.
6949//===----------------------------------------------------------------------===//
6950
6951static CXLanguageKind getDeclLanguage(const Decl *D) {
6952 if (!D)
6953 return CXLanguage_C;
6954
6955 switch (D->getKind()) {
6956 default:
6957 break;
6958 case Decl::ImplicitParam:
6959 case Decl::ObjCAtDefsField:
6960 case Decl::ObjCCategory:
6961 case Decl::ObjCCategoryImpl:
6962 case Decl::ObjCCompatibleAlias:
6963 case Decl::ObjCImplementation:
6964 case Decl::ObjCInterface:
6965 case Decl::ObjCIvar:
6966 case Decl::ObjCMethod:
6967 case Decl::ObjCProperty:
6968 case Decl::ObjCPropertyImpl:
6969 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006970 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006971 return CXLanguage_ObjC;
6972 case Decl::CXXConstructor:
6973 case Decl::CXXConversion:
6974 case Decl::CXXDestructor:
6975 case Decl::CXXMethod:
6976 case Decl::CXXRecord:
6977 case Decl::ClassTemplate:
6978 case Decl::ClassTemplatePartialSpecialization:
6979 case Decl::ClassTemplateSpecialization:
6980 case Decl::Friend:
6981 case Decl::FriendTemplate:
6982 case Decl::FunctionTemplate:
6983 case Decl::LinkageSpec:
6984 case Decl::Namespace:
6985 case Decl::NamespaceAlias:
6986 case Decl::NonTypeTemplateParm:
6987 case Decl::StaticAssert:
6988 case Decl::TemplateTemplateParm:
6989 case Decl::TemplateTypeParm:
6990 case Decl::UnresolvedUsingTypename:
6991 case Decl::UnresolvedUsingValue:
6992 case Decl::Using:
6993 case Decl::UsingDirective:
6994 case Decl::UsingShadow:
6995 return CXLanguage_CPlusPlus;
6996 }
6997
6998 return CXLanguage_C;
6999}
7000
7001extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007002
7003static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7004 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007005 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00007006
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007007 switch (D->getAvailability()) {
7008 case AR_Available:
7009 case AR_NotYetIntroduced:
7010 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007011 return getCursorAvailabilityForDecl(
7012 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007013 return CXAvailability_Available;
7014
7015 case AR_Deprecated:
7016 return CXAvailability_Deprecated;
7017
7018 case AR_Unavailable:
7019 return CXAvailability_NotAvailable;
7020 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007021
7022 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007023}
7024
Guy Benyei11169dd2012-12-18 14:30:41 +00007025enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7026 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007027 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7028 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007029
7030 return CXAvailability_Available;
7031}
7032
7033static CXVersion convertVersion(VersionTuple In) {
7034 CXVersion Out = { -1, -1, -1 };
7035 if (In.empty())
7036 return Out;
7037
7038 Out.Major = In.getMajor();
7039
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007040 Optional<unsigned> Minor = In.getMinor();
7041 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007042 Out.Minor = *Minor;
7043 else
7044 return Out;
7045
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007046 Optional<unsigned> Subminor = In.getSubminor();
7047 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007048 Out.Subminor = *Subminor;
7049
7050 return Out;
7051}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007052
7053static int getCursorPlatformAvailabilityForDecl(const Decl *D,
7054 int *always_deprecated,
7055 CXString *deprecated_message,
7056 int *always_unavailable,
7057 CXString *unavailable_message,
7058 CXPlatformAvailability *availability,
7059 int availability_size) {
7060 bool HadAvailAttr = false;
7061 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007062 for (auto A : D->attrs()) {
7063 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007064 HadAvailAttr = true;
7065 if (always_deprecated)
7066 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007067 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007068 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007069 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007070 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007071 continue;
7072 }
7073
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007074 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007075 HadAvailAttr = true;
7076 if (always_unavailable)
7077 *always_unavailable = 1;
7078 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007079 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007080 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7081 }
7082 continue;
7083 }
7084
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007085 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007086 HadAvailAttr = true;
7087 if (N < availability_size) {
7088 availability[N].Platform
7089 = cxstring::createDup(Avail->getPlatform()->getName());
7090 availability[N].Introduced = convertVersion(Avail->getIntroduced());
7091 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7092 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7093 availability[N].Unavailable = Avail->getUnavailable();
7094 availability[N].Message = cxstring::createDup(Avail->getMessage());
7095 }
7096 ++N;
7097 }
7098 }
7099
7100 if (!HadAvailAttr)
7101 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7102 return getCursorPlatformAvailabilityForDecl(
7103 cast<Decl>(EnumConst->getDeclContext()),
7104 always_deprecated,
7105 deprecated_message,
7106 always_unavailable,
7107 unavailable_message,
7108 availability,
7109 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007110
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007111 return N;
7112}
7113
Guy Benyei11169dd2012-12-18 14:30:41 +00007114int clang_getCursorPlatformAvailability(CXCursor cursor,
7115 int *always_deprecated,
7116 CXString *deprecated_message,
7117 int *always_unavailable,
7118 CXString *unavailable_message,
7119 CXPlatformAvailability *availability,
7120 int availability_size) {
7121 if (always_deprecated)
7122 *always_deprecated = 0;
7123 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007124 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007125 if (always_unavailable)
7126 *always_unavailable = 0;
7127 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007128 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007129
Guy Benyei11169dd2012-12-18 14:30:41 +00007130 if (!clang_isDeclaration(cursor.kind))
7131 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007132
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007133 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007134 if (!D)
7135 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007136
7137 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7138 deprecated_message,
7139 always_unavailable,
7140 unavailable_message,
7141 availability,
7142 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007143}
7144
7145void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7146 clang_disposeString(availability->Platform);
7147 clang_disposeString(availability->Message);
7148}
7149
7150CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7151 if (clang_isDeclaration(cursor.kind))
7152 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7153
7154 return CXLanguage_Invalid;
7155}
7156
7157 /// \brief If the given cursor is the "templated" declaration
7158 /// descibing a class or function template, return the class or
7159 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007160static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007161 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007162 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007163
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007164 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007165 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7166 return FunTmpl;
7167
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007168 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007169 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7170 return ClassTmpl;
7171
7172 return D;
7173}
7174
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007175
7176enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7177 StorageClass sc = SC_None;
7178 const Decl *D = getCursorDecl(C);
7179 if (D) {
7180 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7181 sc = FD->getStorageClass();
7182 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7183 sc = VD->getStorageClass();
7184 } else {
7185 return CX_SC_Invalid;
7186 }
7187 } else {
7188 return CX_SC_Invalid;
7189 }
7190 switch (sc) {
7191 case SC_None:
7192 return CX_SC_None;
7193 case SC_Extern:
7194 return CX_SC_Extern;
7195 case SC_Static:
7196 return CX_SC_Static;
7197 case SC_PrivateExtern:
7198 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007199 case SC_Auto:
7200 return CX_SC_Auto;
7201 case SC_Register:
7202 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007203 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007204 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007205}
7206
Guy Benyei11169dd2012-12-18 14:30:41 +00007207CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7208 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007209 if (const Decl *D = getCursorDecl(cursor)) {
7210 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007211 if (!DC)
7212 return clang_getNullCursor();
7213
7214 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7215 getCursorTU(cursor));
7216 }
7217 }
7218
7219 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007220 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007221 return MakeCXCursor(D, getCursorTU(cursor));
7222 }
7223
7224 return clang_getNullCursor();
7225}
7226
7227CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7228 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007229 if (const Decl *D = getCursorDecl(cursor)) {
7230 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007231 if (!DC)
7232 return clang_getNullCursor();
7233
7234 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7235 getCursorTU(cursor));
7236 }
7237 }
7238
7239 // FIXME: Note that we can't easily compute the lexical context of a
7240 // statement or expression, so we return nothing.
7241 return clang_getNullCursor();
7242}
7243
7244CXFile clang_getIncludedFile(CXCursor cursor) {
7245 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007246 return nullptr;
7247
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007248 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007249 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007250}
7251
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007252unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7253 if (C.kind != CXCursor_ObjCPropertyDecl)
7254 return CXObjCPropertyAttr_noattr;
7255
7256 unsigned Result = CXObjCPropertyAttr_noattr;
7257 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7258 ObjCPropertyDecl::PropertyAttributeKind Attr =
7259 PD->getPropertyAttributesAsWritten();
7260
7261#define SET_CXOBJCPROP_ATTR(A) \
7262 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7263 Result |= CXObjCPropertyAttr_##A
7264 SET_CXOBJCPROP_ATTR(readonly);
7265 SET_CXOBJCPROP_ATTR(getter);
7266 SET_CXOBJCPROP_ATTR(assign);
7267 SET_CXOBJCPROP_ATTR(readwrite);
7268 SET_CXOBJCPROP_ATTR(retain);
7269 SET_CXOBJCPROP_ATTR(copy);
7270 SET_CXOBJCPROP_ATTR(nonatomic);
7271 SET_CXOBJCPROP_ATTR(setter);
7272 SET_CXOBJCPROP_ATTR(atomic);
7273 SET_CXOBJCPROP_ATTR(weak);
7274 SET_CXOBJCPROP_ATTR(strong);
7275 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7276#undef SET_CXOBJCPROP_ATTR
7277
7278 return Result;
7279}
7280
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007281unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7282 if (!clang_isDeclaration(C.kind))
7283 return CXObjCDeclQualifier_None;
7284
7285 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7286 const Decl *D = getCursorDecl(C);
7287 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7288 QT = MD->getObjCDeclQualifier();
7289 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7290 QT = PD->getObjCDeclQualifier();
7291 if (QT == Decl::OBJC_TQ_None)
7292 return CXObjCDeclQualifier_None;
7293
7294 unsigned Result = CXObjCDeclQualifier_None;
7295 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7296 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7297 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7298 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7299 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7300 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7301
7302 return Result;
7303}
7304
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007305unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7306 if (!clang_isDeclaration(C.kind))
7307 return 0;
7308
7309 const Decl *D = getCursorDecl(C);
7310 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7311 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7312 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7313 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7314
7315 return 0;
7316}
7317
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007318unsigned clang_Cursor_isVariadic(CXCursor C) {
7319 if (!clang_isDeclaration(C.kind))
7320 return 0;
7321
7322 const Decl *D = getCursorDecl(C);
7323 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7324 return FD->isVariadic();
7325 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7326 return MD->isVariadic();
7327
7328 return 0;
7329}
7330
Guy Benyei11169dd2012-12-18 14:30:41 +00007331CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7332 if (!clang_isDeclaration(C.kind))
7333 return clang_getNullRange();
7334
7335 const Decl *D = getCursorDecl(C);
7336 ASTContext &Context = getCursorContext(C);
7337 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7338 if (!RC)
7339 return clang_getNullRange();
7340
7341 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7342}
7343
7344CXString clang_Cursor_getRawCommentText(CXCursor C) {
7345 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007346 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007347
7348 const Decl *D = getCursorDecl(C);
7349 ASTContext &Context = getCursorContext(C);
7350 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7351 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7352 StringRef();
7353
7354 // Don't duplicate the string because RawText points directly into source
7355 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007356 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007357}
7358
7359CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7360 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007361 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007362
7363 const Decl *D = getCursorDecl(C);
7364 const ASTContext &Context = getCursorContext(C);
7365 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7366
7367 if (RC) {
7368 StringRef BriefText = RC->getBriefText(Context);
7369
7370 // Don't duplicate the string because RawComment ensures that this memory
7371 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007372 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007373 }
7374
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007375 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007376}
7377
Guy Benyei11169dd2012-12-18 14:30:41 +00007378CXModule clang_Cursor_getModule(CXCursor C) {
7379 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007380 if (const ImportDecl *ImportD =
7381 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007382 return ImportD->getImportedModule();
7383 }
7384
Craig Topper69186e72014-06-08 08:38:04 +00007385 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007386}
7387
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007388CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7389 if (isNotUsableTU(TU)) {
7390 LOG_BAD_TU(TU);
7391 return nullptr;
7392 }
7393 if (!File)
7394 return nullptr;
7395 FileEntry *FE = static_cast<FileEntry *>(File);
7396
7397 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7398 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7399 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7400
Richard Smithfeb54b62014-10-23 02:01:19 +00007401 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007402}
7403
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007404CXFile clang_Module_getASTFile(CXModule CXMod) {
7405 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007406 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007407 Module *Mod = static_cast<Module*>(CXMod);
7408 return const_cast<FileEntry *>(Mod->getASTFile());
7409}
7410
Guy Benyei11169dd2012-12-18 14:30:41 +00007411CXModule clang_Module_getParent(CXModule CXMod) {
7412 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007413 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007414 Module *Mod = static_cast<Module*>(CXMod);
7415 return Mod->Parent;
7416}
7417
7418CXString clang_Module_getName(CXModule CXMod) {
7419 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007420 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007421 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007422 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007423}
7424
7425CXString clang_Module_getFullName(CXModule CXMod) {
7426 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007427 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007428 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007429 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007430}
7431
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007432int clang_Module_isSystem(CXModule CXMod) {
7433 if (!CXMod)
7434 return 0;
7435 Module *Mod = static_cast<Module*>(CXMod);
7436 return Mod->IsSystem;
7437}
7438
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007439unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7440 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007441 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007442 LOG_BAD_TU(TU);
7443 return 0;
7444 }
7445 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007446 return 0;
7447 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007448 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7449 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7450 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007451}
7452
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007453CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7454 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007455 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007456 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007457 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007458 }
7459 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007460 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007461 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007462 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007463
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007464 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7465 if (Index < TopHeaders.size())
7466 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007467
Craig Topper69186e72014-06-08 08:38:04 +00007468 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007469}
7470
7471} // end: extern "C"
7472
7473//===----------------------------------------------------------------------===//
7474// C++ AST instrospection.
7475//===----------------------------------------------------------------------===//
7476
7477extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007478unsigned clang_CXXField_isMutable(CXCursor C) {
7479 if (!clang_isDeclaration(C.kind))
7480 return 0;
7481
7482 if (const auto D = cxcursor::getCursorDecl(C))
7483 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7484 return FD->isMutable() ? 1 : 0;
7485 return 0;
7486}
7487
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007488unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7489 if (!clang_isDeclaration(C.kind))
7490 return 0;
7491
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007492 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007493 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007494 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007495 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7496}
7497
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007498unsigned clang_CXXMethod_isConst(CXCursor C) {
7499 if (!clang_isDeclaration(C.kind))
7500 return 0;
7501
7502 const Decl *D = cxcursor::getCursorDecl(C);
7503 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007504 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007505 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7506}
7507
Guy Benyei11169dd2012-12-18 14:30:41 +00007508unsigned clang_CXXMethod_isStatic(CXCursor C) {
7509 if (!clang_isDeclaration(C.kind))
7510 return 0;
7511
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007512 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007513 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007514 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007515 return (Method && Method->isStatic()) ? 1 : 0;
7516}
7517
7518unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7519 if (!clang_isDeclaration(C.kind))
7520 return 0;
7521
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007522 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007523 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007524 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007525 return (Method && Method->isVirtual()) ? 1 : 0;
7526}
7527} // end: extern "C"
7528
7529//===----------------------------------------------------------------------===//
7530// Attribute introspection.
7531//===----------------------------------------------------------------------===//
7532
7533extern "C" {
7534CXType clang_getIBOutletCollectionType(CXCursor C) {
7535 if (C.kind != CXCursor_IBOutletCollectionAttr)
7536 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7537
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007538 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007539 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7540
7541 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7542}
7543} // end: extern "C"
7544
7545//===----------------------------------------------------------------------===//
7546// Inspecting memory usage.
7547//===----------------------------------------------------------------------===//
7548
7549typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7550
7551static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7552 enum CXTUResourceUsageKind k,
7553 unsigned long amount) {
7554 CXTUResourceUsageEntry entry = { k, amount };
7555 entries.push_back(entry);
7556}
7557
7558extern "C" {
7559
7560const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7561 const char *str = "";
7562 switch (kind) {
7563 case CXTUResourceUsage_AST:
7564 str = "ASTContext: expressions, declarations, and types";
7565 break;
7566 case CXTUResourceUsage_Identifiers:
7567 str = "ASTContext: identifiers";
7568 break;
7569 case CXTUResourceUsage_Selectors:
7570 str = "ASTContext: selectors";
7571 break;
7572 case CXTUResourceUsage_GlobalCompletionResults:
7573 str = "Code completion: cached global results";
7574 break;
7575 case CXTUResourceUsage_SourceManagerContentCache:
7576 str = "SourceManager: content cache allocator";
7577 break;
7578 case CXTUResourceUsage_AST_SideTables:
7579 str = "ASTContext: side tables";
7580 break;
7581 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7582 str = "SourceManager: malloc'ed memory buffers";
7583 break;
7584 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7585 str = "SourceManager: mmap'ed memory buffers";
7586 break;
7587 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7588 str = "ExternalASTSource: malloc'ed memory buffers";
7589 break;
7590 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7591 str = "ExternalASTSource: mmap'ed memory buffers";
7592 break;
7593 case CXTUResourceUsage_Preprocessor:
7594 str = "Preprocessor: malloc'ed memory";
7595 break;
7596 case CXTUResourceUsage_PreprocessingRecord:
7597 str = "Preprocessor: PreprocessingRecord";
7598 break;
7599 case CXTUResourceUsage_SourceManager_DataStructures:
7600 str = "SourceManager: data structures and tables";
7601 break;
7602 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7603 str = "Preprocessor: header search tables";
7604 break;
7605 }
7606 return str;
7607}
7608
7609CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007610 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007611 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007612 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007613 return usage;
7614 }
7615
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007616 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007617 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007618 ASTContext &astContext = astUnit->getASTContext();
7619
7620 // How much memory is used by AST nodes and types?
7621 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7622 (unsigned long) astContext.getASTAllocatedMemory());
7623
7624 // How much memory is used by identifiers?
7625 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7626 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7627
7628 // How much memory is used for selectors?
7629 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7630 (unsigned long) astContext.Selectors.getTotalMemory());
7631
7632 // How much memory is used by ASTContext's side tables?
7633 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7634 (unsigned long) astContext.getSideTableAllocatedMemory());
7635
7636 // How much memory is used for caching global code completion results?
7637 unsigned long completionBytes = 0;
7638 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007639 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007640 completionBytes = completionAllocator->getTotalMemory();
7641 }
7642 createCXTUResourceUsageEntry(*entries,
7643 CXTUResourceUsage_GlobalCompletionResults,
7644 completionBytes);
7645
7646 // How much memory is being used by SourceManager's content cache?
7647 createCXTUResourceUsageEntry(*entries,
7648 CXTUResourceUsage_SourceManagerContentCache,
7649 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7650
7651 // How much memory is being used by the MemoryBuffer's in SourceManager?
7652 const SourceManager::MemoryBufferSizes &srcBufs =
7653 astUnit->getSourceManager().getMemoryBufferSizes();
7654
7655 createCXTUResourceUsageEntry(*entries,
7656 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7657 (unsigned long) srcBufs.malloc_bytes);
7658 createCXTUResourceUsageEntry(*entries,
7659 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7660 (unsigned long) srcBufs.mmap_bytes);
7661 createCXTUResourceUsageEntry(*entries,
7662 CXTUResourceUsage_SourceManager_DataStructures,
7663 (unsigned long) astContext.getSourceManager()
7664 .getDataStructureSizes());
7665
7666 // How much memory is being used by the ExternalASTSource?
7667 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7668 const ExternalASTSource::MemoryBufferSizes &sizes =
7669 esrc->getMemoryBufferSizes();
7670
7671 createCXTUResourceUsageEntry(*entries,
7672 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7673 (unsigned long) sizes.malloc_bytes);
7674 createCXTUResourceUsageEntry(*entries,
7675 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7676 (unsigned long) sizes.mmap_bytes);
7677 }
7678
7679 // How much memory is being used by the Preprocessor?
7680 Preprocessor &pp = astUnit->getPreprocessor();
7681 createCXTUResourceUsageEntry(*entries,
7682 CXTUResourceUsage_Preprocessor,
7683 pp.getTotalMemory());
7684
7685 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7686 createCXTUResourceUsageEntry(*entries,
7687 CXTUResourceUsage_PreprocessingRecord,
7688 pRec->getTotalMemory());
7689 }
7690
7691 createCXTUResourceUsageEntry(*entries,
7692 CXTUResourceUsage_Preprocessor_HeaderSearch,
7693 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007694
Guy Benyei11169dd2012-12-18 14:30:41 +00007695 CXTUResourceUsage usage = { (void*) entries.get(),
7696 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007697 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007698 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007699 return usage;
7700}
7701
7702void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7703 if (usage.data)
7704 delete (MemUsageEntries*) usage.data;
7705}
7706
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007707CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7708 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007709 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007710 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007711
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007712 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007713 LOG_BAD_TU(TU);
7714 return skipped;
7715 }
7716
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007717 if (!file)
7718 return skipped;
7719
7720 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7721 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7722 if (!ppRec)
7723 return skipped;
7724
7725 ASTContext &Ctx = astUnit->getASTContext();
7726 SourceManager &sm = Ctx.getSourceManager();
7727 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7728 FileID wantedFileID = sm.translateFile(fileEntry);
7729
7730 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7731 std::vector<SourceRange> wantedRanges;
7732 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7733 i != ei; ++i) {
7734 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7735 wantedRanges.push_back(*i);
7736 }
7737
7738 skipped->count = wantedRanges.size();
7739 skipped->ranges = new CXSourceRange[skipped->count];
7740 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7741 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7742
7743 return skipped;
7744}
7745
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007746void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7747 if (ranges) {
7748 delete[] ranges->ranges;
7749 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007750 }
7751}
7752
Guy Benyei11169dd2012-12-18 14:30:41 +00007753} // end extern "C"
7754
7755void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7756 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7757 for (unsigned I = 0; I != Usage.numEntries; ++I)
7758 fprintf(stderr, " %s: %lu\n",
7759 clang_getTUResourceUsageName(Usage.entries[I].kind),
7760 Usage.entries[I].amount);
7761
7762 clang_disposeCXTUResourceUsage(Usage);
7763}
7764
7765//===----------------------------------------------------------------------===//
7766// Misc. utility functions.
7767//===----------------------------------------------------------------------===//
7768
7769/// Default to using an 8 MB stack size on "safety" threads.
7770static unsigned SafetyStackThreadSize = 8 << 20;
7771
7772namespace clang {
7773
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007774bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007775 unsigned Size) {
7776 if (!Size)
7777 Size = GetSafetyThreadStackSize();
7778 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007779 return CRC.RunSafelyOnThread(Fn, Size);
7780 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007781}
7782
7783unsigned GetSafetyThreadStackSize() {
7784 return SafetyStackThreadSize;
7785}
7786
7787void SetSafetyThreadStackSize(unsigned Value) {
7788 SafetyStackThreadSize = Value;
7789}
7790
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007791}
Guy Benyei11169dd2012-12-18 14:30:41 +00007792
7793void clang::setThreadBackgroundPriority() {
7794 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7795 return;
7796
Alp Toker1a86ad22014-07-06 06:24:00 +00007797#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007798 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7799#endif
7800}
7801
7802void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7803 if (!Unit)
7804 return;
7805
7806 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7807 DEnd = Unit->stored_diag_end();
7808 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007809 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007810 CXString Msg = clang_formatDiagnostic(&Diag,
7811 clang_defaultDiagnosticDisplayOptions());
7812 fprintf(stderr, "%s\n", clang_getCString(Msg));
7813 clang_disposeString(Msg);
7814 }
7815#ifdef LLVM_ON_WIN32
7816 // On Windows, force a flush, since there may be multiple copies of
7817 // stderr and stdout in the file system, all with different buffers
7818 // but writing to the same device.
7819 fflush(stderr);
7820#endif
7821}
7822
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007823MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7824 SourceLocation MacroDefLoc,
7825 CXTranslationUnit TU){
7826 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007827 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007828 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007829 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007830
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007831 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007832 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007833 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007834 if (MD) {
7835 for (MacroDirective::DefInfo
7836 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7837 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7838 return Def.getMacroInfo();
7839 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007840 }
7841
Craig Topper69186e72014-06-08 08:38:04 +00007842 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007843}
7844
Richard Smith66a81862015-05-04 02:25:31 +00007845const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007846 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007847 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007848 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007849 const IdentifierInfo *II = MacroDef->getName();
7850 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007851 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007852
7853 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7854}
7855
Richard Smith66a81862015-05-04 02:25:31 +00007856MacroDefinitionRecord *
7857cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7858 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007859 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007860 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007861 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007862 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007863
7864 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007865 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007866 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7867 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007868 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007869
7870 // Check that the token is inside the definition and not its argument list.
7871 SourceManager &SM = Unit->getSourceManager();
7872 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007873 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007874 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007875 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007876
7877 Preprocessor &PP = Unit->getPreprocessor();
7878 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7879 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007880 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007881
Alp Toker2d57cea2014-05-17 04:53:25 +00007882 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007883 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007884 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007885
7886 // Check that the identifier is not one of the macro arguments.
7887 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007888 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007889
Richard Smith20e883e2015-04-29 23:20:19 +00007890 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007891 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007892 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007893
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007894 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007895}
7896
Richard Smith66a81862015-05-04 02:25:31 +00007897MacroDefinitionRecord *
7898cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7899 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007900 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007901 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007902
7903 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007904 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007905 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007906 Preprocessor &PP = Unit->getPreprocessor();
7907 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007908 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007909 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7910 Token Tok;
7911 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007912 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007913
7914 return checkForMacroInMacroDefinition(MI, Tok, TU);
7915}
7916
Guy Benyei11169dd2012-12-18 14:30:41 +00007917extern "C" {
7918
7919CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007920 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007921}
7922
7923} // end: extern "C"
7924
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007925Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7926 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007927 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007928 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007929 if (Unit->isMainFileAST())
7930 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007931 return *this;
7932 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007933 } else {
7934 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007935 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007936 return *this;
7937}
7938
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007939Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7940 *this << FE->getName();
7941 return *this;
7942}
7943
7944Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7945 CXString cursorName = clang_getCursorDisplayName(cursor);
7946 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7947 clang_disposeString(cursorName);
7948 return *this;
7949}
7950
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007951Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7952 CXFile File;
7953 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007954 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007955 CXString FileName = clang_getFileName(File);
7956 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7957 clang_disposeString(FileName);
7958 return *this;
7959}
7960
7961Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7962 CXSourceLocation BLoc = clang_getRangeStart(range);
7963 CXSourceLocation ELoc = clang_getRangeEnd(range);
7964
7965 CXFile BFile;
7966 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007967 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007968
7969 CXFile EFile;
7970 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007971 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007972
7973 CXString BFileName = clang_getFileName(BFile);
7974 if (BFile == EFile) {
7975 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7976 BLine, BColumn, ELine, EColumn);
7977 } else {
7978 CXString EFileName = clang_getFileName(EFile);
7979 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7980 BLine, BColumn)
7981 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7982 ELine, EColumn);
7983 clang_disposeString(EFileName);
7984 }
7985 clang_disposeString(BFileName);
7986 return *this;
7987}
7988
7989Logger &cxindex::Logger::operator<<(CXString Str) {
7990 *this << clang_getCString(Str);
7991 return *this;
7992}
7993
7994Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7995 LogOS << Fmt;
7996 return *this;
7997}
7998
Chandler Carruth37ad2582014-06-27 15:14:39 +00007999static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
8000
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008001cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00008002 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008003
8004 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
8005
Dmitri Gribenkof8579502013-01-12 19:30:44 +00008006 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008007 OS << "[libclang:" << Name << ':';
8008
Alp Toker1a86ad22014-07-06 06:24:00 +00008009#ifdef USE_DARWIN_THREADS
8010 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008011 mach_port_t tid = pthread_mach_thread_np(pthread_self());
8012 OS << tid << ':';
8013#endif
8014
8015 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
8016 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00008017 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008018
8019 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00008020 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008021 OS << "--------------------------------------------------\n";
8022 }
8023}