blob: 5462e94f28224c60b24d572398c7924b5f548bed [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000056#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000057#include "llvm/Support/Threading.h"
58#include "llvm/Support/Timer.h"
59#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000060
Alp Toker1a86ad22014-07-06 06:24:00 +000061#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
62#define USE_DARWIN_THREADS
63#endif
64
65#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000066#include <pthread.h>
67#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000068
69using namespace clang;
70using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000071using namespace clang::cxtu;
72using namespace clang::cxindex;
73
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000074CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
75 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000076 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000077 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000078 CXTranslationUnit D = new CXTranslationUnitImpl();
79 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000080 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000081 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000082 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000083 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000084 D->CommentToXML = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000085 return D;
86}
87
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000088bool cxtu::isASTReadError(ASTUnit *AU) {
89 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
90 DEnd = AU->stored_diag_end();
91 D != DEnd; ++D) {
92 if (D->getLevel() >= DiagnosticsEngine::Error &&
93 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
94 diag::DiagCat_AST_Deserialization_Issue)
95 return true;
96 }
97 return false;
98}
99
Guy Benyei11169dd2012-12-18 14:30:41 +0000100cxtu::CXTUOwner::~CXTUOwner() {
101 if (TU)
102 clang_disposeTranslationUnit(TU);
103}
104
105/// \brief Compare two source ranges to determine their relative position in
106/// the translation unit.
107static RangeComparisonResult RangeCompare(SourceManager &SM,
108 SourceRange R1,
109 SourceRange R2) {
110 assert(R1.isValid() && "First range is invalid?");
111 assert(R2.isValid() && "Second range is invalid?");
112 if (R1.getEnd() != R2.getBegin() &&
113 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
114 return RangeBefore;
115 if (R2.getEnd() != R1.getBegin() &&
116 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
117 return RangeAfter;
118 return RangeOverlap;
119}
120
121/// \brief Determine if a source location falls within, before, or after a
122/// a given source range.
123static RangeComparisonResult LocationCompare(SourceManager &SM,
124 SourceLocation L, SourceRange R) {
125 assert(R.isValid() && "First range is invalid?");
126 assert(L.isValid() && "Second range is invalid?");
127 if (L == R.getBegin() || L == R.getEnd())
128 return RangeOverlap;
129 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
130 return RangeBefore;
131 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
132 return RangeAfter;
133 return RangeOverlap;
134}
135
136/// \brief Translate a Clang source range into a CIndex source range.
137///
138/// Clang internally represents ranges where the end location points to the
139/// start of the token at the end. However, for external clients it is more
140/// useful to have a CXSourceRange be a proper half-open interval. This routine
141/// does the appropriate translation.
142CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
143 const LangOptions &LangOpts,
144 const CharSourceRange &R) {
145 // We want the last character in this location, so we will adjust the
146 // location accordingly.
147 SourceLocation EndLoc = R.getEnd();
148 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
149 EndLoc = SM.getExpansionRange(EndLoc).second;
Yaron Keren8b563662015-10-03 10:46:20 +0000150 if (R.isTokenRange() && EndLoc.isValid()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000151 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
152 SM, LangOpts);
153 EndLoc = EndLoc.getLocWithOffset(Length);
154 }
155
Bill Wendlingeade3622013-01-23 08:25:41 +0000156 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000157 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000158 R.getBegin().getRawEncoding(),
159 EndLoc.getRawEncoding()
160 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000161 return Result;
162}
163
164//===----------------------------------------------------------------------===//
165// Cursor visitor.
166//===----------------------------------------------------------------------===//
167
168static SourceRange getRawCursorExtent(CXCursor C);
169static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
170
171
172RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
173 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
174}
175
176/// \brief Visit the given cursor and, if requested by the visitor,
177/// its children.
178///
179/// \param Cursor the cursor to visit.
180///
181/// \param CheckedRegionOfInterest if true, then the caller already checked
182/// that this cursor is within the region of interest.
183///
184/// \returns true if the visitation should be aborted, false if it
185/// should continue.
186bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
187 if (clang_isInvalid(Cursor.kind))
188 return false;
189
190 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000191 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000192 if (!D) {
193 assert(0 && "Invalid declaration cursor");
194 return true; // abort.
195 }
196
197 // Ignore implicit declarations, unless it's an objc method because
198 // currently we should report implicit methods for properties when indexing.
199 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
200 return false;
201 }
202
203 // If we have a range of interest, and this cursor doesn't intersect with it,
204 // we're done.
205 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
206 SourceRange Range = getRawCursorExtent(Cursor);
207 if (Range.isInvalid() || CompareRegionOfInterest(Range))
208 return false;
209 }
210
211 switch (Visitor(Cursor, Parent, ClientData)) {
212 case CXChildVisit_Break:
213 return true;
214
215 case CXChildVisit_Continue:
216 return false;
217
218 case CXChildVisit_Recurse: {
219 bool ret = VisitChildren(Cursor);
220 if (PostChildrenVisitor)
221 if (PostChildrenVisitor(Cursor, ClientData))
222 return true;
223 return ret;
224 }
225 }
226
227 llvm_unreachable("Invalid CXChildVisitResult!");
228}
229
230static bool visitPreprocessedEntitiesInRange(SourceRange R,
231 PreprocessingRecord &PPRec,
232 CursorVisitor &Visitor) {
233 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
234 FileID FID;
235
236 if (!Visitor.shouldVisitIncludedEntities()) {
237 // If the begin/end of the range lie in the same FileID, do the optimization
238 // where we skip preprocessed entities that do not come from the same FileID.
239 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
240 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
241 FID = FileID();
242 }
243
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000244 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000458
Guy Benyei11169dd2012-12-18 14:30:41 +0000459 continue;
460 }
Richard Smith66a81862015-05-04 02:25:31 +0000461
462 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000465
Guy Benyei11169dd2012-12-18 14:30:41 +0000466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000572 if (MacroDefinitionRecord *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000667bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
668 if (VisitTemplateParameters(D->getTemplateParameters()))
669 return true;
670
671 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
672}
673
Guy Benyei11169dd2012-12-18 14:30:41 +0000674bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
682 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
683 return Visit(TSInfo->getTypeLoc());
684
685 return false;
686}
687
688bool CursorVisitor::VisitTagDecl(TagDecl *D) {
689 return VisitDeclContext(D);
690}
691
692bool CursorVisitor::VisitClassTemplateSpecializationDecl(
693 ClassTemplateSpecializationDecl *D) {
694 bool ShouldVisitBody = false;
695 switch (D->getSpecializationKind()) {
696 case TSK_Undeclared:
697 case TSK_ImplicitInstantiation:
698 // Nothing to visit
699 return false;
700
701 case TSK_ExplicitInstantiationDeclaration:
702 case TSK_ExplicitInstantiationDefinition:
703 break;
704
705 case TSK_ExplicitSpecialization:
706 ShouldVisitBody = true;
707 break;
708 }
709
710 // Visit the template arguments used in the specialization.
711 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
712 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000713 if (TemplateSpecializationTypeLoc TSTLoc =
714 TL.getAs<TemplateSpecializationTypeLoc>()) {
715 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
716 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000717 return true;
718 }
719 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000720
721 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000722}
723
724bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
725 ClassTemplatePartialSpecializationDecl *D) {
726 // FIXME: Visit the "outer" template parameter lists on the TagDecl
727 // before visiting these template parameters.
728 if (VisitTemplateParameters(D->getTemplateParameters()))
729 return true;
730
731 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000732 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
733 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
734 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000735 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
736 return true;
737
738 return VisitCXXRecordDecl(D);
739}
740
741bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
742 // Visit the default argument.
743 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
744 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
745 if (Visit(DefArg->getTypeLoc()))
746 return true;
747
748 return false;
749}
750
751bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
752 if (Expr *Init = D->getInitExpr())
753 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
754 return false;
755}
756
757bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000758 unsigned NumParamList = DD->getNumTemplateParameterLists();
759 for (unsigned i = 0; i < NumParamList; i++) {
760 TemplateParameterList* Params = DD->getTemplateParameterList(i);
761 if (VisitTemplateParameters(Params))
762 return true;
763 }
764
Guy Benyei11169dd2012-12-18 14:30:41 +0000765 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
766 if (Visit(TSInfo->getTypeLoc()))
767 return true;
768
769 // Visit the nested-name-specifier, if present.
770 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
771 if (VisitNestedNameSpecifierLoc(QualifierLoc))
772 return true;
773
774 return false;
775}
776
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000777/// \brief Compare two base or member initializers based on their source order.
778static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
779 CXXCtorInitializer *const *Y) {
780 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
781}
782
Guy Benyei11169dd2012-12-18 14:30:41 +0000783bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000784 unsigned NumParamList = ND->getNumTemplateParameterLists();
785 for (unsigned i = 0; i < NumParamList; i++) {
786 TemplateParameterList* Params = ND->getTemplateParameterList(i);
787 if (VisitTemplateParameters(Params))
788 return true;
789 }
790
Guy Benyei11169dd2012-12-18 14:30:41 +0000791 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
792 // Visit the function declaration's syntactic components in the order
793 // written. This requires a bit of work.
794 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000795 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000796
797 // If we have a function declared directly (without the use of a typedef),
798 // visit just the return type. Otherwise, just visit the function's type
799 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000800 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000801 (!FTL && Visit(TL)))
802 return true;
803
804 // Visit the nested-name-specifier, if present.
805 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
806 if (VisitNestedNameSpecifierLoc(QualifierLoc))
807 return true;
808
809 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000810 if (!isa<CXXDestructorDecl>(ND))
811 if (VisitDeclarationNameInfo(ND->getNameInfo()))
812 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000813
814 // FIXME: Visit explicitly-specified template arguments!
815
816 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000817 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000818 return true;
819
Bill Wendling44426052012-12-20 19:22:21 +0000820 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 }
822
823 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
824 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
825 // Find the initializers that were written in the source.
826 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 for (auto *I : Constructor->inits()) {
828 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000829 continue;
830
Aaron Ballman0ad78302014-03-13 17:34:31 +0000831 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000832 }
833
834 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000835 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
836 &CompareCXXCtorInitializers);
837
Guy Benyei11169dd2012-12-18 14:30:41 +0000838 // Visit the initializers in source order
839 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
840 CXXCtorInitializer *Init = WrittenInits[I];
841 if (Init->isAnyMemberInitializer()) {
842 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
843 Init->getMemberLocation(), TU)))
844 return true;
845 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
846 if (Visit(TInfo->getTypeLoc()))
847 return true;
848 }
849
850 // Visit the initializer value.
851 if (Expr *Initializer = Init->getInit())
852 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
853 return true;
854 }
855 }
856
857 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
858 return true;
859 }
860
861 return false;
862}
863
864bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
865 if (VisitDeclaratorDecl(D))
866 return true;
867
868 if (Expr *BitWidth = D->getBitWidth())
869 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
870
871 return false;
872}
873
874bool CursorVisitor::VisitVarDecl(VarDecl *D) {
875 if (VisitDeclaratorDecl(D))
876 return true;
877
878 if (Expr *Init = D->getInit())
879 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
880
881 return false;
882}
883
884bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
885 if (VisitDeclaratorDecl(D))
886 return true;
887
888 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
889 if (Expr *DefArg = D->getDefaultArgument())
890 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
891
892 return false;
893}
894
895bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
896 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
897 // before visiting these template parameters.
898 if (VisitTemplateParameters(D->getTemplateParameters()))
899 return true;
900
901 return VisitFunctionDecl(D->getTemplatedDecl());
902}
903
904bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
905 // FIXME: Visit the "outer" template parameter lists on the TagDecl
906 // before visiting these template parameters.
907 if (VisitTemplateParameters(D->getTemplateParameters()))
908 return true;
909
910 return VisitCXXRecordDecl(D->getTemplatedDecl());
911}
912
913bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
914 if (VisitTemplateParameters(D->getTemplateParameters()))
915 return true;
916
917 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
918 VisitTemplateArgumentLoc(D->getDefaultArgument()))
919 return true;
920
921 return false;
922}
923
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000924bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
925 // Visit the bound, if it's explicit.
926 if (D->hasExplicitBound()) {
927 if (auto TInfo = D->getTypeSourceInfo()) {
928 if (Visit(TInfo->getTypeLoc()))
929 return true;
930 }
931 }
932
933 return false;
934}
935
Guy Benyei11169dd2012-12-18 14:30:41 +0000936bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000937 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000938 if (Visit(TSInfo->getTypeLoc()))
939 return true;
940
Aaron Ballman43b68be2014-03-07 17:50:17 +0000941 for (const auto *P : ND->params()) {
942 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000943 return true;
944 }
945
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000946 return ND->isThisDeclarationADefinition() &&
947 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000948}
949
950template <typename DeclIt>
951static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
952 SourceManager &SM, SourceLocation EndLoc,
953 SmallVectorImpl<Decl *> &Decls) {
954 DeclIt next = *DI_current;
955 while (++next != DE_current) {
956 Decl *D_next = *next;
957 if (!D_next)
958 break;
959 SourceLocation L = D_next->getLocStart();
960 if (!L.isValid())
961 break;
962 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
963 *DI_current = next;
964 Decls.push_back(D_next);
965 continue;
966 }
967 break;
968 }
969}
970
Guy Benyei11169dd2012-12-18 14:30:41 +0000971bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
972 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
973 // an @implementation can lexically contain Decls that are not properly
974 // nested in the AST. When we identify such cases, we need to retrofit
975 // this nesting here.
976 if (!DI_current && !FileDI_current)
977 return VisitDeclContext(D);
978
979 // Scan the Decls that immediately come after the container
980 // in the current DeclContext. If any fall within the
981 // container's lexical region, stash them into a vector
982 // for later processing.
983 SmallVector<Decl *, 24> DeclsInContainer;
984 SourceLocation EndLoc = D->getSourceRange().getEnd();
985 SourceManager &SM = AU->getSourceManager();
986 if (EndLoc.isValid()) {
987 if (DI_current) {
988 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
989 DeclsInContainer);
990 } else {
991 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
992 DeclsInContainer);
993 }
994 }
995
996 // The common case.
997 if (DeclsInContainer.empty())
998 return VisitDeclContext(D);
999
1000 // Get all the Decls in the DeclContext, and sort them with the
1001 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001002 for (auto *SubDecl : D->decls()) {
1003 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1004 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001005 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001006 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001007 }
1008
1009 // Now sort the Decls so that they appear in lexical order.
1010 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001011 [&SM](Decl *A, Decl *B) {
1012 SourceLocation L_A = A->getLocStart();
1013 SourceLocation L_B = B->getLocStart();
1014 assert(L_A.isValid() && L_B.isValid());
1015 return SM.isBeforeInTranslationUnit(L_A, L_B);
1016 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001017
1018 // Now visit the decls.
1019 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1020 E = DeclsInContainer.end(); I != E; ++I) {
1021 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001022 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001023 if (!V.hasValue())
1024 continue;
1025 if (!V.getValue())
1026 return false;
1027 if (Visit(Cursor, true))
1028 return true;
1029 }
1030 return false;
1031}
1032
1033bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1034 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1035 TU)))
1036 return true;
1037
Douglas Gregore9d95f12015-07-07 03:57:35 +00001038 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1039 return true;
1040
Guy Benyei11169dd2012-12-18 14:30:41 +00001041 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1042 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1043 E = ND->protocol_end(); I != E; ++I, ++PL)
1044 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1045 return true;
1046
1047 return VisitObjCContainerDecl(ND);
1048}
1049
1050bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1051 if (!PID->isThisDeclarationADefinition())
1052 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1053
1054 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1055 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1056 E = PID->protocol_end(); I != E; ++I, ++PL)
1057 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1058 return true;
1059
1060 return VisitObjCContainerDecl(PID);
1061}
1062
1063bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1064 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1065 return true;
1066
1067 // FIXME: This implements a workaround with @property declarations also being
1068 // installed in the DeclContext for the @interface. Eventually this code
1069 // should be removed.
1070 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1071 if (!CDecl || !CDecl->IsClassExtension())
1072 return false;
1073
1074 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1075 if (!ID)
1076 return false;
1077
1078 IdentifierInfo *PropertyId = PD->getIdentifier();
1079 ObjCPropertyDecl *prevDecl =
1080 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1081
1082 if (!prevDecl)
1083 return false;
1084
1085 // Visit synthesized methods since they will be skipped when visiting
1086 // the @interface.
1087 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1088 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1089 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1090 return true;
1091
1092 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1093 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1094 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1095 return true;
1096
1097 return false;
1098}
1099
Douglas Gregore9d95f12015-07-07 03:57:35 +00001100bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1101 if (!typeParamList)
1102 return false;
1103
1104 for (auto *typeParam : *typeParamList) {
1105 // Visit the type parameter.
1106 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1107 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001108 }
1109
1110 return false;
1111}
1112
Guy Benyei11169dd2012-12-18 14:30:41 +00001113bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1114 if (!D->isThisDeclarationADefinition()) {
1115 // Forward declaration is treated like a reference.
1116 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1117 }
1118
Douglas Gregore9d95f12015-07-07 03:57:35 +00001119 // Objective-C type parameters.
1120 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1121 return true;
1122
Guy Benyei11169dd2012-12-18 14:30:41 +00001123 // Issue callbacks for super class.
1124 if (D->getSuperClass() &&
1125 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1126 D->getSuperClassLoc(),
1127 TU)))
1128 return true;
1129
Douglas Gregore9d95f12015-07-07 03:57:35 +00001130 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1131 if (Visit(SuperClassTInfo->getTypeLoc()))
1132 return true;
1133
Guy Benyei11169dd2012-12-18 14:30:41 +00001134 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1135 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1136 E = D->protocol_end(); I != E; ++I, ++PL)
1137 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1138 return true;
1139
1140 return VisitObjCContainerDecl(D);
1141}
1142
1143bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1144 return VisitObjCContainerDecl(D);
1145}
1146
1147bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1148 // 'ID' could be null when dealing with invalid code.
1149 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1150 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1151 return true;
1152
1153 return VisitObjCImplDecl(D);
1154}
1155
1156bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1157#if 0
1158 // Issue callbacks for super class.
1159 // FIXME: No source location information!
1160 if (D->getSuperClass() &&
1161 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1162 D->getSuperClassLoc(),
1163 TU)))
1164 return true;
1165#endif
1166
1167 return VisitObjCImplDecl(D);
1168}
1169
1170bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1171 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1172 if (PD->isIvarNameSpecified())
1173 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1174
1175 return false;
1176}
1177
1178bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1179 return VisitDeclContext(D);
1180}
1181
1182bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1183 // Visit nested-name-specifier.
1184 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1185 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1186 return true;
1187
1188 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1189 D->getTargetNameLoc(), TU));
1190}
1191
1192bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1193 // Visit nested-name-specifier.
1194 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1195 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1196 return true;
1197 }
1198
1199 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1200 return true;
1201
1202 return VisitDeclarationNameInfo(D->getNameInfo());
1203}
1204
1205bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1206 // Visit nested-name-specifier.
1207 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1208 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1209 return true;
1210
1211 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1212 D->getIdentLocation(), TU));
1213}
1214
1215bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1216 // Visit nested-name-specifier.
1217 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1218 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1219 return true;
1220 }
1221
1222 return VisitDeclarationNameInfo(D->getNameInfo());
1223}
1224
1225bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1226 UnresolvedUsingTypenameDecl *D) {
1227 // Visit nested-name-specifier.
1228 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1229 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1230 return true;
1231
1232 return false;
1233}
1234
1235bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1236 switch (Name.getName().getNameKind()) {
1237 case clang::DeclarationName::Identifier:
1238 case clang::DeclarationName::CXXLiteralOperatorName:
1239 case clang::DeclarationName::CXXOperatorName:
1240 case clang::DeclarationName::CXXUsingDirective:
1241 return false;
1242
1243 case clang::DeclarationName::CXXConstructorName:
1244 case clang::DeclarationName::CXXDestructorName:
1245 case clang::DeclarationName::CXXConversionFunctionName:
1246 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1247 return Visit(TSInfo->getTypeLoc());
1248 return false;
1249
1250 case clang::DeclarationName::ObjCZeroArgSelector:
1251 case clang::DeclarationName::ObjCOneArgSelector:
1252 case clang::DeclarationName::ObjCMultiArgSelector:
1253 // FIXME: Per-identifier location info?
1254 return false;
1255 }
1256
1257 llvm_unreachable("Invalid DeclarationName::Kind!");
1258}
1259
1260bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1261 SourceRange Range) {
1262 // FIXME: This whole routine is a hack to work around the lack of proper
1263 // source information in nested-name-specifiers (PR5791). Since we do have
1264 // a beginning source location, we can visit the first component of the
1265 // nested-name-specifier, if it's a single-token component.
1266 if (!NNS)
1267 return false;
1268
1269 // Get the first component in the nested-name-specifier.
1270 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1271 NNS = Prefix;
1272
1273 switch (NNS->getKind()) {
1274 case NestedNameSpecifier::Namespace:
1275 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1276 TU));
1277
1278 case NestedNameSpecifier::NamespaceAlias:
1279 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1280 Range.getBegin(), TU));
1281
1282 case NestedNameSpecifier::TypeSpec: {
1283 // If the type has a form where we know that the beginning of the source
1284 // range matches up with a reference cursor. Visit the appropriate reference
1285 // cursor.
1286 const Type *T = NNS->getAsType();
1287 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1288 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1289 if (const TagType *Tag = dyn_cast<TagType>(T))
1290 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1291 if (const TemplateSpecializationType *TST
1292 = dyn_cast<TemplateSpecializationType>(T))
1293 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1294 break;
1295 }
1296
1297 case NestedNameSpecifier::TypeSpecWithTemplate:
1298 case NestedNameSpecifier::Global:
1299 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001300 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001301 break;
1302 }
1303
1304 return false;
1305}
1306
1307bool
1308CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1309 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1310 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1311 Qualifiers.push_back(Qualifier);
1312
1313 while (!Qualifiers.empty()) {
1314 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1315 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1316 switch (NNS->getKind()) {
1317 case NestedNameSpecifier::Namespace:
1318 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1319 Q.getLocalBeginLoc(),
1320 TU)))
1321 return true;
1322
1323 break;
1324
1325 case NestedNameSpecifier::NamespaceAlias:
1326 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1327 Q.getLocalBeginLoc(),
1328 TU)))
1329 return true;
1330
1331 break;
1332
1333 case NestedNameSpecifier::TypeSpec:
1334 case NestedNameSpecifier::TypeSpecWithTemplate:
1335 if (Visit(Q.getTypeLoc()))
1336 return true;
1337
1338 break;
1339
1340 case NestedNameSpecifier::Global:
1341 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001342 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001343 break;
1344 }
1345 }
1346
1347 return false;
1348}
1349
1350bool CursorVisitor::VisitTemplateParameters(
1351 const TemplateParameterList *Params) {
1352 if (!Params)
1353 return false;
1354
1355 for (TemplateParameterList::const_iterator P = Params->begin(),
1356 PEnd = Params->end();
1357 P != PEnd; ++P) {
1358 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1359 return true;
1360 }
1361
1362 return false;
1363}
1364
1365bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1366 switch (Name.getKind()) {
1367 case TemplateName::Template:
1368 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1369
1370 case TemplateName::OverloadedTemplate:
1371 // Visit the overloaded template set.
1372 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1373 return true;
1374
1375 return false;
1376
1377 case TemplateName::DependentTemplate:
1378 // FIXME: Visit nested-name-specifier.
1379 return false;
1380
1381 case TemplateName::QualifiedTemplate:
1382 // FIXME: Visit nested-name-specifier.
1383 return Visit(MakeCursorTemplateRef(
1384 Name.getAsQualifiedTemplateName()->getDecl(),
1385 Loc, TU));
1386
1387 case TemplateName::SubstTemplateTemplateParm:
1388 return Visit(MakeCursorTemplateRef(
1389 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1390 Loc, TU));
1391
1392 case TemplateName::SubstTemplateTemplateParmPack:
1393 return Visit(MakeCursorTemplateRef(
1394 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1395 Loc, TU));
1396 }
1397
1398 llvm_unreachable("Invalid TemplateName::Kind!");
1399}
1400
1401bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1402 switch (TAL.getArgument().getKind()) {
1403 case TemplateArgument::Null:
1404 case TemplateArgument::Integral:
1405 case TemplateArgument::Pack:
1406 return false;
1407
1408 case TemplateArgument::Type:
1409 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1410 return Visit(TSInfo->getTypeLoc());
1411 return false;
1412
1413 case TemplateArgument::Declaration:
1414 if (Expr *E = TAL.getSourceDeclExpression())
1415 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1416 return false;
1417
1418 case TemplateArgument::NullPtr:
1419 if (Expr *E = TAL.getSourceNullPtrExpression())
1420 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1421 return false;
1422
1423 case TemplateArgument::Expression:
1424 if (Expr *E = TAL.getSourceExpression())
1425 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1426 return false;
1427
1428 case TemplateArgument::Template:
1429 case TemplateArgument::TemplateExpansion:
1430 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1431 return true;
1432
1433 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1434 TAL.getTemplateNameLoc());
1435 }
1436
1437 llvm_unreachable("Invalid TemplateArgument::Kind!");
1438}
1439
1440bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1441 return VisitDeclContext(D);
1442}
1443
1444bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1445 return Visit(TL.getUnqualifiedLoc());
1446}
1447
1448bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1449 ASTContext &Context = AU->getASTContext();
1450
1451 // Some builtin types (such as Objective-C's "id", "sel", and
1452 // "Class") have associated declarations. Create cursors for those.
1453 QualType VisitType;
1454 switch (TL.getTypePtr()->getKind()) {
1455
1456 case BuiltinType::Void:
1457 case BuiltinType::NullPtr:
1458 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001459 case BuiltinType::OCLImage1d:
1460 case BuiltinType::OCLImage1dArray:
1461 case BuiltinType::OCLImage1dBuffer:
1462 case BuiltinType::OCLImage2d:
1463 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001464 case BuiltinType::OCLImage2dDepth:
1465 case BuiltinType::OCLImage2dArrayDepth:
1466 case BuiltinType::OCLImage2dMSAA:
1467 case BuiltinType::OCLImage2dArrayMSAA:
1468 case BuiltinType::OCLImage2dMSAADepth:
1469 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001470 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001471 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001472 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001473 case BuiltinType::OCLClkEvent:
1474 case BuiltinType::OCLQueue:
1475 case BuiltinType::OCLNDRange:
1476 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001477#define BUILTIN_TYPE(Id, SingletonId)
1478#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1479#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1480#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1481#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1482#include "clang/AST/BuiltinTypes.def"
1483 break;
1484
1485 case BuiltinType::ObjCId:
1486 VisitType = Context.getObjCIdType();
1487 break;
1488
1489 case BuiltinType::ObjCClass:
1490 VisitType = Context.getObjCClassType();
1491 break;
1492
1493 case BuiltinType::ObjCSel:
1494 VisitType = Context.getObjCSelType();
1495 break;
1496 }
1497
1498 if (!VisitType.isNull()) {
1499 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1500 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1501 TU));
1502 }
1503
1504 return false;
1505}
1506
1507bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1508 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1509}
1510
1511bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1512 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1513}
1514
1515bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1516 if (TL.isDefinition())
1517 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1518
1519 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1520}
1521
1522bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1523 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1524}
1525
1526bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001527 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001528}
1529
1530bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1531 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1532 return true;
1533
Douglas Gregore9d95f12015-07-07 03:57:35 +00001534 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1535 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1536 return true;
1537 }
1538
Guy Benyei11169dd2012-12-18 14:30:41 +00001539 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1540 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1541 TU)))
1542 return true;
1543 }
1544
1545 return false;
1546}
1547
1548bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1549 return Visit(TL.getPointeeLoc());
1550}
1551
1552bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1553 return Visit(TL.getInnerLoc());
1554}
1555
1556bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1557 return Visit(TL.getPointeeLoc());
1558}
1559
1560bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1561 return Visit(TL.getPointeeLoc());
1562}
1563
1564bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1565 return Visit(TL.getPointeeLoc());
1566}
1567
1568bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1569 return Visit(TL.getPointeeLoc());
1570}
1571
1572bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1573 return Visit(TL.getPointeeLoc());
1574}
1575
1576bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1577 return Visit(TL.getModifiedLoc());
1578}
1579
1580bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1581 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001582 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001583 return true;
1584
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001585 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1586 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001587 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1588 return true;
1589
1590 return false;
1591}
1592
1593bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1594 if (Visit(TL.getElementLoc()))
1595 return true;
1596
1597 if (Expr *Size = TL.getSizeExpr())
1598 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1599
1600 return false;
1601}
1602
Reid Kleckner8a365022013-06-24 17:51:48 +00001603bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1604 return Visit(TL.getOriginalLoc());
1605}
1606
Reid Kleckner0503a872013-12-05 01:23:43 +00001607bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1608 return Visit(TL.getOriginalLoc());
1609}
1610
Guy Benyei11169dd2012-12-18 14:30:41 +00001611bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1612 TemplateSpecializationTypeLoc TL) {
1613 // Visit the template name.
1614 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1615 TL.getTemplateNameLoc()))
1616 return true;
1617
1618 // Visit the template arguments.
1619 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1620 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1621 return true;
1622
1623 return false;
1624}
1625
1626bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1627 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1628}
1629
1630bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1631 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1632 return Visit(TSInfo->getTypeLoc());
1633
1634 return false;
1635}
1636
1637bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1638 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1639 return Visit(TSInfo->getTypeLoc());
1640
1641 return false;
1642}
1643
1644bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001645 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001646}
1647
1648bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1649 DependentTemplateSpecializationTypeLoc TL) {
1650 // Visit the nested-name-specifier, if there is one.
1651 if (TL.getQualifierLoc() &&
1652 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1653 return true;
1654
1655 // Visit the template arguments.
1656 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1657 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1658 return true;
1659
1660 return false;
1661}
1662
1663bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1664 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1665 return true;
1666
1667 return Visit(TL.getNamedTypeLoc());
1668}
1669
1670bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1671 return Visit(TL.getPatternLoc());
1672}
1673
1674bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1675 if (Expr *E = TL.getUnderlyingExpr())
1676 return Visit(MakeCXCursor(E, StmtParent, TU));
1677
1678 return false;
1679}
1680
1681bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1682 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1683}
1684
1685bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1686 return Visit(TL.getValueLoc());
1687}
1688
Xiuli Pan9c14e282016-01-09 12:53:17 +00001689bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1690 return Visit(TL.getValueLoc());
1691}
1692
Guy Benyei11169dd2012-12-18 14:30:41 +00001693#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1694bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1695 return Visit##PARENT##Loc(TL); \
1696}
1697
1698DEFAULT_TYPELOC_IMPL(Complex, Type)
1699DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1700DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1701DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1702DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1703DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1704DEFAULT_TYPELOC_IMPL(Vector, Type)
1705DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1706DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1707DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1708DEFAULT_TYPELOC_IMPL(Record, TagType)
1709DEFAULT_TYPELOC_IMPL(Enum, TagType)
1710DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1711DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1712DEFAULT_TYPELOC_IMPL(Auto, Type)
1713
1714bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1715 // Visit the nested-name-specifier, if present.
1716 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1717 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1718 return true;
1719
1720 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001721 for (const auto &I : D->bases()) {
1722 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001723 return true;
1724 }
1725 }
1726
1727 return VisitTagDecl(D);
1728}
1729
1730bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001731 for (const auto *I : D->attrs())
1732 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001733 return true;
1734
1735 return false;
1736}
1737
1738//===----------------------------------------------------------------------===//
1739// Data-recursive visitor methods.
1740//===----------------------------------------------------------------------===//
1741
1742namespace {
1743#define DEF_JOB(NAME, DATA, KIND)\
1744class NAME : public VisitorJob {\
1745public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001746 NAME(const DATA *d, CXCursor parent) : \
1747 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001748 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001749 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001750};
1751
1752DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1753DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1754DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1755DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001756DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1757DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1758DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1759#undef DEF_JOB
1760
James Y Knight04ec5bf2015-12-24 02:59:37 +00001761class ExplicitTemplateArgsVisit : public VisitorJob {
1762public:
1763 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1764 const TemplateArgumentLoc *End, CXCursor parent)
1765 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1766 End) {}
1767 static bool classof(const VisitorJob *VJ) {
1768 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1769 }
1770 const TemplateArgumentLoc *begin() const {
1771 return static_cast<const TemplateArgumentLoc *>(data[0]);
1772 }
1773 const TemplateArgumentLoc *end() {
1774 return static_cast<const TemplateArgumentLoc *>(data[1]);
1775 }
1776};
Guy Benyei11169dd2012-12-18 14:30:41 +00001777class DeclVisit : public VisitorJob {
1778public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001779 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001780 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001781 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 static bool classof(const VisitorJob *VJ) {
1783 return VJ->getKind() == DeclVisitKind;
1784 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001785 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001786 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001787};
1788class TypeLocVisit : public VisitorJob {
1789public:
1790 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1791 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1792 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1793
1794 static bool classof(const VisitorJob *VJ) {
1795 return VJ->getKind() == TypeLocVisitKind;
1796 }
1797
1798 TypeLoc get() const {
1799 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001801 }
1802};
1803
1804class LabelRefVisit : public VisitorJob {
1805public:
1806 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1807 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1808 labelLoc.getPtrEncoding()) {}
1809
1810 static bool classof(const VisitorJob *VJ) {
1811 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1812 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813 const LabelDecl *get() const {
1814 return static_cast<const LabelDecl *>(data[0]);
1815 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001816 SourceLocation getLoc() const {
1817 return SourceLocation::getFromPtrEncoding(data[1]); }
1818};
1819
1820class NestedNameSpecifierLocVisit : public VisitorJob {
1821public:
1822 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1823 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1824 Qualifier.getNestedNameSpecifier(),
1825 Qualifier.getOpaqueData()) { }
1826
1827 static bool classof(const VisitorJob *VJ) {
1828 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1829 }
1830
1831 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001832 return NestedNameSpecifierLoc(
1833 const_cast<NestedNameSpecifier *>(
1834 static_cast<const NestedNameSpecifier *>(data[0])),
1835 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001836 }
1837};
1838
1839class DeclarationNameInfoVisit : public VisitorJob {
1840public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001841 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001842 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001843 static bool classof(const VisitorJob *VJ) {
1844 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1845 }
1846 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001847 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001848 switch (S->getStmtClass()) {
1849 default:
1850 llvm_unreachable("Unhandled Stmt");
1851 case clang::Stmt::MSDependentExistsStmtClass:
1852 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1853 case Stmt::CXXDependentScopeMemberExprClass:
1854 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1855 case Stmt::DependentScopeDeclRefExprClass:
1856 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001857 case Stmt::OMPCriticalDirectiveClass:
1858 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001859 }
1860 }
1861};
1862class MemberRefVisit : public VisitorJob {
1863public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001865 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1866 L.getPtrEncoding()) {}
1867 static bool classof(const VisitorJob *VJ) {
1868 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1869 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001870 const FieldDecl *get() const {
1871 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001872 }
1873 SourceLocation getLoc() const {
1874 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1875 }
1876};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001877class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001878 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001879 VisitorWorkList &WL;
1880 CXCursor Parent;
1881public:
1882 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1883 : WL(wl), Parent(parent) {}
1884
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1886 void VisitBlockExpr(const BlockExpr *B);
1887 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1888 void VisitCompoundStmt(const CompoundStmt *S);
1889 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1890 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1891 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1892 void VisitCXXNewExpr(const CXXNewExpr *E);
1893 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1894 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1895 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1896 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1897 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1898 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1899 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1900 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001901 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902 void VisitDeclRefExpr(const DeclRefExpr *D);
1903 void VisitDeclStmt(const DeclStmt *S);
1904 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1905 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1906 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1907 void VisitForStmt(const ForStmt *FS);
1908 void VisitGotoStmt(const GotoStmt *GS);
1909 void VisitIfStmt(const IfStmt *If);
1910 void VisitInitListExpr(const InitListExpr *IE);
1911 void VisitMemberExpr(const MemberExpr *M);
1912 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1913 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1914 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1915 void VisitOverloadExpr(const OverloadExpr *E);
1916 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1917 void VisitStmt(const Stmt *S);
1918 void VisitSwitchStmt(const SwitchStmt *S);
1919 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001920 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1921 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1922 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1923 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1924 void VisitVAArgExpr(const VAArgExpr *E);
1925 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1926 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1927 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1928 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001929 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001930 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001931 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001932 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001933 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001934 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001935 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001936 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001937 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001938 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001939 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001940 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001941 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001942 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001943 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001944 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001945 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001946 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001947 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001948 void
1949 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001950 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001951 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001952 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001953 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001954 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001955 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00001956 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00001957 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001958 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001959 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001960 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001961 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001962
Guy Benyei11169dd2012-12-18 14:30:41 +00001963private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001964 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001965 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00001966 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1967 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001968 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1969 void AddStmt(const Stmt *S);
1970 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001971 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001972 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001973 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001974};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001975} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001976
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 // 'S' should always be non-null, since it comes from the
1979 // statement we are visiting.
1980 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1981}
1982
1983void
1984EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1985 if (Qualifier)
1986 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1987}
1988
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001989void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001990 if (S)
1991 WL.push_back(StmtVisit(S, Parent));
1992}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 if (D)
1995 WL.push_back(DeclVisit(D, Parent, isFirst));
1996}
James Y Knight04ec5bf2015-12-24 02:59:37 +00001997void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1998 unsigned NumTemplateArgs) {
1999 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002000}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002001void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002002 if (D)
2003 WL.push_back(MemberRefVisit(D, L, Parent));
2004}
2005void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2006 if (TI)
2007 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2008 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002009void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002010 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002011 for (const Stmt *SubStmt : S->children()) {
2012 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002013 }
2014 if (size == WL.size())
2015 return;
2016 // Now reverse the entries we just added. This will match the DFS
2017 // ordering performed by the worklist.
2018 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2019 std::reverse(I, E);
2020}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002021namespace {
2022class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2023 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002024 /// \brief Process clauses with list of variables.
2025 template <typename T>
2026 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002027public:
2028 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2029#define OPENMP_CLAUSE(Name, Class) \
2030 void Visit##Class(const Class *C);
2031#include "clang/Basic/OpenMPKinds.def"
2032};
2033
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002034void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2035 Visitor->AddStmt(C->getCondition());
2036}
2037
Alexey Bataev3778b602014-07-17 07:32:53 +00002038void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2039 Visitor->AddStmt(C->getCondition());
2040}
2041
Alexey Bataev568a8332014-03-06 06:15:19 +00002042void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2043 Visitor->AddStmt(C->getNumThreads());
2044}
2045
Alexey Bataev62c87d22014-03-21 04:51:18 +00002046void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2047 Visitor->AddStmt(C->getSafelen());
2048}
2049
Alexey Bataev66b15b52015-08-21 11:14:16 +00002050void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2051 Visitor->AddStmt(C->getSimdlen());
2052}
2053
Alexander Musman8bd31e62014-05-27 15:12:19 +00002054void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2055 Visitor->AddStmt(C->getNumForLoops());
2056}
2057
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002058void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002059
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002060void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2061
Alexey Bataev56dafe82014-06-20 07:16:17 +00002062void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2063 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002064 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002065}
2066
Alexey Bataev10e775f2015-07-30 11:36:16 +00002067void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2068 Visitor->AddStmt(C->getNumForLoops());
2069}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002070
Alexey Bataev236070f2014-06-20 11:19:47 +00002071void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2072
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002073void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2074
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002075void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2076
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002077void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2078
Alexey Bataevdea47612014-07-23 07:46:59 +00002079void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2080
Alexey Bataev67a4f222014-07-23 10:25:33 +00002081void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2082
Alexey Bataev459dec02014-07-24 06:46:57 +00002083void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2084
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002085void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2086
Alexey Bataev346265e2015-09-25 10:37:12 +00002087void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2088
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002089void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2090
Alexey Bataevb825de12015-12-07 10:51:44 +00002091void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2092
Michael Wonge710d542015-08-07 16:16:36 +00002093void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2094 Visitor->AddStmt(C->getDevice());
2095}
2096
Kelvin Li099bb8c2015-11-24 20:50:12 +00002097void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2098 Visitor->AddStmt(C->getNumTeams());
2099}
2100
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002101void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2102 Visitor->AddStmt(C->getThreadLimit());
2103}
2104
Alexey Bataeva0569352015-12-01 10:17:31 +00002105void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2106 Visitor->AddStmt(C->getPriority());
2107}
2108
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002109void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2110 Visitor->AddStmt(C->getGrainsize());
2111}
2112
Alexey Bataev382967a2015-12-08 12:06:20 +00002113void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2114 Visitor->AddStmt(C->getNumTasks());
2115}
2116
Alexey Bataev28c75412015-12-15 08:19:24 +00002117void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2118 Visitor->AddStmt(C->getHint());
2119}
2120
Alexey Bataev756c1962013-09-24 03:17:45 +00002121template<typename T>
2122void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002123 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002124 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002125 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002126}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002127
2128void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002129 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002130 for (const auto *E : C->private_copies()) {
2131 Visitor->AddStmt(E);
2132 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002133}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002134void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2135 const OMPFirstprivateClause *C) {
2136 VisitOMPClauseList(C);
2137}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002138void OMPClauseEnqueue::VisitOMPLastprivateClause(
2139 const OMPLastprivateClause *C) {
2140 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002141 for (auto *E : C->private_copies()) {
2142 Visitor->AddStmt(E);
2143 }
2144 for (auto *E : C->source_exprs()) {
2145 Visitor->AddStmt(E);
2146 }
2147 for (auto *E : C->destination_exprs()) {
2148 Visitor->AddStmt(E);
2149 }
2150 for (auto *E : C->assignment_ops()) {
2151 Visitor->AddStmt(E);
2152 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002153}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002154void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002155 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002156}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002157void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2158 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002159 for (auto *E : C->privates()) {
2160 Visitor->AddStmt(E);
2161 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002162 for (auto *E : C->lhs_exprs()) {
2163 Visitor->AddStmt(E);
2164 }
2165 for (auto *E : C->rhs_exprs()) {
2166 Visitor->AddStmt(E);
2167 }
2168 for (auto *E : C->reduction_ops()) {
2169 Visitor->AddStmt(E);
2170 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002171}
Alexander Musman8dba6642014-04-22 13:09:42 +00002172void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2173 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002174 for (const auto *E : C->privates()) {
2175 Visitor->AddStmt(E);
2176 }
Alexander Musman3276a272015-03-21 10:12:56 +00002177 for (const auto *E : C->inits()) {
2178 Visitor->AddStmt(E);
2179 }
2180 for (const auto *E : C->updates()) {
2181 Visitor->AddStmt(E);
2182 }
2183 for (const auto *E : C->finals()) {
2184 Visitor->AddStmt(E);
2185 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002186 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002187 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002188}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002189void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2190 VisitOMPClauseList(C);
2191 Visitor->AddStmt(C->getAlignment());
2192}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002193void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2194 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002195 for (auto *E : C->source_exprs()) {
2196 Visitor->AddStmt(E);
2197 }
2198 for (auto *E : C->destination_exprs()) {
2199 Visitor->AddStmt(E);
2200 }
2201 for (auto *E : C->assignment_ops()) {
2202 Visitor->AddStmt(E);
2203 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002204}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002205void
2206OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2207 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002208 for (auto *E : C->source_exprs()) {
2209 Visitor->AddStmt(E);
2210 }
2211 for (auto *E : C->destination_exprs()) {
2212 Visitor->AddStmt(E);
2213 }
2214 for (auto *E : C->assignment_ops()) {
2215 Visitor->AddStmt(E);
2216 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002217}
Alexey Bataev6125da92014-07-21 11:26:11 +00002218void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2219 VisitOMPClauseList(C);
2220}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002221void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2222 VisitOMPClauseList(C);
2223}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002224void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2225 VisitOMPClauseList(C);
2226}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002227void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2228 const OMPDistScheduleClause *C) {
2229 Visitor->AddStmt(C->getChunkSize());
2230 Visitor->AddStmt(C->getHelperChunkSize());
2231}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002232}
Alexey Bataev756c1962013-09-24 03:17:45 +00002233
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002234void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2235 unsigned size = WL.size();
2236 OMPClauseEnqueue Visitor(this);
2237 Visitor.Visit(S);
2238 if (size == WL.size())
2239 return;
2240 // Now reverse the entries we just added. This will match the DFS
2241 // ordering performed by the worklist.
2242 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2243 std::reverse(I, E);
2244}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002245void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002246 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 AddDecl(B->getBlockDecl());
2250}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 EnqueueChildren(E);
2253 AddTypeLoc(E->getTypeSourceInfo());
2254}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002256 for (auto &I : llvm::reverse(S->body()))
2257 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002258}
2259void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 AddStmt(S->getSubStmt());
2262 AddDeclarationNameInfo(S);
2263 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2264 AddNestedNameSpecifierLoc(QualifierLoc);
2265}
2266
2267void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002268VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002269 if (E->hasExplicitTemplateArgs())
2270 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 AddDeclarationNameInfo(E);
2272 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2273 AddNestedNameSpecifierLoc(QualifierLoc);
2274 if (!E->isImplicitAccess())
2275 AddStmt(E->getBase());
2276}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 // Enqueue the initializer , if any.
2279 AddStmt(E->getInitializer());
2280 // Enqueue the array size, if any.
2281 AddStmt(E->getArraySize());
2282 // Enqueue the allocated type.
2283 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2284 // Enqueue the placement arguments.
2285 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2286 AddStmt(E->getPlacementArg(I-1));
2287}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2290 AddStmt(CE->getArg(I-1));
2291 AddStmt(CE->getCallee());
2292 AddStmt(CE->getArg(0));
2293}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2295 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002296 // Visit the name of the type being destroyed.
2297 AddTypeLoc(E->getDestroyedTypeInfo());
2298 // Visit the scope type that looks disturbingly like the nested-name-specifier
2299 // but isn't.
2300 AddTypeLoc(E->getScopeTypeInfo());
2301 // Visit the nested-name-specifier.
2302 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2303 AddNestedNameSpecifierLoc(QualifierLoc);
2304 // Visit base expression.
2305 AddStmt(E->getBase());
2306}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002307void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2308 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 AddTypeLoc(E->getTypeSourceInfo());
2310}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002311void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2312 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 EnqueueChildren(E);
2314 AddTypeLoc(E->getTypeSourceInfo());
2315}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002316void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002317 EnqueueChildren(E);
2318 if (E->isTypeOperand())
2319 AddTypeLoc(E->getTypeOperandSourceInfo());
2320}
2321
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002322void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2323 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002324 EnqueueChildren(E);
2325 AddTypeLoc(E->getTypeSourceInfo());
2326}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002327void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002328 EnqueueChildren(E);
2329 if (E->isTypeOperand())
2330 AddTypeLoc(E->getTypeOperandSourceInfo());
2331}
2332
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002333void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002334 EnqueueChildren(S);
2335 AddDecl(S->getExceptionDecl());
2336}
2337
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002338void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002339 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002340 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002341 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002342}
2343
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002344void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002345 if (DR->hasExplicitTemplateArgs())
2346 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002347 WL.push_back(DeclRefExprParts(DR, Parent));
2348}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002349void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2350 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002351 if (E->hasExplicitTemplateArgs())
2352 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002353 AddDeclarationNameInfo(E);
2354 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2355}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002356void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002357 unsigned size = WL.size();
2358 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002359 for (const auto *D : S->decls()) {
2360 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002361 isFirst = false;
2362 }
2363 if (size == WL.size())
2364 return;
2365 // Now reverse the entries we just added. This will match the DFS
2366 // ordering performed by the worklist.
2367 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2368 std::reverse(I, E);
2369}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002370void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002371 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002372 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002373 D = E->designators_rbegin(), DEnd = E->designators_rend();
2374 D != DEnd; ++D) {
2375 if (D->isFieldDesignator()) {
2376 if (FieldDecl *Field = D->getField())
2377 AddMemberRef(Field, D->getFieldLoc());
2378 continue;
2379 }
2380 if (D->isArrayDesignator()) {
2381 AddStmt(E->getArrayIndex(*D));
2382 continue;
2383 }
2384 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2385 AddStmt(E->getArrayRangeEnd(*D));
2386 AddStmt(E->getArrayRangeStart(*D));
2387 }
2388}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002389void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002390 EnqueueChildren(E);
2391 AddTypeLoc(E->getTypeInfoAsWritten());
2392}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002393void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002394 AddStmt(FS->getBody());
2395 AddStmt(FS->getInc());
2396 AddStmt(FS->getCond());
2397 AddDecl(FS->getConditionVariable());
2398 AddStmt(FS->getInit());
2399}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002400void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002401 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2402}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002403void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002404 AddStmt(If->getElse());
2405 AddStmt(If->getThen());
2406 AddStmt(If->getCond());
2407 AddDecl(If->getConditionVariable());
2408}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002409void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002410 // We care about the syntactic form of the initializer list, only.
2411 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2412 IE = Syntactic;
2413 EnqueueChildren(IE);
2414}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002415void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002416 WL.push_back(MemberExprParts(M, Parent));
2417
2418 // If the base of the member access expression is an implicit 'this', don't
2419 // visit it.
2420 // FIXME: If we ever want to show these implicit accesses, this will be
2421 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002422 if (M->isImplicitAccess())
2423 return;
2424
2425 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2426 // real field that that we are interested in.
2427 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2428 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2429 if (FD->isAnonymousStructOrUnion()) {
2430 AddStmt(SubME->getBase());
2431 return;
2432 }
2433 }
2434 }
2435
2436 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002437}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 AddTypeLoc(E->getEncodedTypeSourceInfo());
2440}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002441void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 EnqueueChildren(M);
2443 AddTypeLoc(M->getClassReceiverTypeInfo());
2444}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002445void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 // Visit the components of the offsetof expression.
2447 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002448 const OffsetOfNode &Node = E->getComponent(I-1);
2449 switch (Node.getKind()) {
2450 case OffsetOfNode::Array:
2451 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2452 break;
2453 case OffsetOfNode::Field:
2454 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2455 break;
2456 case OffsetOfNode::Identifier:
2457 case OffsetOfNode::Base:
2458 continue;
2459 }
2460 }
2461 // Visit the type into which we're computing the offset.
2462 AddTypeLoc(E->getTypeSourceInfo());
2463}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002464void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002465 if (E->hasExplicitTemplateArgs())
2466 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002467 WL.push_back(OverloadExprParts(E, Parent));
2468}
2469void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002470 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002471 EnqueueChildren(E);
2472 if (E->isArgumentType())
2473 AddTypeLoc(E->getArgumentTypeInfo());
2474}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002475void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002476 EnqueueChildren(S);
2477}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002478void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002479 AddStmt(S->getBody());
2480 AddStmt(S->getCond());
2481 AddDecl(S->getConditionVariable());
2482}
2483
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002484void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002485 AddStmt(W->getBody());
2486 AddStmt(W->getCond());
2487 AddDecl(W->getConditionVariable());
2488}
2489
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002490void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002491 for (unsigned I = E->getNumArgs(); I > 0; --I)
2492 AddTypeLoc(E->getArg(I-1));
2493}
2494
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002495void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002496 AddTypeLoc(E->getQueriedTypeSourceInfo());
2497}
2498
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002499void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002500 EnqueueChildren(E);
2501}
2502
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002503void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002504 VisitOverloadExpr(U);
2505 if (!U->isImplicitAccess())
2506 AddStmt(U->getBase());
2507}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002508void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002509 AddStmt(E->getSubExpr());
2510 AddTypeLoc(E->getWrittenTypeInfo());
2511}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002512void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002513 WL.push_back(SizeOfPackExprParts(E, Parent));
2514}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002515void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002516 // If the opaque value has a source expression, just transparently
2517 // visit that. This is useful for (e.g.) pseudo-object expressions.
2518 if (Expr *SourceExpr = E->getSourceExpr())
2519 return Visit(SourceExpr);
2520}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002521void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002522 AddStmt(E->getBody());
2523 WL.push_back(LambdaExprParts(E, Parent));
2524}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002525void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002526 // Treat the expression like its syntactic form.
2527 Visit(E->getSyntacticForm());
2528}
2529
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002530void EnqueueVisitor::VisitOMPExecutableDirective(
2531 const OMPExecutableDirective *D) {
2532 EnqueueChildren(D);
2533 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2534 E = D->clauses().end();
2535 I != E; ++I)
2536 EnqueueChildren(*I);
2537}
2538
Alexander Musman3aaab662014-08-19 11:27:13 +00002539void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2540 VisitOMPExecutableDirective(D);
2541}
2542
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002543void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2544 VisitOMPExecutableDirective(D);
2545}
2546
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002547void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002548 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002549}
2550
Alexey Bataevf29276e2014-06-18 04:14:57 +00002551void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002552 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002553}
2554
Alexander Musmanf82886e2014-09-18 05:12:34 +00002555void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2556 VisitOMPLoopDirective(D);
2557}
2558
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002559void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2560 VisitOMPExecutableDirective(D);
2561}
2562
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002563void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2564 VisitOMPExecutableDirective(D);
2565}
2566
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002567void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2568 VisitOMPExecutableDirective(D);
2569}
2570
Alexander Musman80c22892014-07-17 08:54:58 +00002571void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2572 VisitOMPExecutableDirective(D);
2573}
2574
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002575void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2576 VisitOMPExecutableDirective(D);
2577 AddDeclarationNameInfo(D);
2578}
2579
Alexey Bataev4acb8592014-07-07 13:01:15 +00002580void
2581EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002582 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002583}
2584
Alexander Musmane4e893b2014-09-23 09:33:00 +00002585void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2586 const OMPParallelForSimdDirective *D) {
2587 VisitOMPLoopDirective(D);
2588}
2589
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002590void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2591 const OMPParallelSectionsDirective *D) {
2592 VisitOMPExecutableDirective(D);
2593}
2594
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002595void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2596 VisitOMPExecutableDirective(D);
2597}
2598
Alexey Bataev68446b72014-07-18 07:47:19 +00002599void
2600EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2601 VisitOMPExecutableDirective(D);
2602}
2603
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002604void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2605 VisitOMPExecutableDirective(D);
2606}
2607
Alexey Bataev2df347a2014-07-18 10:17:07 +00002608void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2609 VisitOMPExecutableDirective(D);
2610}
2611
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002612void EnqueueVisitor::VisitOMPTaskgroupDirective(
2613 const OMPTaskgroupDirective *D) {
2614 VisitOMPExecutableDirective(D);
2615}
2616
Alexey Bataev6125da92014-07-21 11:26:11 +00002617void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2618 VisitOMPExecutableDirective(D);
2619}
2620
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002621void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2622 VisitOMPExecutableDirective(D);
2623}
2624
Alexey Bataev0162e452014-07-22 10:10:35 +00002625void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2626 VisitOMPExecutableDirective(D);
2627}
2628
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002629void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2630 VisitOMPExecutableDirective(D);
2631}
2632
Michael Wong65f367f2015-07-21 13:44:28 +00002633void EnqueueVisitor::VisitOMPTargetDataDirective(const
2634 OMPTargetDataDirective *D) {
2635 VisitOMPExecutableDirective(D);
2636}
2637
Samuel Antaodf67fc42016-01-19 19:15:56 +00002638void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2639 const OMPTargetEnterDataDirective *D) {
2640 VisitOMPExecutableDirective(D);
2641}
2642
Samuel Antao72590762016-01-19 20:04:50 +00002643void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2644 const OMPTargetExitDataDirective *D) {
2645 VisitOMPExecutableDirective(D);
2646}
2647
Alexey Bataev13314bf2014-10-09 04:18:56 +00002648void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2649 VisitOMPExecutableDirective(D);
2650}
2651
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002652void EnqueueVisitor::VisitOMPCancellationPointDirective(
2653 const OMPCancellationPointDirective *D) {
2654 VisitOMPExecutableDirective(D);
2655}
2656
Alexey Bataev80909872015-07-02 11:25:17 +00002657void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2658 VisitOMPExecutableDirective(D);
2659}
2660
Alexey Bataev49f6e782015-12-01 04:18:41 +00002661void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2662 VisitOMPLoopDirective(D);
2663}
2664
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002665void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2666 const OMPTaskLoopSimdDirective *D) {
2667 VisitOMPLoopDirective(D);
2668}
2669
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002670void EnqueueVisitor::VisitOMPDistributeDirective(
2671 const OMPDistributeDirective *D) {
2672 VisitOMPLoopDirective(D);
2673}
2674
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002675void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002676 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2677}
2678
2679bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2680 if (RegionOfInterest.isValid()) {
2681 SourceRange Range = getRawCursorExtent(C);
2682 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2683 return false;
2684 }
2685 return true;
2686}
2687
2688bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2689 while (!WL.empty()) {
2690 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002691 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002692
2693 // Set the Parent field, then back to its old value once we're done.
2694 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2695
2696 switch (LI.getKind()) {
2697 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002698 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002699 if (!D)
2700 continue;
2701
2702 // For now, perform default visitation for Decls.
2703 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2704 cast<DeclVisit>(&LI)->isFirst())))
2705 return true;
2706
2707 continue;
2708 }
2709 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002710 for (const TemplateArgumentLoc &Arg :
2711 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2712 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002713 return true;
2714 }
2715 continue;
2716 }
2717 case VisitorJob::TypeLocVisitKind: {
2718 // Perform default visitation for TypeLocs.
2719 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2720 return true;
2721 continue;
2722 }
2723 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002724 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002725 if (LabelStmt *stmt = LS->getStmt()) {
2726 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2727 TU))) {
2728 return true;
2729 }
2730 }
2731 continue;
2732 }
2733
2734 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2735 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2736 if (VisitNestedNameSpecifierLoc(V->get()))
2737 return true;
2738 continue;
2739 }
2740
2741 case VisitorJob::DeclarationNameInfoVisitKind: {
2742 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2743 ->get()))
2744 return true;
2745 continue;
2746 }
2747 case VisitorJob::MemberRefVisitKind: {
2748 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2749 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2750 return true;
2751 continue;
2752 }
2753 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002754 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002755 if (!S)
2756 continue;
2757
2758 // Update the current cursor.
2759 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2760 if (!IsInRegionOfInterest(Cursor))
2761 continue;
2762 switch (Visitor(Cursor, Parent, ClientData)) {
2763 case CXChildVisit_Break: return true;
2764 case CXChildVisit_Continue: break;
2765 case CXChildVisit_Recurse:
2766 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002767 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002768 EnqueueWorkList(WL, S);
2769 break;
2770 }
2771 continue;
2772 }
2773 case VisitorJob::MemberExprPartsKind: {
2774 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002775 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002776
2777 // Visit the nested-name-specifier
2778 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2779 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2780 return true;
2781
2782 // Visit the declaration name.
2783 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2784 return true;
2785
2786 // Visit the explicitly-specified template arguments, if any.
2787 if (M->hasExplicitTemplateArgs()) {
2788 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2789 *ArgEnd = Arg + M->getNumTemplateArgs();
2790 Arg != ArgEnd; ++Arg) {
2791 if (VisitTemplateArgumentLoc(*Arg))
2792 return true;
2793 }
2794 }
2795 continue;
2796 }
2797 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002798 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002799 // Visit nested-name-specifier, if present.
2800 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2801 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2802 return true;
2803 // Visit declaration name.
2804 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2805 return true;
2806 continue;
2807 }
2808 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002809 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002810 // Visit the nested-name-specifier.
2811 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2812 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2813 return true;
2814 // Visit the declaration name.
2815 if (VisitDeclarationNameInfo(O->getNameInfo()))
2816 return true;
2817 // Visit the overloaded declaration reference.
2818 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2819 return true;
2820 continue;
2821 }
2822 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002823 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002824 NamedDecl *Pack = E->getPack();
2825 if (isa<TemplateTypeParmDecl>(Pack)) {
2826 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2827 E->getPackLoc(), TU)))
2828 return true;
2829
2830 continue;
2831 }
2832
2833 if (isa<TemplateTemplateParmDecl>(Pack)) {
2834 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2835 E->getPackLoc(), TU)))
2836 return true;
2837
2838 continue;
2839 }
2840
2841 // Non-type template parameter packs and function parameter packs are
2842 // treated like DeclRefExpr cursors.
2843 continue;
2844 }
2845
2846 case VisitorJob::LambdaExprPartsKind: {
2847 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002848 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002849 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2850 CEnd = E->explicit_capture_end();
2851 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002852 // FIXME: Lambda init-captures.
2853 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002854 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002855
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2857 C->getLocation(),
2858 TU)))
2859 return true;
2860 }
2861
2862 // Visit parameters and return type, if present.
2863 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2864 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2865 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2866 // Visit the whole type.
2867 if (Visit(TL))
2868 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002869 } else if (FunctionProtoTypeLoc Proto =
2870 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002871 if (E->hasExplicitParameters()) {
2872 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002873 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2874 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002875 return true;
2876 } else {
2877 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002878 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002879 return true;
2880 }
2881 }
2882 }
2883 break;
2884 }
2885
2886 case VisitorJob::PostChildrenVisitKind:
2887 if (PostChildrenVisitor(Parent, ClientData))
2888 return true;
2889 break;
2890 }
2891 }
2892 return false;
2893}
2894
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002895bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002896 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002897 if (!WorkListFreeList.empty()) {
2898 WL = WorkListFreeList.back();
2899 WL->clear();
2900 WorkListFreeList.pop_back();
2901 }
2902 else {
2903 WL = new VisitorWorkList();
2904 WorkListCache.push_back(WL);
2905 }
2906 EnqueueWorkList(*WL, S);
2907 bool result = RunVisitorWorkList(*WL);
2908 WorkListFreeList.push_back(WL);
2909 return result;
2910}
2911
2912namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002913typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002914RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2915 const DeclarationNameInfo &NI, SourceRange QLoc,
2916 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002917 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2918 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2919 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2920
2921 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2922
2923 RefNamePieces Pieces;
2924
2925 if (WantQualifier && QLoc.isValid())
2926 Pieces.push_back(QLoc);
2927
2928 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2929 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002930
2931 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2932 Pieces.push_back(*TemplateArgsLoc);
2933
Guy Benyei11169dd2012-12-18 14:30:41 +00002934 if (Kind == DeclarationName::CXXOperatorName) {
2935 Pieces.push_back(SourceLocation::getFromRawEncoding(
2936 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2937 Pieces.push_back(SourceLocation::getFromRawEncoding(
2938 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2939 }
2940
2941 if (WantSinglePiece) {
2942 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2943 Pieces.clear();
2944 Pieces.push_back(R);
2945 }
2946
2947 return Pieces;
2948}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002949}
Guy Benyei11169dd2012-12-18 14:30:41 +00002950
2951//===----------------------------------------------------------------------===//
2952// Misc. API hooks.
2953//===----------------------------------------------------------------------===//
2954
Chad Rosier05c71aa2013-03-27 18:28:23 +00002955static void fatal_error_handler(void *user_data, const std::string& reason,
2956 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002957 // Write the result out to stderr avoiding errs() because raw_ostreams can
2958 // call report_fatal_error.
2959 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2960 ::abort();
2961}
2962
Chandler Carruth66660742014-06-27 16:37:27 +00002963namespace {
2964struct RegisterFatalErrorHandler {
2965 RegisterFatalErrorHandler() {
2966 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2967 }
2968};
2969}
2970
2971static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2972
Guy Benyei11169dd2012-12-18 14:30:41 +00002973extern "C" {
2974CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2975 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002976 // We use crash recovery to make some of our APIs more reliable, implicitly
2977 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002978 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2979 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002980
Chandler Carruth66660742014-06-27 16:37:27 +00002981 // Look through the managed static to trigger construction of the managed
2982 // static which registers our fatal error handler. This ensures it is only
2983 // registered once.
2984 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002985
Adrian Prantlbc068582015-07-08 01:00:30 +00002986 // Initialize targets for clang module support.
2987 llvm::InitializeAllTargets();
2988 llvm::InitializeAllTargetMCs();
2989 llvm::InitializeAllAsmPrinters();
2990 llvm::InitializeAllAsmParsers();
2991
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002992 CIndexer *CIdxr = new CIndexer();
2993
Guy Benyei11169dd2012-12-18 14:30:41 +00002994 if (excludeDeclarationsFromPCH)
2995 CIdxr->setOnlyLocalDecls();
2996 if (displayDiagnostics)
2997 CIdxr->setDisplayDiagnostics();
2998
2999 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3000 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3001 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3002 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3003 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3004 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3005
3006 return CIdxr;
3007}
3008
3009void clang_disposeIndex(CXIndex CIdx) {
3010 if (CIdx)
3011 delete static_cast<CIndexer *>(CIdx);
3012}
3013
3014void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3015 if (CIdx)
3016 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3017}
3018
3019unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3020 if (CIdx)
3021 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3022 return 0;
3023}
3024
3025void clang_toggleCrashRecovery(unsigned isEnabled) {
3026 if (isEnabled)
3027 llvm::CrashRecoveryContext::Enable();
3028 else
3029 llvm::CrashRecoveryContext::Disable();
3030}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003031
Guy Benyei11169dd2012-12-18 14:30:41 +00003032CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3033 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003034 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003035 enum CXErrorCode Result =
3036 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003037 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003038 assert((TU && Result == CXError_Success) ||
3039 (!TU && Result != CXError_Success));
3040 return TU;
3041}
3042
3043enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3044 const char *ast_filename,
3045 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003046 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003047 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003048
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003049 if (!CIdx || !ast_filename || !out_TU)
3050 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003051
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003052 LOG_FUNC_SECTION {
3053 *Log << ast_filename;
3054 }
3055
Guy Benyei11169dd2012-12-18 14:30:41 +00003056 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3057 FileSystemOptions FileSystemOpts;
3058
Justin Bognerd512c1e2014-10-15 00:33:06 +00003059 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3060 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003061 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003062 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003063 FileSystemOpts, /*UseDebugInfo=*/false,
3064 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003065 /*CaptureDiagnostics=*/true,
3066 /*AllowPCHWithCompilerErrors=*/true,
3067 /*UserFilesAreVolatile=*/true);
3068 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003069 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003070}
3071
3072unsigned clang_defaultEditingTranslationUnitOptions() {
3073 return CXTranslationUnit_PrecompiledPreamble |
3074 CXTranslationUnit_CacheCompletionResults;
3075}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003076
Guy Benyei11169dd2012-12-18 14:30:41 +00003077CXTranslationUnit
3078clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3079 const char *source_filename,
3080 int num_command_line_args,
3081 const char * const *command_line_args,
3082 unsigned num_unsaved_files,
3083 struct CXUnsavedFile *unsaved_files) {
3084 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3085 return clang_parseTranslationUnit(CIdx, source_filename,
3086 command_line_args, num_command_line_args,
3087 unsaved_files, num_unsaved_files,
3088 Options);
3089}
3090
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003091static CXErrorCode
3092clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3093 const char *const *command_line_args,
3094 int num_command_line_args,
3095 ArrayRef<CXUnsavedFile> unsaved_files,
3096 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003097 // Set up the initial return values.
3098 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003099 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003100
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003101 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003102 if (!CIdx || !out_TU)
3103 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003104
Guy Benyei11169dd2012-12-18 14:30:41 +00003105 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3106
3107 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3108 setThreadBackgroundPriority();
3109
3110 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003111 bool CreatePreambleOnFirstParse =
3112 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003113 // FIXME: Add a flag for modules.
3114 TranslationUnitKind TUKind
3115 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003116 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003117 = options & CXTranslationUnit_CacheCompletionResults;
3118 bool IncludeBriefCommentsInCodeCompletion
3119 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3120 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3121 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3122
3123 // Configure the diagnostics.
3124 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003125 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003126
3127 // Recover resources if we crash before exiting this function.
3128 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3129 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003130 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003131
Ahmed Charlesb8984322014-03-07 20:03:18 +00003132 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3133 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003134
3135 // Recover resources if we crash before exiting this function.
3136 llvm::CrashRecoveryContextCleanupRegistrar<
3137 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3138
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003139 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003140 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003141 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003142 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003143 }
3144
Ahmed Charlesb8984322014-03-07 20:03:18 +00003145 std::unique_ptr<std::vector<const char *>> Args(
3146 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003147
3148 // Recover resources if we crash before exiting this method.
3149 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3150 ArgsCleanup(Args.get());
3151
3152 // Since the Clang C library is primarily used by batch tools dealing with
3153 // (often very broken) source code, where spell-checking can have a
3154 // significant negative impact on performance (particularly when
3155 // precompiled headers are involved), we disable it by default.
3156 // Only do this if we haven't found a spell-checking-related argument.
3157 bool FoundSpellCheckingArgument = false;
3158 for (int I = 0; I != num_command_line_args; ++I) {
3159 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3160 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3161 FoundSpellCheckingArgument = true;
3162 break;
3163 }
3164 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 Args->insert(Args->end(), command_line_args,
3166 command_line_args + num_command_line_args);
3167
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003168 if (!FoundSpellCheckingArgument)
3169 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3170
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 // The 'source_filename' argument is optional. If the caller does not
3172 // specify it then it is assumed that the source file is specified
3173 // in the actual argument list.
3174 // Put the source file after command_line_args otherwise if '-x' flag is
3175 // present it will be unused.
3176 if (source_filename)
3177 Args->push_back(source_filename);
3178
3179 // Do we need the detailed preprocessing record?
3180 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3181 Args->push_back("-Xclang");
3182 Args->push_back("-detailed-preprocessing-record");
3183 }
3184
3185 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003186 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003187 // Unless the user specified that they want the preamble on the first parse
3188 // set it up to be created on the first reparse. This makes the first parse
3189 // faster, trading for a slower (first) reparse.
3190 unsigned PrecompilePreambleAfterNParses =
3191 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003192 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003193 Args->data(), Args->data() + Args->size(),
3194 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003195 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3196 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003197 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3198 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003199 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003200 /*UserFilesAreVolatile=*/true, ForSerialization,
3201 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3202 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003203
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003204 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003205 if (!Unit && !ErrUnit)
3206 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003207
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 if (NumErrors != Diags->getClient()->getNumErrors()) {
3209 // Make sure to check that 'Unit' is non-NULL.
3210 if (CXXIdx->getDisplayDiagnostics())
3211 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3212 }
3213
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003214 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3215 return CXError_ASTReadError;
3216
3217 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3218 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003219}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003220
3221CXTranslationUnit
3222clang_parseTranslationUnit(CXIndex CIdx,
3223 const char *source_filename,
3224 const char *const *command_line_args,
3225 int num_command_line_args,
3226 struct CXUnsavedFile *unsaved_files,
3227 unsigned num_unsaved_files,
3228 unsigned options) {
3229 CXTranslationUnit TU;
3230 enum CXErrorCode Result = clang_parseTranslationUnit2(
3231 CIdx, source_filename, command_line_args, num_command_line_args,
3232 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003233 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003234 assert((TU && Result == CXError_Success) ||
3235 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003236 return TU;
3237}
3238
3239enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003240 CXIndex CIdx, const char *source_filename,
3241 const char *const *command_line_args, int num_command_line_args,
3242 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3243 unsigned options, CXTranslationUnit *out_TU) {
3244 SmallVector<const char *, 4> Args;
3245 Args.push_back("clang");
3246 Args.append(command_line_args, command_line_args + num_command_line_args);
3247 return clang_parseTranslationUnit2FullArgv(
3248 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3249 num_unsaved_files, options, out_TU);
3250}
3251
3252enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3253 CXIndex CIdx, const char *source_filename,
3254 const char *const *command_line_args, int num_command_line_args,
3255 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3256 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003257 LOG_FUNC_SECTION {
3258 *Log << source_filename << ": ";
3259 for (int i = 0; i != num_command_line_args; ++i)
3260 *Log << command_line_args[i] << " ";
3261 }
3262
Alp Toker9d85b182014-07-07 01:23:14 +00003263 if (num_unsaved_files && !unsaved_files)
3264 return CXError_InvalidArguments;
3265
Alp Toker5c532982014-07-07 22:42:03 +00003266 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003267 auto ParseTranslationUnitImpl = [=, &result] {
3268 result = clang_parseTranslationUnit_Impl(
3269 CIdx, source_filename, command_line_args, num_command_line_args,
3270 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3271 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 llvm::CrashRecoveryContext CRC;
3273
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003274 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3276 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3277 fprintf(stderr, " 'command_line_args' : [");
3278 for (int i = 0; i != num_command_line_args; ++i) {
3279 if (i)
3280 fprintf(stderr, ", ");
3281 fprintf(stderr, "'%s'", command_line_args[i]);
3282 }
3283 fprintf(stderr, "],\n");
3284 fprintf(stderr, " 'unsaved_files' : [");
3285 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3286 if (i)
3287 fprintf(stderr, ", ");
3288 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3289 unsaved_files[i].Length);
3290 }
3291 fprintf(stderr, "],\n");
3292 fprintf(stderr, " 'options' : %d,\n", options);
3293 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003294
3295 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003296 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003297 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003298 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 }
Alp Toker5c532982014-07-07 22:42:03 +00003300
3301 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003302}
3303
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003304CXString clang_Type_getObjCEncoding(CXType CT) {
3305 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3306 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3307 std::string encoding;
3308 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3309 encoding);
3310
3311 return cxstring::createDup(encoding);
3312}
3313
3314static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3315 if (C.kind == CXCursor_MacroDefinition) {
3316 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3317 return MDR->getName();
3318 } else if (C.kind == CXCursor_MacroExpansion) {
3319 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3320 return ME.getName();
3321 }
3322 return nullptr;
3323}
3324
3325unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3326 const IdentifierInfo *II = getMacroIdentifier(C);
3327 if (!II) {
3328 return false;
3329 }
3330 ASTUnit *ASTU = getCursorASTUnit(C);
3331 Preprocessor &PP = ASTU->getPreprocessor();
3332 if (const MacroInfo *MI = PP.getMacroInfo(II))
3333 return MI->isFunctionLike();
3334 return false;
3335}
3336
3337unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3338 const IdentifierInfo *II = getMacroIdentifier(C);
3339 if (!II) {
3340 return false;
3341 }
3342 ASTUnit *ASTU = getCursorASTUnit(C);
3343 Preprocessor &PP = ASTU->getPreprocessor();
3344 if (const MacroInfo *MI = PP.getMacroInfo(II))
3345 return MI->isBuiltinMacro();
3346 return false;
3347}
3348
3349unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3350 const Decl *D = getCursorDecl(C);
3351 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3352 if (!FD) {
3353 return false;
3354 }
3355 return FD->isInlined();
3356}
3357
3358static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3359 if (callExpr->getNumArgs() != 1) {
3360 return nullptr;
3361 }
3362
3363 StringLiteral *S = nullptr;
3364 auto *arg = callExpr->getArg(0);
3365 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3366 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3367 auto *subExpr = I->getSubExprAsWritten();
3368
3369 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3370 return nullptr;
3371 }
3372
3373 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3374 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3375 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3376 } else {
3377 return nullptr;
3378 }
3379 return S;
3380}
3381
3382typedef struct {
3383 CXEvalResultKind EvalType;
3384 union {
3385 int intVal;
3386 double floatVal;
3387 char *stringVal;
3388 } EvalData;
3389} ExprEvalResult;
3390
3391void clang_EvalResult_dispose(CXEvalResult E) {
3392 ExprEvalResult *ER = (ExprEvalResult *)E;
3393 if (ER) {
3394 CXEvalResultKind evalType = ER->EvalType;
3395
3396 if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
3397 evalType != CXEval_Int && ER->EvalData.stringVal) {
3398 free((void *) ER->EvalData.stringVal);
3399 }
3400 free((void *)ER);
3401 }
3402}
3403
3404CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3405 if (!E) {
3406 return CXEval_UnExposed;
3407 }
3408 return ((ExprEvalResult *)E)->EvalType;
3409}
3410
3411int clang_EvalResult_getAsInt(CXEvalResult E) {
3412 if (!E) {
3413 return 0;
3414 }
3415 return ((ExprEvalResult *)E)->EvalData.intVal;
3416}
3417
3418double clang_EvalResult_getAsDouble(CXEvalResult E) {
3419 if (!E) {
3420 return 0;
3421 }
3422 return ((ExprEvalResult *)E)->EvalData.floatVal;
3423}
3424
3425const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3426 if (!E) {
3427 return nullptr;
3428 }
3429 return ((ExprEvalResult *)E)->EvalData.stringVal;
3430}
3431
3432static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3433 Expr::EvalResult ER;
3434 ASTContext &ctx = getCursorContext(C);
3435 if (!expr) {
3436 return nullptr;
3437 }
3438 expr = expr->IgnoreParens();
3439 bool res = expr->EvaluateAsRValue(ER, ctx);
3440 QualType rettype;
3441 CallExpr *callExpr;
3442 ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
3443 if (!result) {
3444 return nullptr;
3445 }
3446 result->EvalType = CXEval_UnExposed;
3447
3448 if (res) {
3449
3450 if (ER.Val.isInt()) {
3451 result->EvalType = CXEval_Int;
3452 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3453 return result;
3454 } else if (ER.Val.isFloat()) {
3455
3456 llvm::SmallVector<char, 100> Buffer;
3457 ER.Val.getFloat().toString(Buffer);
3458 std::string floatStr(Buffer.data(), Buffer.size());
3459 result->EvalType = CXEval_Float;
3460 bool ignored;
3461 llvm::APFloat apFloat = ER.Val.getFloat();
3462 apFloat.convert(llvm::APFloat::IEEEdouble,
3463 llvm::APFloat::rmNearestTiesToEven, &ignored);
3464 result->EvalData.floatVal = apFloat.convertToDouble();
3465 return result;
3466
3467 } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3468
3469 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3470 auto *subExpr = I->getSubExprAsWritten();
3471 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3472 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3473
3474 const StringLiteral *StrE = nullptr;
3475 const ObjCStringLiteral *ObjCExpr;
3476 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3477
3478 if (ObjCExpr) {
3479 StrE = ObjCExpr->getString();
3480 result->EvalType = CXEval_ObjCStrLiteral;
3481 } else {
3482 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3483 result->EvalType = CXEval_StrLiteral;
3484 }
3485
3486 std::string strRef(StrE->getString().str());
3487 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3488 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3489 strRef.size());
3490 result->EvalData.stringVal[strRef.size()] = '\0';
3491 return result;
3492 }
3493
3494 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3495 expr->getStmtClass() == Stmt::StringLiteralClass) {
3496
3497 const StringLiteral *StrE = nullptr;
3498 const ObjCStringLiteral *ObjCExpr;
3499 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3500
3501 if (ObjCExpr) {
3502 StrE = ObjCExpr->getString();
3503 result->EvalType = CXEval_ObjCStrLiteral;
3504 } else {
3505 StrE = cast<StringLiteral>(expr);
3506 result->EvalType = CXEval_StrLiteral;
3507 }
3508
3509 std::string strRef(StrE->getString().str());
3510 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3511 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3512 strRef.size());
3513 result->EvalData.stringVal[strRef.size()] = '\0';
3514 return result;
3515
3516 } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3517
3518 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3519
3520 rettype = CC->getType();
3521 if (rettype.getAsString() == "CFStringRef" &&
3522 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3523
3524 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3525 StringLiteral* S = getCFSTR_value(callExpr);
3526 if (S) {
3527 std::string strLiteral(S->getString().str());
3528 result->EvalType = CXEval_CFStr;
3529
3530 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3531 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3532 strLiteral.size());
3533 result->EvalData.stringVal[strLiteral.size()] = '\0';
3534 return result;
3535 }
3536 }
3537
3538 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3539
3540 callExpr = static_cast<CallExpr *>(expr);
3541 rettype = callExpr->getCallReturnType(ctx);
3542
3543 if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
3544 return nullptr;
3545 }
3546 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3547 if(callExpr->getNumArgs() == 1 &&
3548 !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
3549
3550 return nullptr;
3551 }
3552 } else if(rettype.getAsString() == "CFStringRef") {
3553
3554 StringLiteral* S = getCFSTR_value(callExpr);
3555 if (S) {
3556 std::string strLiteral(S->getString().str());
3557 result->EvalType = CXEval_CFStr;
3558 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3559 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3560 strLiteral.size());
3561 result->EvalData.stringVal[strLiteral.size()] = '\0';
3562 return result;
3563 }
3564 }
3565
3566 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3567
3568 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3569 ValueDecl *V = D->getDecl();
3570 if (V->getKind() == Decl::Function) {
3571 std::string strName(V->getNameAsString());
3572 result->EvalType = CXEval_Other;
3573 result->EvalData.stringVal = (char *)malloc(strName.size()+1);
3574 strncpy((char*)result->EvalData.stringVal, strName.c_str(),
3575 strName.size());
3576 result->EvalData.stringVal[strName.size()] = '\0';
3577 return result;
3578 }
3579 }
3580
3581 }
3582
3583 clang_EvalResult_dispose((CXEvalResult *)result);
3584 return nullptr;
3585}
3586
3587CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3588 const Decl *D = getCursorDecl(C);
3589 if (D) {
3590 const Expr *expr = nullptr;
3591 if (auto *Var = dyn_cast<VarDecl>(D)) {
3592 expr = Var->getInit();
3593 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3594 expr = Field->getInClassInitializer();
3595 }
3596 if (expr)
3597 return (CXEvalResult)evaluateExpr((Expr *)expr, C);
3598 return nullptr;
3599 }
3600
3601 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3602 if (compoundStmt) {
3603 Expr *expr = nullptr;
3604 for (auto *bodyIterator : compoundStmt->body()) {
3605 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3606 break;
3607 }
3608 }
3609 if (expr)
3610 return (CXEvalResult)evaluateExpr(expr, C);
3611 }
3612 return nullptr;
3613}
3614
3615unsigned clang_Cursor_hasAttrs(CXCursor C) {
3616 const Decl *D = getCursorDecl(C);
3617 if (!D) {
3618 return 0;
3619 }
3620
3621 if (D->hasAttrs()) {
3622 return 1;
3623 }
3624
3625 return 0;
3626}
Guy Benyei11169dd2012-12-18 14:30:41 +00003627unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3628 return CXSaveTranslationUnit_None;
3629}
3630
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003631static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3632 const char *FileName,
3633 unsigned options) {
3634 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3636 setThreadBackgroundPriority();
3637
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003638 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3639 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003640}
3641
3642int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3643 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003644 LOG_FUNC_SECTION {
3645 *Log << TU << ' ' << FileName;
3646 }
3647
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003648 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003649 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003651 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003652
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003653 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3655 if (!CXXUnit->hasSema())
3656 return CXSaveError_InvalidTU;
3657
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003658 CXSaveError result;
3659 auto SaveTranslationUnitImpl = [=, &result]() {
3660 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3661 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003662
3663 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3664 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003665 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003666
3667 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3668 PrintLibclangResourceUsage(TU);
3669
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003670 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 }
3672
3673 // We have an AST that has invalid nodes due to compiler errors.
3674 // Use a crash recovery thread for protection.
3675
3676 llvm::CrashRecoveryContext CRC;
3677
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003678 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3680 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3681 fprintf(stderr, " 'options' : %d,\n", options);
3682 fprintf(stderr, "}\n");
3683
3684 return CXSaveError_Unknown;
3685
3686 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3687 PrintLibclangResourceUsage(TU);
3688 }
3689
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003690 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003691}
3692
3693void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3694 if (CTUnit) {
3695 // If the translation unit has been marked as unsafe to free, just discard
3696 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003697 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3698 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 return;
3700
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003701 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003702 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3704 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003705 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 delete CTUnit;
3707 }
3708}
3709
3710unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3711 return CXReparse_None;
3712}
3713
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003714static CXErrorCode
3715clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3716 ArrayRef<CXUnsavedFile> unsaved_files,
3717 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003718 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003719 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003720 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003721 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003722 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003723
3724 // Reset the associated diagnostics.
3725 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003726 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003727
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003728 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3730 setThreadBackgroundPriority();
3731
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003732 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003734
3735 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3736 new std::vector<ASTUnit::RemappedFile>());
3737
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 // Recover resources if we crash before exiting this function.
3739 llvm::CrashRecoveryContextCleanupRegistrar<
3740 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003741
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003742 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003743 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003744 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003745 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003747
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003748 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3749 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003750 return CXError_Success;
3751 if (isASTReadError(CXXUnit))
3752 return CXError_ASTReadError;
3753 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003754}
3755
3756int clang_reparseTranslationUnit(CXTranslationUnit TU,
3757 unsigned num_unsaved_files,
3758 struct CXUnsavedFile *unsaved_files,
3759 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003760 LOG_FUNC_SECTION {
3761 *Log << TU;
3762 }
3763
Alp Toker9d85b182014-07-07 01:23:14 +00003764 if (num_unsaved_files && !unsaved_files)
3765 return CXError_InvalidArguments;
3766
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003767 CXErrorCode result;
3768 auto ReparseTranslationUnitImpl = [=, &result]() {
3769 result = clang_reparseTranslationUnit_Impl(
3770 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3771 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003772
3773 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003774 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003775 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 }
3777
3778 llvm::CrashRecoveryContext CRC;
3779
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003780 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003782 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003783 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3785 PrintLibclangResourceUsage(TU);
3786
Alp Toker5c532982014-07-07 22:42:03 +00003787 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003788}
3789
3790
3791CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003792 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003793 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003794 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003795 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003796
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003797 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003798 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003799}
3800
3801CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003802 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003803 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003804 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003805 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003806
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003807 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3809}
3810
3811} // end: extern "C"
3812
3813//===----------------------------------------------------------------------===//
3814// CXFile Operations.
3815//===----------------------------------------------------------------------===//
3816
3817extern "C" {
3818CXString clang_getFileName(CXFile SFile) {
3819 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003820 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003821
3822 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003824}
3825
3826time_t clang_getFileTime(CXFile SFile) {
3827 if (!SFile)
3828 return 0;
3829
3830 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3831 return FEnt->getModificationTime();
3832}
3833
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003834CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003835 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003836 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003837 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003838 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003839
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003840 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003841
3842 FileManager &FMgr = CXXUnit->getFileManager();
3843 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3844}
3845
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003846unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3847 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003848 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003849 LOG_BAD_TU(TU);
3850 return 0;
3851 }
3852
3853 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 return 0;
3855
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003856 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 FileEntry *FEnt = static_cast<FileEntry *>(file);
3858 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3859 .isFileMultipleIncludeGuarded(FEnt);
3860}
3861
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003862int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3863 if (!file || !outID)
3864 return 1;
3865
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003866 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003867 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3868 outID->data[0] = ID.getDevice();
3869 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003870 outID->data[2] = FEnt->getModificationTime();
3871 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003872}
3873
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003874int clang_File_isEqual(CXFile file1, CXFile file2) {
3875 if (file1 == file2)
3876 return true;
3877
3878 if (!file1 || !file2)
3879 return false;
3880
3881 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3882 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3883 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3884}
3885
Guy Benyei11169dd2012-12-18 14:30:41 +00003886} // end: extern "C"
3887
3888//===----------------------------------------------------------------------===//
3889// CXCursor Operations.
3890//===----------------------------------------------------------------------===//
3891
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003892static const Decl *getDeclFromExpr(const Stmt *E) {
3893 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 return getDeclFromExpr(CE->getSubExpr());
3895
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003896 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003898 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003900 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003902 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 if (PRE->isExplicitProperty())
3904 return PRE->getExplicitProperty();
3905 // It could be messaging both getter and setter as in:
3906 // ++myobj.myprop;
3907 // in which case prefer to associate the setter since it is less obvious
3908 // from inspecting the source that the setter is going to get called.
3909 if (PRE->isMessagingSetter())
3910 return PRE->getImplicitPropertySetter();
3911 return PRE->getImplicitPropertyGetter();
3912 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003913 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003915 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 if (Expr *Src = OVE->getSourceExpr())
3917 return getDeclFromExpr(Src);
3918
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003919 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003921 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 if (!CE->isElidable())
3923 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003924 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 return OME->getMethodDecl();
3926
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003927 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003929 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3931 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003932 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3934 isa<ParmVarDecl>(SizeOfPack->getPack()))
3935 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003936
3937 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003938}
3939
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003940static SourceLocation getLocationFromExpr(const Expr *E) {
3941 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 return getLocationFromExpr(CE->getSubExpr());
3943
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003944 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003946 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003948 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003950 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003952 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003954 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 return PropRef->getLocation();
3956
3957 return E->getLocStart();
3958}
3959
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003960static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3961 std::unique_ptr<llvm::DataLayout> &DL,
3962 const NamedDecl *ND,
3963 unsigned StructorType) {
3964 std::string FrontendBuf;
3965 llvm::raw_string_ostream FOS(FrontendBuf);
3966
3967 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3968 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3969 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3970 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3971
3972 std::string BackendBuf;
3973 llvm::raw_string_ostream BOS(BackendBuf);
3974
3975 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3976
3977 return BOS.str();
3978}
3979
Guy Benyei11169dd2012-12-18 14:30:41 +00003980extern "C" {
3981
3982unsigned clang_visitChildren(CXCursor parent,
3983 CXCursorVisitor visitor,
3984 CXClientData client_data) {
3985 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3986 /*VisitPreprocessorLast=*/false);
3987 return CursorVis.VisitChildren(parent);
3988}
3989
3990#ifndef __has_feature
3991#define __has_feature(x) 0
3992#endif
3993#if __has_feature(blocks)
3994typedef enum CXChildVisitResult
3995 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3996
3997static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3998 CXClientData client_data) {
3999 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4000 return block(cursor, parent);
4001}
4002#else
4003// If we are compiled with a compiler that doesn't have native blocks support,
4004// define and call the block manually, so the
4005typedef struct _CXChildVisitResult
4006{
4007 void *isa;
4008 int flags;
4009 int reserved;
4010 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4011 CXCursor);
4012} *CXCursorVisitorBlock;
4013
4014static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4015 CXClientData client_data) {
4016 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4017 return block->invoke(block, cursor, parent);
4018}
4019#endif
4020
4021
4022unsigned clang_visitChildrenWithBlock(CXCursor parent,
4023 CXCursorVisitorBlock block) {
4024 return clang_visitChildren(parent, visitWithBlock, block);
4025}
4026
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004027static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004029 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004030
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004031 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004033 if (const ObjCPropertyImplDecl *PropImpl =
4034 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004036 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004037
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004038 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004040 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004041
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004042 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 }
4044
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004045 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004046 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004047
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004048 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4050 // and returns different names. NamedDecl returns the class name and
4051 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004053
4054 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004055 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004056
4057 SmallString<1024> S;
4058 llvm::raw_svector_ostream os(S);
4059 ND->printName(os);
4060
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004061 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004062}
4063
4064CXString clang_getCursorSpelling(CXCursor C) {
4065 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004066 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004067
4068 if (clang_isReference(C.kind)) {
4069 switch (C.kind) {
4070 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004071 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 }
4074 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004075 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 }
4078 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004079 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004081 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 }
4083 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004084 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004085 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 }
4087 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004088 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 assert(Type && "Missing type decl");
4090
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004091 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 getAsString());
4093 }
4094 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004095 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 assert(Template && "Missing template decl");
4097
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004098 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 }
4100
4101 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004102 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 assert(NS && "Missing namespace decl");
4104
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004105 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 }
4107
4108 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004109 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 assert(Field && "Missing member decl");
4111
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004112 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 }
4114
4115 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004116 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 assert(Label && "Missing label");
4118
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004119 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 }
4121
4122 case CXCursor_OverloadedDeclRef: {
4123 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004124 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4125 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004126 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004127 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004128 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004129 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004130 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 OverloadedTemplateStorage *Ovl
4132 = Storage.get<OverloadedTemplateStorage*>();
4133 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004134 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004135 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 }
4137
4138 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004139 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004140 assert(Var && "Missing variable decl");
4141
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004142 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 }
4144
4145 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 }
4148 }
4149
4150 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004151 const Expr *E = getCursorExpr(C);
4152
4153 if (C.kind == CXCursor_ObjCStringLiteral ||
4154 C.kind == CXCursor_StringLiteral) {
4155 const StringLiteral *SLit;
4156 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4157 SLit = OSL->getString();
4158 } else {
4159 SLit = cast<StringLiteral>(E);
4160 }
4161 SmallString<256> Buf;
4162 llvm::raw_svector_ostream OS(Buf);
4163 SLit->outputString(OS);
4164 return cxstring::createDup(OS.str());
4165 }
4166
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004167 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 if (D)
4169 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004170 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 }
4172
4173 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004174 const Stmt *S = getCursorStmt(C);
4175 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004177
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004178 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 }
4180
4181 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 ->getNameStart());
4184
4185 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 ->getNameStart());
4188
4189 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004190 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004191
4192 if (clang_isDeclaration(C.kind))
4193 return getDeclSpelling(getCursorDecl(C));
4194
4195 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004196 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004197 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 }
4199
4200 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004201 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004202 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 }
4204
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004205 if (C.kind == CXCursor_PackedAttr) {
4206 return cxstring::createRef("packed");
4207 }
4208
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004209 if (C.kind == CXCursor_VisibilityAttr) {
4210 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4211 switch (AA->getVisibility()) {
4212 case VisibilityAttr::VisibilityType::Default:
4213 return cxstring::createRef("default");
4214 case VisibilityAttr::VisibilityType::Hidden:
4215 return cxstring::createRef("hidden");
4216 case VisibilityAttr::VisibilityType::Protected:
4217 return cxstring::createRef("protected");
4218 }
4219 llvm_unreachable("unknown visibility type");
4220 }
4221
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004222 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004223}
4224
4225CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4226 unsigned pieceIndex,
4227 unsigned options) {
4228 if (clang_Cursor_isNull(C))
4229 return clang_getNullRange();
4230
4231 ASTContext &Ctx = getCursorContext(C);
4232
4233 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004234 const Stmt *S = getCursorStmt(C);
4235 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 if (pieceIndex > 0)
4237 return clang_getNullRange();
4238 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4239 }
4240
4241 return clang_getNullRange();
4242 }
4243
4244 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004245 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4247 if (pieceIndex >= ME->getNumSelectorLocs())
4248 return clang_getNullRange();
4249 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4250 }
4251 }
4252
4253 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4254 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004255 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4257 if (pieceIndex >= MD->getNumSelectorLocs())
4258 return clang_getNullRange();
4259 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4260 }
4261 }
4262
4263 if (C.kind == CXCursor_ObjCCategoryDecl ||
4264 C.kind == CXCursor_ObjCCategoryImplDecl) {
4265 if (pieceIndex > 0)
4266 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004267 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4269 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004270 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4272 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4273 }
4274
4275 if (C.kind == CXCursor_ModuleImportDecl) {
4276 if (pieceIndex > 0)
4277 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004278 if (const ImportDecl *ImportD =
4279 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4281 if (!Locs.empty())
4282 return cxloc::translateSourceRange(Ctx,
4283 SourceRange(Locs.front(), Locs.back()));
4284 }
4285 return clang_getNullRange();
4286 }
4287
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004288 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4289 C.kind == CXCursor_ConversionFunction) {
4290 if (pieceIndex > 0)
4291 return clang_getNullRange();
4292 if (const FunctionDecl *FD =
4293 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4294 DeclarationNameInfo FunctionName = FD->getNameInfo();
4295 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4296 }
4297 return clang_getNullRange();
4298 }
4299
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 // FIXME: A CXCursor_InclusionDirective should give the location of the
4301 // filename, but we don't keep track of this.
4302
4303 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4304 // but we don't keep track of this.
4305
4306 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4307 // but we don't keep track of this.
4308
4309 // Default handling, give the location of the cursor.
4310
4311 if (pieceIndex > 0)
4312 return clang_getNullRange();
4313
4314 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4315 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4316 return cxloc::translateSourceRange(Ctx, Loc);
4317}
4318
Eli Bendersky44a206f2014-07-31 18:04:56 +00004319CXString clang_Cursor_getMangling(CXCursor C) {
4320 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4321 return cxstring::createEmpty();
4322
Eli Bendersky44a206f2014-07-31 18:04:56 +00004323 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004324 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004325 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4326 return cxstring::createEmpty();
4327
Eli Bendersky79759592014-08-01 15:01:10 +00004328 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00004329 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00004330 ASTContext &Ctx = ND->getASTContext();
4331 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004332
Eli Bendersky79759592014-08-01 15:01:10 +00004333 std::string FrontendBuf;
4334 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00004335 if (MC->shouldMangleDeclName(ND)) {
4336 MC->mangleName(ND, FrontendBufOS);
4337 } else {
4338 ND->printName(FrontendBufOS);
4339 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00004340
Eli Bendersky79759592014-08-01 15:01:10 +00004341 // Now apply backend mangling.
4342 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00004343 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00004344
4345 std::string FinalBuf;
4346 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00004347 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
4348 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00004349
4350 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004351}
4352
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004353CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4354 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4355 return nullptr;
4356
4357 const Decl *D = getCursorDecl(C);
4358 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4359 return nullptr;
4360
4361 const NamedDecl *ND = cast<NamedDecl>(D);
4362
4363 ASTContext &Ctx = ND->getASTContext();
4364 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
4365 std::unique_ptr<llvm::DataLayout> DL(
4366 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
4367
4368 std::vector<std::string> Manglings;
4369
4370 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4371 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4372 /*IsCSSMethod=*/true);
4373 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4374 return CC == DefaultCC;
4375 };
4376
4377 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4378 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4379
4380 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4381 if (!CD->getParent()->isAbstract())
4382 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4383
4384 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4385 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4386 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4387 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4388 Ctor_DefaultClosure));
4389 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4390 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4391 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4392 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
Saleem Abdulrasoold5af8ae2015-12-10 06:30:23 +00004393 if (DD->isVirtual())
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004394 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4395 }
4396 }
4397
4398 return cxstring::createSet(Manglings);
4399}
4400
Guy Benyei11169dd2012-12-18 14:30:41 +00004401CXString clang_getCursorDisplayName(CXCursor C) {
4402 if (!clang_isDeclaration(C.kind))
4403 return clang_getCursorSpelling(C);
4404
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004405 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004407 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004408
4409 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004410 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004411 D = FunTmpl->getTemplatedDecl();
4412
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004413 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 SmallString<64> Str;
4415 llvm::raw_svector_ostream OS(Str);
4416 OS << *Function;
4417 if (Function->getPrimaryTemplate())
4418 OS << "<>";
4419 OS << "(";
4420 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4421 if (I)
4422 OS << ", ";
4423 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4424 }
4425
4426 if (Function->isVariadic()) {
4427 if (Function->getNumParams())
4428 OS << ", ";
4429 OS << "...";
4430 }
4431 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004432 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004433 }
4434
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004435 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 SmallString<64> Str;
4437 llvm::raw_svector_ostream OS(Str);
4438 OS << *ClassTemplate;
4439 OS << "<";
4440 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4441 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4442 if (I)
4443 OS << ", ";
4444
4445 NamedDecl *Param = Params->getParam(I);
4446 if (Param->getIdentifier()) {
4447 OS << Param->getIdentifier()->getName();
4448 continue;
4449 }
4450
4451 // There is no parameter name, which makes this tricky. Try to come up
4452 // with something useful that isn't too long.
4453 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4454 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4455 else if (NonTypeTemplateParmDecl *NTTP
4456 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4457 OS << NTTP->getType().getAsString(Policy);
4458 else
4459 OS << "template<...> class";
4460 }
4461
4462 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004463 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 }
4465
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004466 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4468 // If the type was explicitly written, use that.
4469 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004470 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004471
Benjamin Kramer9170e912013-02-22 15:46:01 +00004472 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 llvm::raw_svector_ostream OS(Str);
4474 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004475 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 ClassSpec->getTemplateArgs().data(),
4477 ClassSpec->getTemplateArgs().size(),
4478 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004479 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004480 }
4481
4482 return clang_getCursorSpelling(C);
4483}
4484
4485CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4486 switch (Kind) {
4487 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004488 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004490 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004492 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004494 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004496 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004498 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004500 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004502 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004504 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004506 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004508 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004510 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004512 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004514 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004516 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004518 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004520 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004522 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004524 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004526 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004528 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004530 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004532 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004534 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004536 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004538 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004540 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004542 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004544 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004550 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004552 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004554 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004556 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004558 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004560 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004562 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004564 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004565 case CXCursor_OMPArraySectionExpr:
4566 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004570 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004572 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004574 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004576 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004578 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004580 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004582 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004584 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004588 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004596 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004600 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004602 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004606 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004608 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004610 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004612 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004614 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004616 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004617 case CXCursor_ObjCSelfExpr:
4618 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004620 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004622 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004624 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004626 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004628 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004632 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004634 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004636 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004638 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004640 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004642 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004644 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004646 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004648 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004650 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004652 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004654 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004656 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004658 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004660 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004662 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004666 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004668 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004670 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004672 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004674 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004676 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004678 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004680 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004682 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004684 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004686 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004688 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004690 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004692 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004694 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004696 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004698 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004700 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004702 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004704 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004706 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004707 case CXCursor_SEHLeaveStmt:
4708 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004710 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004712 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004714 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004716 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004718 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004720 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004722 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004724 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004726 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004728 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004730 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004732 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004734 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004736 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004737 case CXCursor_PackedAttr:
4738 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004739 case CXCursor_PureAttr:
4740 return cxstring::createRef("attribute(pure)");
4741 case CXCursor_ConstAttr:
4742 return cxstring::createRef("attribute(const)");
4743 case CXCursor_NoDuplicateAttr:
4744 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004745 case CXCursor_CUDAConstantAttr:
4746 return cxstring::createRef("attribute(constant)");
4747 case CXCursor_CUDADeviceAttr:
4748 return cxstring::createRef("attribute(device)");
4749 case CXCursor_CUDAGlobalAttr:
4750 return cxstring::createRef("attribute(global)");
4751 case CXCursor_CUDAHostAttr:
4752 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004753 case CXCursor_CUDASharedAttr:
4754 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004755 case CXCursor_VisibilityAttr:
4756 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004757 case CXCursor_DLLExport:
4758 return cxstring::createRef("attribute(dllexport)");
4759 case CXCursor_DLLImport:
4760 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004762 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004764 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004766 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004768 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004770 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004772 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004774 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004776 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004778 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004780 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004782 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004784 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004786 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004788 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004790 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004792 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004794 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004795 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004796 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004798 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004800 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004802 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004803 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004804 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004805 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004806 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004808 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004809 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004810 return cxstring::createRef("OMPParallelDirective");
4811 case CXCursor_OMPSimdDirective:
4812 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004813 case CXCursor_OMPForDirective:
4814 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004815 case CXCursor_OMPForSimdDirective:
4816 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004817 case CXCursor_OMPSectionsDirective:
4818 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004819 case CXCursor_OMPSectionDirective:
4820 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004821 case CXCursor_OMPSingleDirective:
4822 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004823 case CXCursor_OMPMasterDirective:
4824 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004825 case CXCursor_OMPCriticalDirective:
4826 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004827 case CXCursor_OMPParallelForDirective:
4828 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004829 case CXCursor_OMPParallelForSimdDirective:
4830 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004831 case CXCursor_OMPParallelSectionsDirective:
4832 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004833 case CXCursor_OMPTaskDirective:
4834 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004835 case CXCursor_OMPTaskyieldDirective:
4836 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004837 case CXCursor_OMPBarrierDirective:
4838 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004839 case CXCursor_OMPTaskwaitDirective:
4840 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004841 case CXCursor_OMPTaskgroupDirective:
4842 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004843 case CXCursor_OMPFlushDirective:
4844 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004845 case CXCursor_OMPOrderedDirective:
4846 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004847 case CXCursor_OMPAtomicDirective:
4848 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004849 case CXCursor_OMPTargetDirective:
4850 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004851 case CXCursor_OMPTargetDataDirective:
4852 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004853 case CXCursor_OMPTargetEnterDataDirective:
4854 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00004855 case CXCursor_OMPTargetExitDataDirective:
4856 return cxstring::createRef("OMPTargetExitDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004857 case CXCursor_OMPTeamsDirective:
4858 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004859 case CXCursor_OMPCancellationPointDirective:
4860 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004861 case CXCursor_OMPCancelDirective:
4862 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004863 case CXCursor_OMPTaskLoopDirective:
4864 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004865 case CXCursor_OMPTaskLoopSimdDirective:
4866 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004867 case CXCursor_OMPDistributeDirective:
4868 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004869 case CXCursor_OverloadCandidate:
4870 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004871 case CXCursor_TypeAliasTemplateDecl:
4872 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 }
4874
4875 llvm_unreachable("Unhandled CXCursorKind");
4876}
4877
4878struct GetCursorData {
4879 SourceLocation TokenBeginLoc;
4880 bool PointsAtMacroArgExpansion;
4881 bool VisitedObjCPropertyImplDecl;
4882 SourceLocation VisitedDeclaratorDeclStartLoc;
4883 CXCursor &BestCursor;
4884
4885 GetCursorData(SourceManager &SM,
4886 SourceLocation tokenBegin, CXCursor &outputCursor)
4887 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4888 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4889 VisitedObjCPropertyImplDecl = false;
4890 }
4891};
4892
4893static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4894 CXCursor parent,
4895 CXClientData client_data) {
4896 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4897 CXCursor *BestCursor = &Data->BestCursor;
4898
4899 // If we point inside a macro argument we should provide info of what the
4900 // token is so use the actual cursor, don't replace it with a macro expansion
4901 // cursor.
4902 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4903 return CXChildVisit_Recurse;
4904
4905 if (clang_isDeclaration(cursor.kind)) {
4906 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004907 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004908 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4909 if (MD->isImplicit())
4910 return CXChildVisit_Break;
4911
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004912 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4914 // Check that when we have multiple @class references in the same line,
4915 // that later ones do not override the previous ones.
4916 // If we have:
4917 // @class Foo, Bar;
4918 // source ranges for both start at '@', so 'Bar' will end up overriding
4919 // 'Foo' even though the cursor location was at 'Foo'.
4920 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4921 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004922 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4924 if (PrevID != ID &&
4925 !PrevID->isThisDeclarationADefinition() &&
4926 !ID->isThisDeclarationADefinition())
4927 return CXChildVisit_Break;
4928 }
4929
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004930 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004931 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4932 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4933 // Check that when we have multiple declarators in the same line,
4934 // that later ones do not override the previous ones.
4935 // If we have:
4936 // int Foo, Bar;
4937 // source ranges for both start at 'int', so 'Bar' will end up overriding
4938 // 'Foo' even though the cursor location was at 'Foo'.
4939 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4940 return CXChildVisit_Break;
4941 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4942
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004943 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004944 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4945 (void)PropImp;
4946 // Check that when we have multiple @synthesize in the same line,
4947 // that later ones do not override the previous ones.
4948 // If we have:
4949 // @synthesize Foo, Bar;
4950 // source ranges for both start at '@', so 'Bar' will end up overriding
4951 // 'Foo' even though the cursor location was at 'Foo'.
4952 if (Data->VisitedObjCPropertyImplDecl)
4953 return CXChildVisit_Break;
4954 Data->VisitedObjCPropertyImplDecl = true;
4955 }
4956 }
4957
4958 if (clang_isExpression(cursor.kind) &&
4959 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004960 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004961 // Avoid having the cursor of an expression replace the declaration cursor
4962 // when the expression source range overlaps the declaration range.
4963 // This can happen for C++ constructor expressions whose range generally
4964 // include the variable declaration, e.g.:
4965 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4966 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4967 D->getLocation() == Data->TokenBeginLoc)
4968 return CXChildVisit_Break;
4969 }
4970 }
4971
4972 // If our current best cursor is the construction of a temporary object,
4973 // don't replace that cursor with a type reference, because we want
4974 // clang_getCursor() to point at the constructor.
4975 if (clang_isExpression(BestCursor->kind) &&
4976 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4977 cursor.kind == CXCursor_TypeRef) {
4978 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4979 // as having the actual point on the type reference.
4980 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4981 return CXChildVisit_Recurse;
4982 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004983
4984 // If we already have an Objective-C superclass reference, don't
4985 // update it further.
4986 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4987 return CXChildVisit_Break;
4988
Guy Benyei11169dd2012-12-18 14:30:41 +00004989 *BestCursor = cursor;
4990 return CXChildVisit_Recurse;
4991}
4992
4993CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004994 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004995 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004996 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004997 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004998
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004999 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5001
5002 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5003 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5004
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005005 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 CXFile SearchFile;
5007 unsigned SearchLine, SearchColumn;
5008 CXFile ResultFile;
5009 unsigned ResultLine, ResultColumn;
5010 CXString SearchFileName, ResultFileName, KindSpelling, USR;
5011 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
5012 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005013
5014 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5015 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005016 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00005017 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 SearchFileName = clang_getFileName(SearchFile);
5019 ResultFileName = clang_getFileName(ResultFile);
5020 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5021 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005022 *Log << llvm::format("(%s:%d:%d) = %s",
5023 clang_getCString(SearchFileName), SearchLine, SearchColumn,
5024 clang_getCString(KindSpelling))
5025 << llvm::format("(%s:%d:%d):%s%s",
5026 clang_getCString(ResultFileName), ResultLine, ResultColumn,
5027 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 clang_disposeString(SearchFileName);
5029 clang_disposeString(ResultFileName);
5030 clang_disposeString(KindSpelling);
5031 clang_disposeString(USR);
5032
5033 CXCursor Definition = clang_getCursorDefinition(Result);
5034 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5035 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5036 CXString DefinitionKindSpelling
5037 = clang_getCursorKindSpelling(Definition.kind);
5038 CXFile DefinitionFile;
5039 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005040 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005041 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005043 *Log << llvm::format(" -> %s(%s:%d:%d)",
5044 clang_getCString(DefinitionKindSpelling),
5045 clang_getCString(DefinitionFileName),
5046 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 clang_disposeString(DefinitionFileName);
5048 clang_disposeString(DefinitionKindSpelling);
5049 }
5050 }
5051
5052 return Result;
5053}
5054
5055CXCursor clang_getNullCursor(void) {
5056 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5057}
5058
5059unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005060 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5061 // can't set consistently. For example, when visiting a DeclStmt we will set
5062 // it but we don't set it on the result of clang_getCursorDefinition for
5063 // a reference of the same declaration.
5064 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5065 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5066 // to provide that kind of info.
5067 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005068 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005069 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005070 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005071
Guy Benyei11169dd2012-12-18 14:30:41 +00005072 return X == Y;
5073}
5074
5075unsigned clang_hashCursor(CXCursor C) {
5076 unsigned Index = 0;
5077 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5078 Index = 1;
5079
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005080 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 std::make_pair(C.kind, C.data[Index]));
5082}
5083
5084unsigned clang_isInvalid(enum CXCursorKind K) {
5085 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5086}
5087
5088unsigned clang_isDeclaration(enum CXCursorKind K) {
5089 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5090 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5091}
5092
5093unsigned clang_isReference(enum CXCursorKind K) {
5094 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5095}
5096
5097unsigned clang_isExpression(enum CXCursorKind K) {
5098 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5099}
5100
5101unsigned clang_isStatement(enum CXCursorKind K) {
5102 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5103}
5104
5105unsigned clang_isAttribute(enum CXCursorKind K) {
5106 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5107}
5108
5109unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5110 return K == CXCursor_TranslationUnit;
5111}
5112
5113unsigned clang_isPreprocessing(enum CXCursorKind K) {
5114 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5115}
5116
5117unsigned clang_isUnexposed(enum CXCursorKind K) {
5118 switch (K) {
5119 case CXCursor_UnexposedDecl:
5120 case CXCursor_UnexposedExpr:
5121 case CXCursor_UnexposedStmt:
5122 case CXCursor_UnexposedAttr:
5123 return true;
5124 default:
5125 return false;
5126 }
5127}
5128
5129CXCursorKind clang_getCursorKind(CXCursor C) {
5130 return C.kind;
5131}
5132
5133CXSourceLocation clang_getCursorLocation(CXCursor C) {
5134 if (clang_isReference(C.kind)) {
5135 switch (C.kind) {
5136 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005137 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 = getCursorObjCSuperClassRef(C);
5139 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5140 }
5141
5142 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005143 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 = getCursorObjCProtocolRef(C);
5145 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5146 }
5147
5148 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005149 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 = getCursorObjCClassRef(C);
5151 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5152 }
5153
5154 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005155 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5157 }
5158
5159 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005160 std::pair<const TemplateDecl *, SourceLocation> P =
5161 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5163 }
5164
5165 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005166 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005167 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5168 }
5169
5170 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005171 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5173 }
5174
5175 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005176 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5178 }
5179
5180 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005181 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 if (!BaseSpec)
5183 return clang_getNullLocation();
5184
5185 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5186 return cxloc::translateSourceLocation(getCursorContext(C),
5187 TSInfo->getTypeLoc().getBeginLoc());
5188
5189 return cxloc::translateSourceLocation(getCursorContext(C),
5190 BaseSpec->getLocStart());
5191 }
5192
5193 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005194 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005195 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5196 }
5197
5198 case CXCursor_OverloadedDeclRef:
5199 return cxloc::translateSourceLocation(getCursorContext(C),
5200 getCursorOverloadedDeclRef(C).second);
5201
5202 default:
5203 // FIXME: Need a way to enumerate all non-reference cases.
5204 llvm_unreachable("Missed a reference kind");
5205 }
5206 }
5207
5208 if (clang_isExpression(C.kind))
5209 return cxloc::translateSourceLocation(getCursorContext(C),
5210 getLocationFromExpr(getCursorExpr(C)));
5211
5212 if (clang_isStatement(C.kind))
5213 return cxloc::translateSourceLocation(getCursorContext(C),
5214 getCursorStmt(C)->getLocStart());
5215
5216 if (C.kind == CXCursor_PreprocessingDirective) {
5217 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5218 return cxloc::translateSourceLocation(getCursorContext(C), L);
5219 }
5220
5221 if (C.kind == CXCursor_MacroExpansion) {
5222 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005223 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 return cxloc::translateSourceLocation(getCursorContext(C), L);
5225 }
5226
5227 if (C.kind == CXCursor_MacroDefinition) {
5228 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5229 return cxloc::translateSourceLocation(getCursorContext(C), L);
5230 }
5231
5232 if (C.kind == CXCursor_InclusionDirective) {
5233 SourceLocation L
5234 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5235 return cxloc::translateSourceLocation(getCursorContext(C), L);
5236 }
5237
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005238 if (clang_isAttribute(C.kind)) {
5239 SourceLocation L
5240 = cxcursor::getCursorAttr(C)->getLocation();
5241 return cxloc::translateSourceLocation(getCursorContext(C), L);
5242 }
5243
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 if (!clang_isDeclaration(C.kind))
5245 return clang_getNullLocation();
5246
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005247 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 if (!D)
5249 return clang_getNullLocation();
5250
5251 SourceLocation Loc = D->getLocation();
5252 // FIXME: Multiple variables declared in a single declaration
5253 // currently lack the information needed to correctly determine their
5254 // ranges when accounting for the type-specifier. We use context
5255 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5256 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005257 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 if (!cxcursor::isFirstInDeclGroup(C))
5259 Loc = VD->getLocation();
5260 }
5261
5262 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005263 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 Loc = MD->getSelectorStartLoc();
5265
5266 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5267}
5268
5269} // end extern "C"
5270
5271CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5272 assert(TU);
5273
5274 // Guard against an invalid SourceLocation, or we may assert in one
5275 // of the following calls.
5276 if (SLoc.isInvalid())
5277 return clang_getNullCursor();
5278
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005279 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005280
5281 // Translate the given source location to make it point at the beginning of
5282 // the token under the cursor.
5283 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5284 CXXUnit->getASTContext().getLangOpts());
5285
5286 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5287 if (SLoc.isValid()) {
5288 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5289 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5290 /*VisitPreprocessorLast=*/true,
5291 /*VisitIncludedEntities=*/false,
5292 SourceLocation(SLoc));
5293 CursorVis.visitFileRegion();
5294 }
5295
5296 return Result;
5297}
5298
5299static SourceRange getRawCursorExtent(CXCursor C) {
5300 if (clang_isReference(C.kind)) {
5301 switch (C.kind) {
5302 case CXCursor_ObjCSuperClassRef:
5303 return getCursorObjCSuperClassRef(C).second;
5304
5305 case CXCursor_ObjCProtocolRef:
5306 return getCursorObjCProtocolRef(C).second;
5307
5308 case CXCursor_ObjCClassRef:
5309 return getCursorObjCClassRef(C).second;
5310
5311 case CXCursor_TypeRef:
5312 return getCursorTypeRef(C).second;
5313
5314 case CXCursor_TemplateRef:
5315 return getCursorTemplateRef(C).second;
5316
5317 case CXCursor_NamespaceRef:
5318 return getCursorNamespaceRef(C).second;
5319
5320 case CXCursor_MemberRef:
5321 return getCursorMemberRef(C).second;
5322
5323 case CXCursor_CXXBaseSpecifier:
5324 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5325
5326 case CXCursor_LabelRef:
5327 return getCursorLabelRef(C).second;
5328
5329 case CXCursor_OverloadedDeclRef:
5330 return getCursorOverloadedDeclRef(C).second;
5331
5332 case CXCursor_VariableRef:
5333 return getCursorVariableRef(C).second;
5334
5335 default:
5336 // FIXME: Need a way to enumerate all non-reference cases.
5337 llvm_unreachable("Missed a reference kind");
5338 }
5339 }
5340
5341 if (clang_isExpression(C.kind))
5342 return getCursorExpr(C)->getSourceRange();
5343
5344 if (clang_isStatement(C.kind))
5345 return getCursorStmt(C)->getSourceRange();
5346
5347 if (clang_isAttribute(C.kind))
5348 return getCursorAttr(C)->getRange();
5349
5350 if (C.kind == CXCursor_PreprocessingDirective)
5351 return cxcursor::getCursorPreprocessingDirective(C);
5352
5353 if (C.kind == CXCursor_MacroExpansion) {
5354 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005355 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 return TU->mapRangeFromPreamble(Range);
5357 }
5358
5359 if (C.kind == CXCursor_MacroDefinition) {
5360 ASTUnit *TU = getCursorASTUnit(C);
5361 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5362 return TU->mapRangeFromPreamble(Range);
5363 }
5364
5365 if (C.kind == CXCursor_InclusionDirective) {
5366 ASTUnit *TU = getCursorASTUnit(C);
5367 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5368 return TU->mapRangeFromPreamble(Range);
5369 }
5370
5371 if (C.kind == CXCursor_TranslationUnit) {
5372 ASTUnit *TU = getCursorASTUnit(C);
5373 FileID MainID = TU->getSourceManager().getMainFileID();
5374 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5375 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5376 return SourceRange(Start, End);
5377 }
5378
5379 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005380 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005381 if (!D)
5382 return SourceRange();
5383
5384 SourceRange R = D->getSourceRange();
5385 // FIXME: Multiple variables declared in a single declaration
5386 // currently lack the information needed to correctly determine their
5387 // ranges when accounting for the type-specifier. We use context
5388 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5389 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005390 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005391 if (!cxcursor::isFirstInDeclGroup(C))
5392 R.setBegin(VD->getLocation());
5393 }
5394 return R;
5395 }
5396 return SourceRange();
5397}
5398
5399/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5400/// the decl-specifier-seq for declarations.
5401static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5402 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005403 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005404 if (!D)
5405 return SourceRange();
5406
5407 SourceRange R = D->getSourceRange();
5408
5409 // Adjust the start of the location for declarations preceded by
5410 // declaration specifiers.
5411 SourceLocation StartLoc;
5412 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5413 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5414 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005415 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005416 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5417 StartLoc = TI->getTypeLoc().getLocStart();
5418 }
5419
5420 if (StartLoc.isValid() && R.getBegin().isValid() &&
5421 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5422 R.setBegin(StartLoc);
5423
5424 // FIXME: Multiple variables declared in a single declaration
5425 // currently lack the information needed to correctly determine their
5426 // ranges when accounting for the type-specifier. We use context
5427 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5428 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005429 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005430 if (!cxcursor::isFirstInDeclGroup(C))
5431 R.setBegin(VD->getLocation());
5432 }
5433
5434 return R;
5435 }
5436
5437 return getRawCursorExtent(C);
5438}
5439
5440extern "C" {
5441
5442CXSourceRange clang_getCursorExtent(CXCursor C) {
5443 SourceRange R = getRawCursorExtent(C);
5444 if (R.isInvalid())
5445 return clang_getNullRange();
5446
5447 return cxloc::translateSourceRange(getCursorContext(C), R);
5448}
5449
5450CXCursor clang_getCursorReferenced(CXCursor C) {
5451 if (clang_isInvalid(C.kind))
5452 return clang_getNullCursor();
5453
5454 CXTranslationUnit tu = getCursorTU(C);
5455 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005456 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 if (!D)
5458 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005459 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005460 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005461 if (const ObjCPropertyImplDecl *PropImpl =
5462 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5464 return MakeCXCursor(Property, tu);
5465
5466 return C;
5467 }
5468
5469 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005470 const Expr *E = getCursorExpr(C);
5471 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005472 if (D) {
5473 CXCursor declCursor = MakeCXCursor(D, tu);
5474 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5475 declCursor);
5476 return declCursor;
5477 }
5478
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005479 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005480 return MakeCursorOverloadedDeclRef(Ovl, tu);
5481
5482 return clang_getNullCursor();
5483 }
5484
5485 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005486 const Stmt *S = getCursorStmt(C);
5487 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005488 if (LabelDecl *label = Goto->getLabel())
5489 if (LabelStmt *labelS = label->getStmt())
5490 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5491
5492 return clang_getNullCursor();
5493 }
Richard Smith66a81862015-05-04 02:25:31 +00005494
Guy Benyei11169dd2012-12-18 14:30:41 +00005495 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005496 if (const MacroDefinitionRecord *Def =
5497 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005498 return MakeMacroDefinitionCursor(Def, tu);
5499 }
5500
5501 if (!clang_isReference(C.kind))
5502 return clang_getNullCursor();
5503
5504 switch (C.kind) {
5505 case CXCursor_ObjCSuperClassRef:
5506 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5507
5508 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005509 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5510 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 return MakeCXCursor(Def, tu);
5512
5513 return MakeCXCursor(Prot, tu);
5514 }
5515
5516 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005517 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5518 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005519 return MakeCXCursor(Def, tu);
5520
5521 return MakeCXCursor(Class, tu);
5522 }
5523
5524 case CXCursor_TypeRef:
5525 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5526
5527 case CXCursor_TemplateRef:
5528 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5529
5530 case CXCursor_NamespaceRef:
5531 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5532
5533 case CXCursor_MemberRef:
5534 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5535
5536 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005537 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005538 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5539 tu ));
5540 }
5541
5542 case CXCursor_LabelRef:
5543 // FIXME: We end up faking the "parent" declaration here because we
5544 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005545 return MakeCXCursor(getCursorLabelRef(C).first,
5546 cxtu::getASTUnit(tu)->getASTContext()
5547 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005548 tu);
5549
5550 case CXCursor_OverloadedDeclRef:
5551 return C;
5552
5553 case CXCursor_VariableRef:
5554 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5555
5556 default:
5557 // We would prefer to enumerate all non-reference cursor kinds here.
5558 llvm_unreachable("Unhandled reference cursor kind");
5559 }
5560}
5561
5562CXCursor clang_getCursorDefinition(CXCursor C) {
5563 if (clang_isInvalid(C.kind))
5564 return clang_getNullCursor();
5565
5566 CXTranslationUnit TU = getCursorTU(C);
5567
5568 bool WasReference = false;
5569 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5570 C = clang_getCursorReferenced(C);
5571 WasReference = true;
5572 }
5573
5574 if (C.kind == CXCursor_MacroExpansion)
5575 return clang_getCursorReferenced(C);
5576
5577 if (!clang_isDeclaration(C.kind))
5578 return clang_getNullCursor();
5579
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005580 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005581 if (!D)
5582 return clang_getNullCursor();
5583
5584 switch (D->getKind()) {
5585 // Declaration kinds that don't really separate the notions of
5586 // declaration and definition.
5587 case Decl::Namespace:
5588 case Decl::Typedef:
5589 case Decl::TypeAlias:
5590 case Decl::TypeAliasTemplate:
5591 case Decl::TemplateTypeParm:
5592 case Decl::EnumConstant:
5593 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005594 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 case Decl::IndirectField:
5596 case Decl::ObjCIvar:
5597 case Decl::ObjCAtDefsField:
5598 case Decl::ImplicitParam:
5599 case Decl::ParmVar:
5600 case Decl::NonTypeTemplateParm:
5601 case Decl::TemplateTemplateParm:
5602 case Decl::ObjCCategoryImpl:
5603 case Decl::ObjCImplementation:
5604 case Decl::AccessSpec:
5605 case Decl::LinkageSpec:
5606 case Decl::ObjCPropertyImpl:
5607 case Decl::FileScopeAsm:
5608 case Decl::StaticAssert:
5609 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005610 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005611 case Decl::Label: // FIXME: Is this right??
5612 case Decl::ClassScopeFunctionSpecialization:
5613 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005614 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005615 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005616 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005617 return C;
5618
5619 // Declaration kinds that don't make any sense here, but are
5620 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005621 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005622 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005623 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005624 break;
5625
5626 // Declaration kinds for which the definition is not resolvable.
5627 case Decl::UnresolvedUsingTypename:
5628 case Decl::UnresolvedUsingValue:
5629 break;
5630
5631 case Decl::UsingDirective:
5632 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5633 TU);
5634
5635 case Decl::NamespaceAlias:
5636 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5637
5638 case Decl::Enum:
5639 case Decl::Record:
5640 case Decl::CXXRecord:
5641 case Decl::ClassTemplateSpecialization:
5642 case Decl::ClassTemplatePartialSpecialization:
5643 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5644 return MakeCXCursor(Def, TU);
5645 return clang_getNullCursor();
5646
5647 case Decl::Function:
5648 case Decl::CXXMethod:
5649 case Decl::CXXConstructor:
5650 case Decl::CXXDestructor:
5651 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005652 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005654 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 return clang_getNullCursor();
5656 }
5657
Larisse Voufo39a1e502013-08-06 01:03:05 +00005658 case Decl::Var:
5659 case Decl::VarTemplateSpecialization:
5660 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005661 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005662 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 return MakeCXCursor(Def, TU);
5664 return clang_getNullCursor();
5665 }
5666
5667 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005668 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005669 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5670 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5671 return clang_getNullCursor();
5672 }
5673
5674 case Decl::ClassTemplate: {
5675 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5676 ->getDefinition())
5677 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5678 TU);
5679 return clang_getNullCursor();
5680 }
5681
Larisse Voufo39a1e502013-08-06 01:03:05 +00005682 case Decl::VarTemplate: {
5683 if (VarDecl *Def =
5684 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5685 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5686 return clang_getNullCursor();
5687 }
5688
Guy Benyei11169dd2012-12-18 14:30:41 +00005689 case Decl::Using:
5690 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5691 D->getLocation(), TU);
5692
5693 case Decl::UsingShadow:
5694 return clang_getCursorDefinition(
5695 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5696 TU));
5697
5698 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005699 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005700 if (Method->isThisDeclarationADefinition())
5701 return C;
5702
5703 // Dig out the method definition in the associated
5704 // @implementation, if we have it.
5705 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005706 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005707 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5708 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5709 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5710 Method->isInstanceMethod()))
5711 if (Def->isThisDeclarationADefinition())
5712 return MakeCXCursor(Def, TU);
5713
5714 return clang_getNullCursor();
5715 }
5716
5717 case Decl::ObjCCategory:
5718 if (ObjCCategoryImplDecl *Impl
5719 = cast<ObjCCategoryDecl>(D)->getImplementation())
5720 return MakeCXCursor(Impl, TU);
5721 return clang_getNullCursor();
5722
5723 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005724 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005725 return MakeCXCursor(Def, TU);
5726 return clang_getNullCursor();
5727
5728 case Decl::ObjCInterface: {
5729 // There are two notions of a "definition" for an Objective-C
5730 // class: the interface and its implementation. When we resolved a
5731 // reference to an Objective-C class, produce the @interface as
5732 // the definition; when we were provided with the interface,
5733 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005734 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005735 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005736 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005737 return MakeCXCursor(Def, TU);
5738 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5739 return MakeCXCursor(Impl, TU);
5740 return clang_getNullCursor();
5741 }
5742
5743 case Decl::ObjCProperty:
5744 // FIXME: We don't really know where to find the
5745 // ObjCPropertyImplDecls that implement this property.
5746 return clang_getNullCursor();
5747
5748 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005749 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005751 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 return MakeCXCursor(Def, TU);
5753
5754 return clang_getNullCursor();
5755
5756 case Decl::Friend:
5757 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5758 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5759 return clang_getNullCursor();
5760
5761 case Decl::FriendTemplate:
5762 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5763 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5764 return clang_getNullCursor();
5765 }
5766
5767 return clang_getNullCursor();
5768}
5769
5770unsigned clang_isCursorDefinition(CXCursor C) {
5771 if (!clang_isDeclaration(C.kind))
5772 return 0;
5773
5774 return clang_getCursorDefinition(C) == C;
5775}
5776
5777CXCursor clang_getCanonicalCursor(CXCursor C) {
5778 if (!clang_isDeclaration(C.kind))
5779 return C;
5780
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005781 if (const Decl *D = getCursorDecl(C)) {
5782 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005783 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5784 return MakeCXCursor(CatD, getCursorTU(C));
5785
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005786 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5787 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 return MakeCXCursor(IFD, getCursorTU(C));
5789
5790 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5791 }
5792
5793 return C;
5794}
5795
5796int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5797 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5798}
5799
5800unsigned clang_getNumOverloadedDecls(CXCursor C) {
5801 if (C.kind != CXCursor_OverloadedDeclRef)
5802 return 0;
5803
5804 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005805 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005806 return E->getNumDecls();
5807
5808 if (OverloadedTemplateStorage *S
5809 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5810 return S->size();
5811
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005812 const Decl *D = Storage.get<const Decl *>();
5813 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005814 return Using->shadow_size();
5815
5816 return 0;
5817}
5818
5819CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5820 if (cursor.kind != CXCursor_OverloadedDeclRef)
5821 return clang_getNullCursor();
5822
5823 if (index >= clang_getNumOverloadedDecls(cursor))
5824 return clang_getNullCursor();
5825
5826 CXTranslationUnit TU = getCursorTU(cursor);
5827 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005828 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005829 return MakeCXCursor(E->decls_begin()[index], TU);
5830
5831 if (OverloadedTemplateStorage *S
5832 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5833 return MakeCXCursor(S->begin()[index], TU);
5834
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005835 const Decl *D = Storage.get<const Decl *>();
5836 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005837 // FIXME: This is, unfortunately, linear time.
5838 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5839 std::advance(Pos, index);
5840 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5841 }
5842
5843 return clang_getNullCursor();
5844}
5845
5846void clang_getDefinitionSpellingAndExtent(CXCursor C,
5847 const char **startBuf,
5848 const char **endBuf,
5849 unsigned *startLine,
5850 unsigned *startColumn,
5851 unsigned *endLine,
5852 unsigned *endColumn) {
5853 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005854 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005855 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5856
5857 SourceManager &SM = FD->getASTContext().getSourceManager();
5858 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5859 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5860 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5861 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5862 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5863 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5864}
5865
5866
5867CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5868 unsigned PieceIndex) {
5869 RefNamePieces Pieces;
5870
5871 switch (C.kind) {
5872 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005873 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005874 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5875 E->getQualifierLoc().getSourceRange());
5876 break;
5877
5878 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005879 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5880 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5881 Pieces =
5882 buildPieces(NameFlags, false, E->getNameInfo(),
5883 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5884 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 break;
5886
5887 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005888 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005889 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005890 const Expr *Callee = OCE->getCallee();
5891 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005892 Callee = ICE->getSubExpr();
5893
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005894 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005895 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5896 DRE->getQualifierLoc().getSourceRange());
5897 }
5898 break;
5899
5900 default:
5901 break;
5902 }
5903
5904 if (Pieces.empty()) {
5905 if (PieceIndex == 0)
5906 return clang_getCursorExtent(C);
5907 } else if (PieceIndex < Pieces.size()) {
5908 SourceRange R = Pieces[PieceIndex];
5909 if (R.isValid())
5910 return cxloc::translateSourceRange(getCursorContext(C), R);
5911 }
5912
5913 return clang_getNullRange();
5914}
5915
5916void clang_enableStackTraces(void) {
5917 llvm::sys::PrintStackTraceOnErrorSignal();
5918}
5919
5920void clang_executeOnThread(void (*fn)(void*), void *user_data,
5921 unsigned stack_size) {
5922 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5923}
5924
5925} // end: extern "C"
5926
5927//===----------------------------------------------------------------------===//
5928// Token-based Operations.
5929//===----------------------------------------------------------------------===//
5930
5931/* CXToken layout:
5932 * int_data[0]: a CXTokenKind
5933 * int_data[1]: starting token location
5934 * int_data[2]: token length
5935 * int_data[3]: reserved
5936 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5937 * otherwise unused.
5938 */
5939extern "C" {
5940
5941CXTokenKind clang_getTokenKind(CXToken CXTok) {
5942 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5943}
5944
5945CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5946 switch (clang_getTokenKind(CXTok)) {
5947 case CXToken_Identifier:
5948 case CXToken_Keyword:
5949 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005950 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005951 ->getNameStart());
5952
5953 case CXToken_Literal: {
5954 // We have stashed the starting pointer in the ptr_data field. Use it.
5955 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005956 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005957 }
5958
5959 case CXToken_Punctuation:
5960 case CXToken_Comment:
5961 break;
5962 }
5963
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005964 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005965 LOG_BAD_TU(TU);
5966 return cxstring::createEmpty();
5967 }
5968
Guy Benyei11169dd2012-12-18 14:30:41 +00005969 // We have to find the starting buffer pointer the hard way, by
5970 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005971 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005972 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005973 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005974
5975 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5976 std::pair<FileID, unsigned> LocInfo
5977 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5978 bool Invalid = false;
5979 StringRef Buffer
5980 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5981 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005982 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005983
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005984 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005985}
5986
5987CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005988 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005989 LOG_BAD_TU(TU);
5990 return clang_getNullLocation();
5991 }
5992
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005993 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005994 if (!CXXUnit)
5995 return clang_getNullLocation();
5996
5997 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5998 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5999}
6000
6001CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006002 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006003 LOG_BAD_TU(TU);
6004 return clang_getNullRange();
6005 }
6006
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006007 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006008 if (!CXXUnit)
6009 return clang_getNullRange();
6010
6011 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
6012 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6013}
6014
6015static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6016 SmallVectorImpl<CXToken> &CXTokens) {
6017 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6018 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006019 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006020 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006021 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006022
6023 // Cannot tokenize across files.
6024 if (BeginLocInfo.first != EndLocInfo.first)
6025 return;
6026
6027 // Create a lexer
6028 bool Invalid = false;
6029 StringRef Buffer
6030 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6031 if (Invalid)
6032 return;
6033
6034 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6035 CXXUnit->getASTContext().getLangOpts(),
6036 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6037 Lex.SetCommentRetentionState(true);
6038
6039 // Lex tokens until we hit the end of the range.
6040 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6041 Token Tok;
6042 bool previousWasAt = false;
6043 do {
6044 // Lex the next token
6045 Lex.LexFromRawLexer(Tok);
6046 if (Tok.is(tok::eof))
6047 break;
6048
6049 // Initialize the CXToken.
6050 CXToken CXTok;
6051
6052 // - Common fields
6053 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6054 CXTok.int_data[2] = Tok.getLength();
6055 CXTok.int_data[3] = 0;
6056
6057 // - Kind-specific fields
6058 if (Tok.isLiteral()) {
6059 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006060 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006061 } else if (Tok.is(tok::raw_identifier)) {
6062 // Lookup the identifier to determine whether we have a keyword.
6063 IdentifierInfo *II
6064 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6065
6066 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6067 CXTok.int_data[0] = CXToken_Keyword;
6068 }
6069 else {
6070 CXTok.int_data[0] = Tok.is(tok::identifier)
6071 ? CXToken_Identifier
6072 : CXToken_Keyword;
6073 }
6074 CXTok.ptr_data = II;
6075 } else if (Tok.is(tok::comment)) {
6076 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006077 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006078 } else {
6079 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006080 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006081 }
6082 CXTokens.push_back(CXTok);
6083 previousWasAt = Tok.is(tok::at);
6084 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6085}
6086
6087void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6088 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006089 LOG_FUNC_SECTION {
6090 *Log << TU << ' ' << Range;
6091 }
6092
Guy Benyei11169dd2012-12-18 14:30:41 +00006093 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006094 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006095 if (NumTokens)
6096 *NumTokens = 0;
6097
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006098 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006099 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006100 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006101 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006102
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006103 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006104 if (!CXXUnit || !Tokens || !NumTokens)
6105 return;
6106
6107 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6108
6109 SourceRange R = cxloc::translateCXSourceRange(Range);
6110 if (R.isInvalid())
6111 return;
6112
6113 SmallVector<CXToken, 32> CXTokens;
6114 getTokens(CXXUnit, R, CXTokens);
6115
6116 if (CXTokens.empty())
6117 return;
6118
6119 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6120 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6121 *NumTokens = CXTokens.size();
6122}
6123
6124void clang_disposeTokens(CXTranslationUnit TU,
6125 CXToken *Tokens, unsigned NumTokens) {
6126 free(Tokens);
6127}
6128
6129} // end: extern "C"
6130
6131//===----------------------------------------------------------------------===//
6132// Token annotation APIs.
6133//===----------------------------------------------------------------------===//
6134
Guy Benyei11169dd2012-12-18 14:30:41 +00006135static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6136 CXCursor parent,
6137 CXClientData client_data);
6138static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6139 CXClientData client_data);
6140
6141namespace {
6142class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006143 CXToken *Tokens;
6144 CXCursor *Cursors;
6145 unsigned NumTokens;
6146 unsigned TokIdx;
6147 unsigned PreprocessingTokIdx;
6148 CursorVisitor AnnotateVis;
6149 SourceManager &SrcMgr;
6150 bool HasContextSensitiveKeywords;
6151
6152 struct PostChildrenInfo {
6153 CXCursor Cursor;
6154 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006155 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006156 unsigned BeforeChildrenTokenIdx;
6157 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006158 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006159
6160 CXToken &getTok(unsigned Idx) {
6161 assert(Idx < NumTokens);
6162 return Tokens[Idx];
6163 }
6164 const CXToken &getTok(unsigned Idx) const {
6165 assert(Idx < NumTokens);
6166 return Tokens[Idx];
6167 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006168 bool MoreTokens() const { return TokIdx < NumTokens; }
6169 unsigned NextToken() const { return TokIdx; }
6170 void AdvanceToken() { ++TokIdx; }
6171 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006172 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006173 }
6174 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006175 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006176 }
6177 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006178 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006179 }
6180
6181 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006182 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006183 SourceRange);
6184
6185public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006186 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006187 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006188 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006189 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006190 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006191 AnnotateTokensVisitor, this,
6192 /*VisitPreprocessorLast=*/true,
6193 /*VisitIncludedEntities=*/false,
6194 RegionOfInterest,
6195 /*VisitDeclsOnly=*/false,
6196 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006197 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006198 HasContextSensitiveKeywords(false) { }
6199
6200 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6201 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6202 bool postVisitChildren(CXCursor cursor);
6203 void AnnotateTokens();
6204
6205 /// \brief Determine whether the annotator saw any cursors that have
6206 /// context-sensitive keywords.
6207 bool hasContextSensitiveKeywords() const {
6208 return HasContextSensitiveKeywords;
6209 }
6210
6211 ~AnnotateTokensWorker() {
6212 assert(PostChildrenInfos.empty());
6213 }
6214};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006215}
Guy Benyei11169dd2012-12-18 14:30:41 +00006216
6217void AnnotateTokensWorker::AnnotateTokens() {
6218 // Walk the AST within the region of interest, annotating tokens
6219 // along the way.
6220 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006221}
Guy Benyei11169dd2012-12-18 14:30:41 +00006222
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006223static inline void updateCursorAnnotation(CXCursor &Cursor,
6224 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006225 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006226 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006227 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006228}
6229
6230/// \brief It annotates and advances tokens with a cursor until the comparison
6231//// between the cursor location and the source range is the same as
6232/// \arg compResult.
6233///
6234/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6235/// Pass RangeOverlap to annotate tokens inside a range.
6236void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6237 RangeComparisonResult compResult,
6238 SourceRange range) {
6239 while (MoreTokens()) {
6240 const unsigned I = NextToken();
6241 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006242 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6243 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006244
6245 SourceLocation TokLoc = GetTokenLoc(I);
6246 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006247 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006248 AdvanceToken();
6249 continue;
6250 }
6251 break;
6252 }
6253}
6254
6255/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006256/// \returns true if it advanced beyond all macro tokens, false otherwise.
6257bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006258 CXCursor updateC,
6259 RangeComparisonResult compResult,
6260 SourceRange range) {
6261 assert(MoreTokens());
6262 assert(isFunctionMacroToken(NextToken()) &&
6263 "Should be called only for macro arg tokens");
6264
6265 // This works differently than annotateAndAdvanceTokens; because expanded
6266 // macro arguments can have arbitrary translation-unit source order, we do not
6267 // advance the token index one by one until a token fails the range test.
6268 // We only advance once past all of the macro arg tokens if all of them
6269 // pass the range test. If one of them fails we keep the token index pointing
6270 // at the start of the macro arg tokens so that the failing token will be
6271 // annotated by a subsequent annotation try.
6272
6273 bool atLeastOneCompFail = false;
6274
6275 unsigned I = NextToken();
6276 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6277 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6278 if (TokLoc.isFileID())
6279 continue; // not macro arg token, it's parens or comma.
6280 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6281 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6282 Cursors[I] = updateC;
6283 } else
6284 atLeastOneCompFail = true;
6285 }
6286
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006287 if (atLeastOneCompFail)
6288 return false;
6289
6290 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6291 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006292}
6293
6294enum CXChildVisitResult
6295AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006296 SourceRange cursorRange = getRawCursorExtent(cursor);
6297 if (cursorRange.isInvalid())
6298 return CXChildVisit_Recurse;
6299
6300 if (!HasContextSensitiveKeywords) {
6301 // Objective-C properties can have context-sensitive keywords.
6302 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006303 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006304 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6305 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6306 }
6307 // Objective-C methods can have context-sensitive keywords.
6308 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6309 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006310 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006311 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6312 if (Method->getObjCDeclQualifier())
6313 HasContextSensitiveKeywords = true;
6314 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006315 for (const auto *P : Method->params()) {
6316 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006317 HasContextSensitiveKeywords = true;
6318 break;
6319 }
6320 }
6321 }
6322 }
6323 }
6324 // C++ methods can have context-sensitive keywords.
6325 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006326 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006327 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6328 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6329 HasContextSensitiveKeywords = true;
6330 }
6331 }
6332 // C++ classes can have context-sensitive keywords.
6333 else if (cursor.kind == CXCursor_StructDecl ||
6334 cursor.kind == CXCursor_ClassDecl ||
6335 cursor.kind == CXCursor_ClassTemplate ||
6336 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006337 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006338 if (D->hasAttr<FinalAttr>())
6339 HasContextSensitiveKeywords = true;
6340 }
6341 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006342
6343 // Don't override a property annotation with its getter/setter method.
6344 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6345 parent.kind == CXCursor_ObjCPropertyDecl)
6346 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006347
6348 if (clang_isPreprocessing(cursor.kind)) {
6349 // Items in the preprocessing record are kept separate from items in
6350 // declarations, so we keep a separate token index.
6351 unsigned SavedTokIdx = TokIdx;
6352 TokIdx = PreprocessingTokIdx;
6353
6354 // Skip tokens up until we catch up to the beginning of the preprocessing
6355 // entry.
6356 while (MoreTokens()) {
6357 const unsigned I = NextToken();
6358 SourceLocation TokLoc = GetTokenLoc(I);
6359 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6360 case RangeBefore:
6361 AdvanceToken();
6362 continue;
6363 case RangeAfter:
6364 case RangeOverlap:
6365 break;
6366 }
6367 break;
6368 }
6369
6370 // Look at all of the tokens within this range.
6371 while (MoreTokens()) {
6372 const unsigned I = NextToken();
6373 SourceLocation TokLoc = GetTokenLoc(I);
6374 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6375 case RangeBefore:
6376 llvm_unreachable("Infeasible");
6377 case RangeAfter:
6378 break;
6379 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006380 // For macro expansions, just note where the beginning of the macro
6381 // expansion occurs.
6382 if (cursor.kind == CXCursor_MacroExpansion) {
6383 if (TokLoc == cursorRange.getBegin())
6384 Cursors[I] = cursor;
6385 AdvanceToken();
6386 break;
6387 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006388 // We may have already annotated macro names inside macro definitions.
6389 if (Cursors[I].kind != CXCursor_MacroExpansion)
6390 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006391 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006392 continue;
6393 }
6394 break;
6395 }
6396
6397 // Save the preprocessing token index; restore the non-preprocessing
6398 // token index.
6399 PreprocessingTokIdx = TokIdx;
6400 TokIdx = SavedTokIdx;
6401 return CXChildVisit_Recurse;
6402 }
6403
6404 if (cursorRange.isInvalid())
6405 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006406
6407 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006408 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006409 const enum CXCursorKind K = clang_getCursorKind(parent);
6410 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006411 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6412 // Attributes are annotated out-of-order, skip tokens until we reach it.
6413 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 ? clang_getNullCursor() : parent;
6415
6416 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6417
6418 // Avoid having the cursor of an expression "overwrite" the annotation of the
6419 // variable declaration that it belongs to.
6420 // This can happen for C++ constructor expressions whose range generally
6421 // include the variable declaration, e.g.:
6422 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006423 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006424 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006425 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006426 const unsigned I = NextToken();
6427 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6428 E->getLocStart() == D->getLocation() &&
6429 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006430 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006431 AdvanceToken();
6432 }
6433 }
6434 }
6435
6436 // Before recursing into the children keep some state that we are going
6437 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6438 // extra work after the child nodes are visited.
6439 // Note that we don't call VisitChildren here to avoid traversing statements
6440 // code-recursively which can blow the stack.
6441
6442 PostChildrenInfo Info;
6443 Info.Cursor = cursor;
6444 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006445 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006446 Info.BeforeChildrenTokenIdx = NextToken();
6447 PostChildrenInfos.push_back(Info);
6448
6449 return CXChildVisit_Recurse;
6450}
6451
6452bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6453 if (PostChildrenInfos.empty())
6454 return false;
6455 const PostChildrenInfo &Info = PostChildrenInfos.back();
6456 if (!clang_equalCursors(Info.Cursor, cursor))
6457 return false;
6458
6459 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6460 const unsigned AfterChildren = NextToken();
6461 SourceRange cursorRange = Info.CursorRange;
6462
6463 // Scan the tokens that are at the end of the cursor, but are not captured
6464 // but the child cursors.
6465 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6466
6467 // Scan the tokens that are at the beginning of the cursor, but are not
6468 // capture by the child cursors.
6469 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6470 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6471 break;
6472
6473 Cursors[I] = cursor;
6474 }
6475
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006476 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6477 // encountered the attribute cursor.
6478 if (clang_isAttribute(cursor.kind))
6479 TokIdx = Info.BeforeReachingCursorIdx;
6480
Guy Benyei11169dd2012-12-18 14:30:41 +00006481 PostChildrenInfos.pop_back();
6482 return false;
6483}
6484
6485static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6486 CXCursor parent,
6487 CXClientData client_data) {
6488 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6489}
6490
6491static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6492 CXClientData client_data) {
6493 return static_cast<AnnotateTokensWorker*>(client_data)->
6494 postVisitChildren(cursor);
6495}
6496
6497namespace {
6498
6499/// \brief Uses the macro expansions in the preprocessing record to find
6500/// and mark tokens that are macro arguments. This info is used by the
6501/// AnnotateTokensWorker.
6502class MarkMacroArgTokensVisitor {
6503 SourceManager &SM;
6504 CXToken *Tokens;
6505 unsigned NumTokens;
6506 unsigned CurIdx;
6507
6508public:
6509 MarkMacroArgTokensVisitor(SourceManager &SM,
6510 CXToken *tokens, unsigned numTokens)
6511 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6512
6513 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6514 if (cursor.kind != CXCursor_MacroExpansion)
6515 return CXChildVisit_Continue;
6516
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006517 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006518 if (macroRange.getBegin() == macroRange.getEnd())
6519 return CXChildVisit_Continue; // it's not a function macro.
6520
6521 for (; CurIdx < NumTokens; ++CurIdx) {
6522 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6523 macroRange.getBegin()))
6524 break;
6525 }
6526
6527 if (CurIdx == NumTokens)
6528 return CXChildVisit_Break;
6529
6530 for (; CurIdx < NumTokens; ++CurIdx) {
6531 SourceLocation tokLoc = getTokenLoc(CurIdx);
6532 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6533 break;
6534
6535 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6536 }
6537
6538 if (CurIdx == NumTokens)
6539 return CXChildVisit_Break;
6540
6541 return CXChildVisit_Continue;
6542 }
6543
6544private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006545 CXToken &getTok(unsigned Idx) {
6546 assert(Idx < NumTokens);
6547 return Tokens[Idx];
6548 }
6549 const CXToken &getTok(unsigned Idx) const {
6550 assert(Idx < NumTokens);
6551 return Tokens[Idx];
6552 }
6553
Guy Benyei11169dd2012-12-18 14:30:41 +00006554 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006555 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006556 }
6557
6558 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6559 // The third field is reserved and currently not used. Use it here
6560 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006561 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006562 }
6563};
6564
6565} // end anonymous namespace
6566
6567static CXChildVisitResult
6568MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6569 CXClientData client_data) {
6570 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6571 parent);
6572}
6573
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006574/// \brief Used by \c annotatePreprocessorTokens.
6575/// \returns true if lexing was finished, false otherwise.
6576static bool lexNext(Lexer &Lex, Token &Tok,
6577 unsigned &NextIdx, unsigned NumTokens) {
6578 if (NextIdx >= NumTokens)
6579 return true;
6580
6581 ++NextIdx;
6582 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006583 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006584}
6585
Guy Benyei11169dd2012-12-18 14:30:41 +00006586static void annotatePreprocessorTokens(CXTranslationUnit TU,
6587 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006588 CXCursor *Cursors,
6589 CXToken *Tokens,
6590 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006591 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006592
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006593 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006594 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6595 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006596 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006597 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006598 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006599
6600 if (BeginLocInfo.first != EndLocInfo.first)
6601 return;
6602
6603 StringRef Buffer;
6604 bool Invalid = false;
6605 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6606 if (Buffer.empty() || Invalid)
6607 return;
6608
6609 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6610 CXXUnit->getASTContext().getLangOpts(),
6611 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6612 Buffer.end());
6613 Lex.SetCommentRetentionState(true);
6614
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006615 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006616 // Lex tokens in raw mode until we hit the end of the range, to avoid
6617 // entering #includes or expanding macros.
6618 while (true) {
6619 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006620 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6621 break;
6622 unsigned TokIdx = NextIdx-1;
6623 assert(Tok.getLocation() ==
6624 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006625
6626 reprocess:
6627 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006628 // We have found a preprocessing directive. Annotate the tokens
6629 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006630 //
6631 // FIXME: Some simple tests here could identify macro definitions and
6632 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006633
6634 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006635 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6636 break;
6637
Craig Topper69186e72014-06-08 08:38:04 +00006638 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006639 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006640 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6641 break;
6642
6643 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006644 IdentifierInfo &II =
6645 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006646 SourceLocation MappedTokLoc =
6647 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6648 MI = getMacroInfo(II, MappedTokLoc, TU);
6649 }
6650 }
6651
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006652 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006653 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006654 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6655 finished = true;
6656 break;
6657 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006658 // If we are in a macro definition, check if the token was ever a
6659 // macro name and annotate it if that's the case.
6660 if (MI) {
6661 SourceLocation SaveLoc = Tok.getLocation();
6662 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006663 MacroDefinitionRecord *MacroDef =
6664 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006665 Tok.setLocation(SaveLoc);
6666 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006667 Cursors[NextIdx - 1] =
6668 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006669 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006670 } while (!Tok.isAtStartOfLine());
6671
6672 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6673 assert(TokIdx <= LastIdx);
6674 SourceLocation EndLoc =
6675 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6676 CXCursor Cursor =
6677 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6678
6679 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006680 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006681
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006682 if (finished)
6683 break;
6684 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006685 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006686 }
6687}
6688
6689// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006690static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6691 CXToken *Tokens, unsigned NumTokens,
6692 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006693 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006694 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6695 setThreadBackgroundPriority();
6696
6697 // Determine the region of interest, which contains all of the tokens.
6698 SourceRange RegionOfInterest;
6699 RegionOfInterest.setBegin(
6700 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6701 RegionOfInterest.setEnd(
6702 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6703 Tokens[NumTokens-1])));
6704
Guy Benyei11169dd2012-12-18 14:30:41 +00006705 // Relex the tokens within the source range to look for preprocessing
6706 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006707 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006708
6709 // If begin location points inside a macro argument, set it to the expansion
6710 // location so we can have the full context when annotating semantically.
6711 {
6712 SourceManager &SM = CXXUnit->getSourceManager();
6713 SourceLocation Loc =
6714 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6715 if (Loc.isMacroID())
6716 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6717 }
6718
Guy Benyei11169dd2012-12-18 14:30:41 +00006719 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6720 // Search and mark tokens that are macro argument expansions.
6721 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6722 Tokens, NumTokens);
6723 CursorVisitor MacroArgMarker(TU,
6724 MarkMacroArgTokensVisitorDelegate, &Visitor,
6725 /*VisitPreprocessorLast=*/true,
6726 /*VisitIncludedEntities=*/false,
6727 RegionOfInterest);
6728 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6729 }
6730
6731 // Annotate all of the source locations in the region of interest that map to
6732 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006733 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006734
6735 // FIXME: We use a ridiculous stack size here because the data-recursion
6736 // algorithm uses a large stack frame than the non-data recursive version,
6737 // and AnnotationTokensWorker currently transforms the data-recursion
6738 // algorithm back into a traditional recursion by explicitly calling
6739 // VisitChildren(). We will need to remove this explicit recursive call.
6740 W.AnnotateTokens();
6741
6742 // If we ran into any entities that involve context-sensitive keywords,
6743 // take another pass through the tokens to mark them as such.
6744 if (W.hasContextSensitiveKeywords()) {
6745 for (unsigned I = 0; I != NumTokens; ++I) {
6746 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6747 continue;
6748
6749 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6750 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006751 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006752 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6753 if (Property->getPropertyAttributesAsWritten() != 0 &&
6754 llvm::StringSwitch<bool>(II->getName())
6755 .Case("readonly", true)
6756 .Case("assign", true)
6757 .Case("unsafe_unretained", true)
6758 .Case("readwrite", true)
6759 .Case("retain", true)
6760 .Case("copy", true)
6761 .Case("nonatomic", true)
6762 .Case("atomic", true)
6763 .Case("getter", true)
6764 .Case("setter", true)
6765 .Case("strong", true)
6766 .Case("weak", true)
6767 .Default(false))
6768 Tokens[I].int_data[0] = CXToken_Keyword;
6769 }
6770 continue;
6771 }
6772
6773 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6774 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6775 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6776 if (llvm::StringSwitch<bool>(II->getName())
6777 .Case("in", true)
6778 .Case("out", true)
6779 .Case("inout", true)
6780 .Case("oneway", true)
6781 .Case("bycopy", true)
6782 .Case("byref", true)
6783 .Default(false))
6784 Tokens[I].int_data[0] = CXToken_Keyword;
6785 continue;
6786 }
6787
6788 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6789 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6790 Tokens[I].int_data[0] = CXToken_Keyword;
6791 continue;
6792 }
6793 }
6794 }
6795}
6796
6797extern "C" {
6798
6799void clang_annotateTokens(CXTranslationUnit TU,
6800 CXToken *Tokens, unsigned NumTokens,
6801 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006802 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006803 LOG_BAD_TU(TU);
6804 return;
6805 }
6806 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006807 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006808 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006809 }
6810
6811 LOG_FUNC_SECTION {
6812 *Log << TU << ' ';
6813 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6814 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6815 *Log << clang_getRange(bloc, eloc);
6816 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006817
6818 // Any token we don't specifically annotate will have a NULL cursor.
6819 CXCursor C = clang_getNullCursor();
6820 for (unsigned I = 0; I != NumTokens; ++I)
6821 Cursors[I] = C;
6822
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006823 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006824 if (!CXXUnit)
6825 return;
6826
6827 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006828
6829 auto AnnotateTokensImpl = [=]() {
6830 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6831 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006832 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006833 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006834 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6835 }
6836}
6837
6838} // end: extern "C"
6839
6840//===----------------------------------------------------------------------===//
6841// Operations for querying linkage of a cursor.
6842//===----------------------------------------------------------------------===//
6843
6844extern "C" {
6845CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6846 if (!clang_isDeclaration(cursor.kind))
6847 return CXLinkage_Invalid;
6848
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006849 const Decl *D = cxcursor::getCursorDecl(cursor);
6850 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006851 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006852 case NoLinkage:
6853 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006854 case InternalLinkage: return CXLinkage_Internal;
6855 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6856 case ExternalLinkage: return CXLinkage_External;
6857 };
6858
6859 return CXLinkage_Invalid;
6860}
6861} // end: extern "C"
6862
6863//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006864// Operations for querying visibility of a cursor.
6865//===----------------------------------------------------------------------===//
6866
6867extern "C" {
6868CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6869 if (!clang_isDeclaration(cursor.kind))
6870 return CXVisibility_Invalid;
6871
6872 const Decl *D = cxcursor::getCursorDecl(cursor);
6873 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6874 switch (ND->getVisibility()) {
6875 case HiddenVisibility: return CXVisibility_Hidden;
6876 case ProtectedVisibility: return CXVisibility_Protected;
6877 case DefaultVisibility: return CXVisibility_Default;
6878 };
6879
6880 return CXVisibility_Invalid;
6881}
6882} // end: extern "C"
6883
6884//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006885// Operations for querying language of a cursor.
6886//===----------------------------------------------------------------------===//
6887
6888static CXLanguageKind getDeclLanguage(const Decl *D) {
6889 if (!D)
6890 return CXLanguage_C;
6891
6892 switch (D->getKind()) {
6893 default:
6894 break;
6895 case Decl::ImplicitParam:
6896 case Decl::ObjCAtDefsField:
6897 case Decl::ObjCCategory:
6898 case Decl::ObjCCategoryImpl:
6899 case Decl::ObjCCompatibleAlias:
6900 case Decl::ObjCImplementation:
6901 case Decl::ObjCInterface:
6902 case Decl::ObjCIvar:
6903 case Decl::ObjCMethod:
6904 case Decl::ObjCProperty:
6905 case Decl::ObjCPropertyImpl:
6906 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006907 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006908 return CXLanguage_ObjC;
6909 case Decl::CXXConstructor:
6910 case Decl::CXXConversion:
6911 case Decl::CXXDestructor:
6912 case Decl::CXXMethod:
6913 case Decl::CXXRecord:
6914 case Decl::ClassTemplate:
6915 case Decl::ClassTemplatePartialSpecialization:
6916 case Decl::ClassTemplateSpecialization:
6917 case Decl::Friend:
6918 case Decl::FriendTemplate:
6919 case Decl::FunctionTemplate:
6920 case Decl::LinkageSpec:
6921 case Decl::Namespace:
6922 case Decl::NamespaceAlias:
6923 case Decl::NonTypeTemplateParm:
6924 case Decl::StaticAssert:
6925 case Decl::TemplateTemplateParm:
6926 case Decl::TemplateTypeParm:
6927 case Decl::UnresolvedUsingTypename:
6928 case Decl::UnresolvedUsingValue:
6929 case Decl::Using:
6930 case Decl::UsingDirective:
6931 case Decl::UsingShadow:
6932 return CXLanguage_CPlusPlus;
6933 }
6934
6935 return CXLanguage_C;
6936}
6937
6938extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006939
6940static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6941 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006942 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006943
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006944 switch (D->getAvailability()) {
6945 case AR_Available:
6946 case AR_NotYetIntroduced:
6947 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006948 return getCursorAvailabilityForDecl(
6949 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006950 return CXAvailability_Available;
6951
6952 case AR_Deprecated:
6953 return CXAvailability_Deprecated;
6954
6955 case AR_Unavailable:
6956 return CXAvailability_NotAvailable;
6957 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006958
6959 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006960}
6961
Guy Benyei11169dd2012-12-18 14:30:41 +00006962enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6963 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006964 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6965 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006966
6967 return CXAvailability_Available;
6968}
6969
6970static CXVersion convertVersion(VersionTuple In) {
6971 CXVersion Out = { -1, -1, -1 };
6972 if (In.empty())
6973 return Out;
6974
6975 Out.Major = In.getMajor();
6976
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006977 Optional<unsigned> Minor = In.getMinor();
6978 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006979 Out.Minor = *Minor;
6980 else
6981 return Out;
6982
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006983 Optional<unsigned> Subminor = In.getSubminor();
6984 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006985 Out.Subminor = *Subminor;
6986
6987 return Out;
6988}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006989
6990static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6991 int *always_deprecated,
6992 CXString *deprecated_message,
6993 int *always_unavailable,
6994 CXString *unavailable_message,
6995 CXPlatformAvailability *availability,
6996 int availability_size) {
6997 bool HadAvailAttr = false;
6998 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006999 for (auto A : D->attrs()) {
7000 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007001 HadAvailAttr = true;
7002 if (always_deprecated)
7003 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007004 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007005 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007006 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007007 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007008 continue;
7009 }
7010
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007011 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007012 HadAvailAttr = true;
7013 if (always_unavailable)
7014 *always_unavailable = 1;
7015 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007016 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007017 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7018 }
7019 continue;
7020 }
7021
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007022 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007023 HadAvailAttr = true;
7024 if (N < availability_size) {
7025 availability[N].Platform
7026 = cxstring::createDup(Avail->getPlatform()->getName());
7027 availability[N].Introduced = convertVersion(Avail->getIntroduced());
7028 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7029 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7030 availability[N].Unavailable = Avail->getUnavailable();
7031 availability[N].Message = cxstring::createDup(Avail->getMessage());
7032 }
7033 ++N;
7034 }
7035 }
7036
7037 if (!HadAvailAttr)
7038 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7039 return getCursorPlatformAvailabilityForDecl(
7040 cast<Decl>(EnumConst->getDeclContext()),
7041 always_deprecated,
7042 deprecated_message,
7043 always_unavailable,
7044 unavailable_message,
7045 availability,
7046 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007047
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007048 return N;
7049}
7050
Guy Benyei11169dd2012-12-18 14:30:41 +00007051int clang_getCursorPlatformAvailability(CXCursor cursor,
7052 int *always_deprecated,
7053 CXString *deprecated_message,
7054 int *always_unavailable,
7055 CXString *unavailable_message,
7056 CXPlatformAvailability *availability,
7057 int availability_size) {
7058 if (always_deprecated)
7059 *always_deprecated = 0;
7060 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007061 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007062 if (always_unavailable)
7063 *always_unavailable = 0;
7064 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007065 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007066
Guy Benyei11169dd2012-12-18 14:30:41 +00007067 if (!clang_isDeclaration(cursor.kind))
7068 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007069
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007070 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007071 if (!D)
7072 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007073
7074 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7075 deprecated_message,
7076 always_unavailable,
7077 unavailable_message,
7078 availability,
7079 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007080}
7081
7082void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7083 clang_disposeString(availability->Platform);
7084 clang_disposeString(availability->Message);
7085}
7086
7087CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7088 if (clang_isDeclaration(cursor.kind))
7089 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7090
7091 return CXLanguage_Invalid;
7092}
7093
7094 /// \brief If the given cursor is the "templated" declaration
7095 /// descibing a class or function template, return the class or
7096 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007097static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007098 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007099 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007100
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007101 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007102 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7103 return FunTmpl;
7104
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007105 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007106 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7107 return ClassTmpl;
7108
7109 return D;
7110}
7111
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007112
7113enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7114 StorageClass sc = SC_None;
7115 const Decl *D = getCursorDecl(C);
7116 if (D) {
7117 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7118 sc = FD->getStorageClass();
7119 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7120 sc = VD->getStorageClass();
7121 } else {
7122 return CX_SC_Invalid;
7123 }
7124 } else {
7125 return CX_SC_Invalid;
7126 }
7127 switch (sc) {
7128 case SC_None:
7129 return CX_SC_None;
7130 case SC_Extern:
7131 return CX_SC_Extern;
7132 case SC_Static:
7133 return CX_SC_Static;
7134 case SC_PrivateExtern:
7135 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007136 case SC_Auto:
7137 return CX_SC_Auto;
7138 case SC_Register:
7139 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007140 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007141 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007142}
7143
Guy Benyei11169dd2012-12-18 14:30:41 +00007144CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7145 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007146 if (const Decl *D = getCursorDecl(cursor)) {
7147 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007148 if (!DC)
7149 return clang_getNullCursor();
7150
7151 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7152 getCursorTU(cursor));
7153 }
7154 }
7155
7156 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007157 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007158 return MakeCXCursor(D, getCursorTU(cursor));
7159 }
7160
7161 return clang_getNullCursor();
7162}
7163
7164CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7165 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007166 if (const Decl *D = getCursorDecl(cursor)) {
7167 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007168 if (!DC)
7169 return clang_getNullCursor();
7170
7171 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7172 getCursorTU(cursor));
7173 }
7174 }
7175
7176 // FIXME: Note that we can't easily compute the lexical context of a
7177 // statement or expression, so we return nothing.
7178 return clang_getNullCursor();
7179}
7180
7181CXFile clang_getIncludedFile(CXCursor cursor) {
7182 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007183 return nullptr;
7184
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007185 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007186 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007187}
7188
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007189unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7190 if (C.kind != CXCursor_ObjCPropertyDecl)
7191 return CXObjCPropertyAttr_noattr;
7192
7193 unsigned Result = CXObjCPropertyAttr_noattr;
7194 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7195 ObjCPropertyDecl::PropertyAttributeKind Attr =
7196 PD->getPropertyAttributesAsWritten();
7197
7198#define SET_CXOBJCPROP_ATTR(A) \
7199 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7200 Result |= CXObjCPropertyAttr_##A
7201 SET_CXOBJCPROP_ATTR(readonly);
7202 SET_CXOBJCPROP_ATTR(getter);
7203 SET_CXOBJCPROP_ATTR(assign);
7204 SET_CXOBJCPROP_ATTR(readwrite);
7205 SET_CXOBJCPROP_ATTR(retain);
7206 SET_CXOBJCPROP_ATTR(copy);
7207 SET_CXOBJCPROP_ATTR(nonatomic);
7208 SET_CXOBJCPROP_ATTR(setter);
7209 SET_CXOBJCPROP_ATTR(atomic);
7210 SET_CXOBJCPROP_ATTR(weak);
7211 SET_CXOBJCPROP_ATTR(strong);
7212 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7213#undef SET_CXOBJCPROP_ATTR
7214
7215 return Result;
7216}
7217
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007218unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7219 if (!clang_isDeclaration(C.kind))
7220 return CXObjCDeclQualifier_None;
7221
7222 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7223 const Decl *D = getCursorDecl(C);
7224 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7225 QT = MD->getObjCDeclQualifier();
7226 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7227 QT = PD->getObjCDeclQualifier();
7228 if (QT == Decl::OBJC_TQ_None)
7229 return CXObjCDeclQualifier_None;
7230
7231 unsigned Result = CXObjCDeclQualifier_None;
7232 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7233 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7234 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7235 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7236 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7237 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7238
7239 return Result;
7240}
7241
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007242unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7243 if (!clang_isDeclaration(C.kind))
7244 return 0;
7245
7246 const Decl *D = getCursorDecl(C);
7247 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7248 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7249 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7250 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7251
7252 return 0;
7253}
7254
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007255unsigned clang_Cursor_isVariadic(CXCursor C) {
7256 if (!clang_isDeclaration(C.kind))
7257 return 0;
7258
7259 const Decl *D = getCursorDecl(C);
7260 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7261 return FD->isVariadic();
7262 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7263 return MD->isVariadic();
7264
7265 return 0;
7266}
7267
Guy Benyei11169dd2012-12-18 14:30:41 +00007268CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7269 if (!clang_isDeclaration(C.kind))
7270 return clang_getNullRange();
7271
7272 const Decl *D = getCursorDecl(C);
7273 ASTContext &Context = getCursorContext(C);
7274 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7275 if (!RC)
7276 return clang_getNullRange();
7277
7278 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7279}
7280
7281CXString clang_Cursor_getRawCommentText(CXCursor C) {
7282 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007283 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007284
7285 const Decl *D = getCursorDecl(C);
7286 ASTContext &Context = getCursorContext(C);
7287 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7288 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7289 StringRef();
7290
7291 // Don't duplicate the string because RawText points directly into source
7292 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007293 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007294}
7295
7296CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7297 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007298 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007299
7300 const Decl *D = getCursorDecl(C);
7301 const ASTContext &Context = getCursorContext(C);
7302 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7303
7304 if (RC) {
7305 StringRef BriefText = RC->getBriefText(Context);
7306
7307 // Don't duplicate the string because RawComment ensures that this memory
7308 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007309 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007310 }
7311
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007312 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007313}
7314
Guy Benyei11169dd2012-12-18 14:30:41 +00007315CXModule clang_Cursor_getModule(CXCursor C) {
7316 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007317 if (const ImportDecl *ImportD =
7318 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007319 return ImportD->getImportedModule();
7320 }
7321
Craig Topper69186e72014-06-08 08:38:04 +00007322 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007323}
7324
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007325CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7326 if (isNotUsableTU(TU)) {
7327 LOG_BAD_TU(TU);
7328 return nullptr;
7329 }
7330 if (!File)
7331 return nullptr;
7332 FileEntry *FE = static_cast<FileEntry *>(File);
7333
7334 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7335 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7336 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7337
Richard Smithfeb54b62014-10-23 02:01:19 +00007338 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007339}
7340
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007341CXFile clang_Module_getASTFile(CXModule CXMod) {
7342 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007343 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007344 Module *Mod = static_cast<Module*>(CXMod);
7345 return const_cast<FileEntry *>(Mod->getASTFile());
7346}
7347
Guy Benyei11169dd2012-12-18 14:30:41 +00007348CXModule clang_Module_getParent(CXModule CXMod) {
7349 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007350 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007351 Module *Mod = static_cast<Module*>(CXMod);
7352 return Mod->Parent;
7353}
7354
7355CXString clang_Module_getName(CXModule CXMod) {
7356 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007357 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007358 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007359 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007360}
7361
7362CXString clang_Module_getFullName(CXModule CXMod) {
7363 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007364 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007365 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007366 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007367}
7368
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007369int clang_Module_isSystem(CXModule CXMod) {
7370 if (!CXMod)
7371 return 0;
7372 Module *Mod = static_cast<Module*>(CXMod);
7373 return Mod->IsSystem;
7374}
7375
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007376unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7377 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007378 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007379 LOG_BAD_TU(TU);
7380 return 0;
7381 }
7382 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007383 return 0;
7384 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007385 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7386 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7387 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007388}
7389
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007390CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7391 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007392 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007393 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007394 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007395 }
7396 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007397 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007398 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007399 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007400
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007401 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7402 if (Index < TopHeaders.size())
7403 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007404
Craig Topper69186e72014-06-08 08:38:04 +00007405 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007406}
7407
7408} // end: extern "C"
7409
7410//===----------------------------------------------------------------------===//
7411// C++ AST instrospection.
7412//===----------------------------------------------------------------------===//
7413
7414extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007415unsigned clang_CXXField_isMutable(CXCursor C) {
7416 if (!clang_isDeclaration(C.kind))
7417 return 0;
7418
7419 if (const auto D = cxcursor::getCursorDecl(C))
7420 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7421 return FD->isMutable() ? 1 : 0;
7422 return 0;
7423}
7424
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007425unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7426 if (!clang_isDeclaration(C.kind))
7427 return 0;
7428
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007429 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007430 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007431 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007432 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7433}
7434
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007435unsigned clang_CXXMethod_isConst(CXCursor C) {
7436 if (!clang_isDeclaration(C.kind))
7437 return 0;
7438
7439 const Decl *D = cxcursor::getCursorDecl(C);
7440 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007441 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007442 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7443}
7444
Guy Benyei11169dd2012-12-18 14:30:41 +00007445unsigned clang_CXXMethod_isStatic(CXCursor C) {
7446 if (!clang_isDeclaration(C.kind))
7447 return 0;
7448
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007449 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007450 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007451 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007452 return (Method && Method->isStatic()) ? 1 : 0;
7453}
7454
7455unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7456 if (!clang_isDeclaration(C.kind))
7457 return 0;
7458
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007459 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007460 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007461 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007462 return (Method && Method->isVirtual()) ? 1 : 0;
7463}
7464} // end: extern "C"
7465
7466//===----------------------------------------------------------------------===//
7467// Attribute introspection.
7468//===----------------------------------------------------------------------===//
7469
7470extern "C" {
7471CXType clang_getIBOutletCollectionType(CXCursor C) {
7472 if (C.kind != CXCursor_IBOutletCollectionAttr)
7473 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7474
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007475 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007476 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7477
7478 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7479}
7480} // end: extern "C"
7481
7482//===----------------------------------------------------------------------===//
7483// Inspecting memory usage.
7484//===----------------------------------------------------------------------===//
7485
7486typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7487
7488static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7489 enum CXTUResourceUsageKind k,
7490 unsigned long amount) {
7491 CXTUResourceUsageEntry entry = { k, amount };
7492 entries.push_back(entry);
7493}
7494
7495extern "C" {
7496
7497const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7498 const char *str = "";
7499 switch (kind) {
7500 case CXTUResourceUsage_AST:
7501 str = "ASTContext: expressions, declarations, and types";
7502 break;
7503 case CXTUResourceUsage_Identifiers:
7504 str = "ASTContext: identifiers";
7505 break;
7506 case CXTUResourceUsage_Selectors:
7507 str = "ASTContext: selectors";
7508 break;
7509 case CXTUResourceUsage_GlobalCompletionResults:
7510 str = "Code completion: cached global results";
7511 break;
7512 case CXTUResourceUsage_SourceManagerContentCache:
7513 str = "SourceManager: content cache allocator";
7514 break;
7515 case CXTUResourceUsage_AST_SideTables:
7516 str = "ASTContext: side tables";
7517 break;
7518 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7519 str = "SourceManager: malloc'ed memory buffers";
7520 break;
7521 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7522 str = "SourceManager: mmap'ed memory buffers";
7523 break;
7524 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7525 str = "ExternalASTSource: malloc'ed memory buffers";
7526 break;
7527 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7528 str = "ExternalASTSource: mmap'ed memory buffers";
7529 break;
7530 case CXTUResourceUsage_Preprocessor:
7531 str = "Preprocessor: malloc'ed memory";
7532 break;
7533 case CXTUResourceUsage_PreprocessingRecord:
7534 str = "Preprocessor: PreprocessingRecord";
7535 break;
7536 case CXTUResourceUsage_SourceManager_DataStructures:
7537 str = "SourceManager: data structures and tables";
7538 break;
7539 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7540 str = "Preprocessor: header search tables";
7541 break;
7542 }
7543 return str;
7544}
7545
7546CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007547 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007548 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007549 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007550 return usage;
7551 }
7552
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007553 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007554 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007555 ASTContext &astContext = astUnit->getASTContext();
7556
7557 // How much memory is used by AST nodes and types?
7558 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7559 (unsigned long) astContext.getASTAllocatedMemory());
7560
7561 // How much memory is used by identifiers?
7562 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7563 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7564
7565 // How much memory is used for selectors?
7566 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7567 (unsigned long) astContext.Selectors.getTotalMemory());
7568
7569 // How much memory is used by ASTContext's side tables?
7570 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7571 (unsigned long) astContext.getSideTableAllocatedMemory());
7572
7573 // How much memory is used for caching global code completion results?
7574 unsigned long completionBytes = 0;
7575 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007576 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007577 completionBytes = completionAllocator->getTotalMemory();
7578 }
7579 createCXTUResourceUsageEntry(*entries,
7580 CXTUResourceUsage_GlobalCompletionResults,
7581 completionBytes);
7582
7583 // How much memory is being used by SourceManager's content cache?
7584 createCXTUResourceUsageEntry(*entries,
7585 CXTUResourceUsage_SourceManagerContentCache,
7586 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7587
7588 // How much memory is being used by the MemoryBuffer's in SourceManager?
7589 const SourceManager::MemoryBufferSizes &srcBufs =
7590 astUnit->getSourceManager().getMemoryBufferSizes();
7591
7592 createCXTUResourceUsageEntry(*entries,
7593 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7594 (unsigned long) srcBufs.malloc_bytes);
7595 createCXTUResourceUsageEntry(*entries,
7596 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7597 (unsigned long) srcBufs.mmap_bytes);
7598 createCXTUResourceUsageEntry(*entries,
7599 CXTUResourceUsage_SourceManager_DataStructures,
7600 (unsigned long) astContext.getSourceManager()
7601 .getDataStructureSizes());
7602
7603 // How much memory is being used by the ExternalASTSource?
7604 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7605 const ExternalASTSource::MemoryBufferSizes &sizes =
7606 esrc->getMemoryBufferSizes();
7607
7608 createCXTUResourceUsageEntry(*entries,
7609 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7610 (unsigned long) sizes.malloc_bytes);
7611 createCXTUResourceUsageEntry(*entries,
7612 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7613 (unsigned long) sizes.mmap_bytes);
7614 }
7615
7616 // How much memory is being used by the Preprocessor?
7617 Preprocessor &pp = astUnit->getPreprocessor();
7618 createCXTUResourceUsageEntry(*entries,
7619 CXTUResourceUsage_Preprocessor,
7620 pp.getTotalMemory());
7621
7622 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7623 createCXTUResourceUsageEntry(*entries,
7624 CXTUResourceUsage_PreprocessingRecord,
7625 pRec->getTotalMemory());
7626 }
7627
7628 createCXTUResourceUsageEntry(*entries,
7629 CXTUResourceUsage_Preprocessor_HeaderSearch,
7630 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007631
Guy Benyei11169dd2012-12-18 14:30:41 +00007632 CXTUResourceUsage usage = { (void*) entries.get(),
7633 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007634 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007635 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007636 return usage;
7637}
7638
7639void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7640 if (usage.data)
7641 delete (MemUsageEntries*) usage.data;
7642}
7643
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007644CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7645 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007646 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007647 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007648
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007649 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007650 LOG_BAD_TU(TU);
7651 return skipped;
7652 }
7653
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007654 if (!file)
7655 return skipped;
7656
7657 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7658 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7659 if (!ppRec)
7660 return skipped;
7661
7662 ASTContext &Ctx = astUnit->getASTContext();
7663 SourceManager &sm = Ctx.getSourceManager();
7664 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7665 FileID wantedFileID = sm.translateFile(fileEntry);
7666
7667 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7668 std::vector<SourceRange> wantedRanges;
7669 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7670 i != ei; ++i) {
7671 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7672 wantedRanges.push_back(*i);
7673 }
7674
7675 skipped->count = wantedRanges.size();
7676 skipped->ranges = new CXSourceRange[skipped->count];
7677 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7678 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7679
7680 return skipped;
7681}
7682
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007683void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7684 if (ranges) {
7685 delete[] ranges->ranges;
7686 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007687 }
7688}
7689
Guy Benyei11169dd2012-12-18 14:30:41 +00007690} // end extern "C"
7691
7692void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7693 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7694 for (unsigned I = 0; I != Usage.numEntries; ++I)
7695 fprintf(stderr, " %s: %lu\n",
7696 clang_getTUResourceUsageName(Usage.entries[I].kind),
7697 Usage.entries[I].amount);
7698
7699 clang_disposeCXTUResourceUsage(Usage);
7700}
7701
7702//===----------------------------------------------------------------------===//
7703// Misc. utility functions.
7704//===----------------------------------------------------------------------===//
7705
7706/// Default to using an 8 MB stack size on "safety" threads.
7707static unsigned SafetyStackThreadSize = 8 << 20;
7708
7709namespace clang {
7710
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007711bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007712 unsigned Size) {
7713 if (!Size)
7714 Size = GetSafetyThreadStackSize();
7715 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007716 return CRC.RunSafelyOnThread(Fn, Size);
7717 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007718}
7719
7720unsigned GetSafetyThreadStackSize() {
7721 return SafetyStackThreadSize;
7722}
7723
7724void SetSafetyThreadStackSize(unsigned Value) {
7725 SafetyStackThreadSize = Value;
7726}
7727
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007728}
Guy Benyei11169dd2012-12-18 14:30:41 +00007729
7730void clang::setThreadBackgroundPriority() {
7731 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7732 return;
7733
Alp Toker1a86ad22014-07-06 06:24:00 +00007734#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007735 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7736#endif
7737}
7738
7739void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7740 if (!Unit)
7741 return;
7742
7743 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7744 DEnd = Unit->stored_diag_end();
7745 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007746 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007747 CXString Msg = clang_formatDiagnostic(&Diag,
7748 clang_defaultDiagnosticDisplayOptions());
7749 fprintf(stderr, "%s\n", clang_getCString(Msg));
7750 clang_disposeString(Msg);
7751 }
7752#ifdef LLVM_ON_WIN32
7753 // On Windows, force a flush, since there may be multiple copies of
7754 // stderr and stdout in the file system, all with different buffers
7755 // but writing to the same device.
7756 fflush(stderr);
7757#endif
7758}
7759
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007760MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7761 SourceLocation MacroDefLoc,
7762 CXTranslationUnit TU){
7763 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007764 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007765 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007766 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007767
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007768 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007769 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007770 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007771 if (MD) {
7772 for (MacroDirective::DefInfo
7773 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7774 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7775 return Def.getMacroInfo();
7776 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007777 }
7778
Craig Topper69186e72014-06-08 08:38:04 +00007779 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007780}
7781
Richard Smith66a81862015-05-04 02:25:31 +00007782const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007783 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007784 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007785 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007786 const IdentifierInfo *II = MacroDef->getName();
7787 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007788 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007789
7790 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7791}
7792
Richard Smith66a81862015-05-04 02:25:31 +00007793MacroDefinitionRecord *
7794cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7795 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007796 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007797 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007798 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007799 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007800
7801 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007802 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007803 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7804 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007805 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007806
7807 // Check that the token is inside the definition and not its argument list.
7808 SourceManager &SM = Unit->getSourceManager();
7809 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007810 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007811 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007812 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007813
7814 Preprocessor &PP = Unit->getPreprocessor();
7815 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7816 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007817 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007818
Alp Toker2d57cea2014-05-17 04:53:25 +00007819 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007820 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007821 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007822
7823 // Check that the identifier is not one of the macro arguments.
7824 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007825 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007826
Richard Smith20e883e2015-04-29 23:20:19 +00007827 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007828 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007829 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007830
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007831 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007832}
7833
Richard Smith66a81862015-05-04 02:25:31 +00007834MacroDefinitionRecord *
7835cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7836 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007837 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007838 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007839
7840 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007841 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007842 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007843 Preprocessor &PP = Unit->getPreprocessor();
7844 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007845 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007846 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7847 Token Tok;
7848 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007849 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007850
7851 return checkForMacroInMacroDefinition(MI, Tok, TU);
7852}
7853
Guy Benyei11169dd2012-12-18 14:30:41 +00007854extern "C" {
7855
7856CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007857 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007858}
7859
7860} // end: extern "C"
7861
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007862Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7863 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007864 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007865 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007866 if (Unit->isMainFileAST())
7867 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007868 return *this;
7869 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007870 } else {
7871 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007872 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007873 return *this;
7874}
7875
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007876Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7877 *this << FE->getName();
7878 return *this;
7879}
7880
7881Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7882 CXString cursorName = clang_getCursorDisplayName(cursor);
7883 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7884 clang_disposeString(cursorName);
7885 return *this;
7886}
7887
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007888Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7889 CXFile File;
7890 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007891 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007892 CXString FileName = clang_getFileName(File);
7893 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7894 clang_disposeString(FileName);
7895 return *this;
7896}
7897
7898Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7899 CXSourceLocation BLoc = clang_getRangeStart(range);
7900 CXSourceLocation ELoc = clang_getRangeEnd(range);
7901
7902 CXFile BFile;
7903 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007904 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007905
7906 CXFile EFile;
7907 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007908 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007909
7910 CXString BFileName = clang_getFileName(BFile);
7911 if (BFile == EFile) {
7912 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7913 BLine, BColumn, ELine, EColumn);
7914 } else {
7915 CXString EFileName = clang_getFileName(EFile);
7916 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7917 BLine, BColumn)
7918 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7919 ELine, EColumn);
7920 clang_disposeString(EFileName);
7921 }
7922 clang_disposeString(BFileName);
7923 return *this;
7924}
7925
7926Logger &cxindex::Logger::operator<<(CXString Str) {
7927 *this << clang_getCString(Str);
7928 return *this;
7929}
7930
7931Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7932 LogOS << Fmt;
7933 return *this;
7934}
7935
Chandler Carruth37ad2582014-06-27 15:14:39 +00007936static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7937
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007938cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007939 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007940
7941 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7942
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007943 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007944 OS << "[libclang:" << Name << ':';
7945
Alp Toker1a86ad22014-07-06 06:24:00 +00007946#ifdef USE_DARWIN_THREADS
7947 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007948 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7949 OS << tid << ':';
7950#endif
7951
7952 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7953 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007954 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007955
7956 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007957 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007958 OS << "--------------------------------------------------\n";
7959 }
7960}