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