blob: 84ba6b0ab178208f11518cbe8f4e8103a6b9be16 [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);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001957 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00001958 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00001959 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00001960 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001961
Guy Benyei11169dd2012-12-18 14:30:41 +00001962private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001963 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001964 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00001965 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1966 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001967 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1968 void AddStmt(const Stmt *S);
1969 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001970 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001972 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001973};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001974} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001975
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001977 // 'S' should always be non-null, since it comes from the
1978 // statement we are visiting.
1979 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1980}
1981
1982void
1983EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1984 if (Qualifier)
1985 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1986}
1987
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001988void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001989 if (S)
1990 WL.push_back(StmtVisit(S, Parent));
1991}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001992void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001993 if (D)
1994 WL.push_back(DeclVisit(D, Parent, isFirst));
1995}
James Y Knight04ec5bf2015-12-24 02:59:37 +00001996void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1997 unsigned NumTemplateArgs) {
1998 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001999}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002000void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002001 if (D)
2002 WL.push_back(MemberRefVisit(D, L, Parent));
2003}
2004void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2005 if (TI)
2006 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2007 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002008void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002009 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002010 for (const Stmt *SubStmt : S->children()) {
2011 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002012 }
2013 if (size == WL.size())
2014 return;
2015 // Now reverse the entries we just added. This will match the DFS
2016 // ordering performed by the worklist.
2017 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2018 std::reverse(I, E);
2019}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002020namespace {
2021class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2022 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002023 /// \brief Process clauses with list of variables.
2024 template <typename T>
2025 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002026public:
2027 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2028#define OPENMP_CLAUSE(Name, Class) \
2029 void Visit##Class(const Class *C);
2030#include "clang/Basic/OpenMPKinds.def"
2031};
2032
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002033void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2034 Visitor->AddStmt(C->getCondition());
2035}
2036
Alexey Bataev3778b602014-07-17 07:32:53 +00002037void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2038 Visitor->AddStmt(C->getCondition());
2039}
2040
Alexey Bataev568a8332014-03-06 06:15:19 +00002041void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2042 Visitor->AddStmt(C->getNumThreads());
2043}
2044
Alexey Bataev62c87d22014-03-21 04:51:18 +00002045void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2046 Visitor->AddStmt(C->getSafelen());
2047}
2048
Alexey Bataev66b15b52015-08-21 11:14:16 +00002049void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2050 Visitor->AddStmt(C->getSimdlen());
2051}
2052
Alexander Musman8bd31e62014-05-27 15:12:19 +00002053void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2054 Visitor->AddStmt(C->getNumForLoops());
2055}
2056
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002057void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002058
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002059void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2060
Alexey Bataev56dafe82014-06-20 07:16:17 +00002061void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2062 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002063 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002064}
2065
Alexey Bataev10e775f2015-07-30 11:36:16 +00002066void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2067 Visitor->AddStmt(C->getNumForLoops());
2068}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002069
Alexey Bataev236070f2014-06-20 11:19:47 +00002070void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2071
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002072void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2073
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002074void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2075
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002076void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2077
Alexey Bataevdea47612014-07-23 07:46:59 +00002078void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2079
Alexey Bataev67a4f222014-07-23 10:25:33 +00002080void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2081
Alexey Bataev459dec02014-07-24 06:46:57 +00002082void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2083
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002084void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2085
Alexey Bataev346265e2015-09-25 10:37:12 +00002086void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2087
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002088void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2089
Alexey Bataevb825de12015-12-07 10:51:44 +00002090void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2091
Michael Wonge710d542015-08-07 16:16:36 +00002092void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2093 Visitor->AddStmt(C->getDevice());
2094}
2095
Kelvin Li099bb8c2015-11-24 20:50:12 +00002096void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2097 Visitor->AddStmt(C->getNumTeams());
2098}
2099
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002100void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2101 Visitor->AddStmt(C->getThreadLimit());
2102}
2103
Alexey Bataeva0569352015-12-01 10:17:31 +00002104void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2105 Visitor->AddStmt(C->getPriority());
2106}
2107
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002108void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2109 Visitor->AddStmt(C->getGrainsize());
2110}
2111
Alexey Bataev382967a2015-12-08 12:06:20 +00002112void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2113 Visitor->AddStmt(C->getNumTasks());
2114}
2115
Alexey Bataev28c75412015-12-15 08:19:24 +00002116void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2117 Visitor->AddStmt(C->getHint());
2118}
2119
Alexey Bataev756c1962013-09-24 03:17:45 +00002120template<typename T>
2121void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002122 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002123 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002124 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002125}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002126
2127void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002128 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002129 for (const auto *E : C->private_copies()) {
2130 Visitor->AddStmt(E);
2131 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002132}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002133void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2134 const OMPFirstprivateClause *C) {
2135 VisitOMPClauseList(C);
2136}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002137void OMPClauseEnqueue::VisitOMPLastprivateClause(
2138 const OMPLastprivateClause *C) {
2139 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002140 for (auto *E : C->private_copies()) {
2141 Visitor->AddStmt(E);
2142 }
2143 for (auto *E : C->source_exprs()) {
2144 Visitor->AddStmt(E);
2145 }
2146 for (auto *E : C->destination_exprs()) {
2147 Visitor->AddStmt(E);
2148 }
2149 for (auto *E : C->assignment_ops()) {
2150 Visitor->AddStmt(E);
2151 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002152}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002153void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002154 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002155}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002156void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2157 VisitOMPClauseList(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002158 for (auto *E : C->privates()) {
2159 Visitor->AddStmt(E);
2160 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002161 for (auto *E : C->lhs_exprs()) {
2162 Visitor->AddStmt(E);
2163 }
2164 for (auto *E : C->rhs_exprs()) {
2165 Visitor->AddStmt(E);
2166 }
2167 for (auto *E : C->reduction_ops()) {
2168 Visitor->AddStmt(E);
2169 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002170}
Alexander Musman8dba6642014-04-22 13:09:42 +00002171void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2172 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002173 for (const auto *E : C->privates()) {
2174 Visitor->AddStmt(E);
2175 }
Alexander Musman3276a272015-03-21 10:12:56 +00002176 for (const auto *E : C->inits()) {
2177 Visitor->AddStmt(E);
2178 }
2179 for (const auto *E : C->updates()) {
2180 Visitor->AddStmt(E);
2181 }
2182 for (const auto *E : C->finals()) {
2183 Visitor->AddStmt(E);
2184 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002185 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002186 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002187}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002188void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2189 VisitOMPClauseList(C);
2190 Visitor->AddStmt(C->getAlignment());
2191}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002192void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2193 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002194 for (auto *E : C->source_exprs()) {
2195 Visitor->AddStmt(E);
2196 }
2197 for (auto *E : C->destination_exprs()) {
2198 Visitor->AddStmt(E);
2199 }
2200 for (auto *E : C->assignment_ops()) {
2201 Visitor->AddStmt(E);
2202 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002203}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002204void
2205OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2206 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002207 for (auto *E : C->source_exprs()) {
2208 Visitor->AddStmt(E);
2209 }
2210 for (auto *E : C->destination_exprs()) {
2211 Visitor->AddStmt(E);
2212 }
2213 for (auto *E : C->assignment_ops()) {
2214 Visitor->AddStmt(E);
2215 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002216}
Alexey Bataev6125da92014-07-21 11:26:11 +00002217void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2218 VisitOMPClauseList(C);
2219}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002220void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2221 VisitOMPClauseList(C);
2222}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002223void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2224 VisitOMPClauseList(C);
2225}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002226void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2227 const OMPDistScheduleClause *C) {
2228 Visitor->AddStmt(C->getChunkSize());
2229 Visitor->AddStmt(C->getHelperChunkSize());
2230}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002231}
Alexey Bataev756c1962013-09-24 03:17:45 +00002232
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002233void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2234 unsigned size = WL.size();
2235 OMPClauseEnqueue Visitor(this);
2236 Visitor.Visit(S);
2237 if (size == WL.size())
2238 return;
2239 // Now reverse the entries we just added. This will match the DFS
2240 // ordering performed by the worklist.
2241 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2242 std::reverse(I, E);
2243}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2246}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002247void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002248 AddDecl(B->getBlockDecl());
2249}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 EnqueueChildren(E);
2252 AddTypeLoc(E->getTypeSourceInfo());
2253}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002254void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002255 for (auto &I : llvm::reverse(S->body()))
2256 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002257}
2258void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 AddStmt(S->getSubStmt());
2261 AddDeclarationNameInfo(S);
2262 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2263 AddNestedNameSpecifierLoc(QualifierLoc);
2264}
2265
2266void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002267VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002268 if (E->hasExplicitTemplateArgs())
2269 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002270 AddDeclarationNameInfo(E);
2271 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2272 AddNestedNameSpecifierLoc(QualifierLoc);
2273 if (!E->isImplicitAccess())
2274 AddStmt(E->getBase());
2275}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 // Enqueue the initializer , if any.
2278 AddStmt(E->getInitializer());
2279 // Enqueue the array size, if any.
2280 AddStmt(E->getArraySize());
2281 // Enqueue the allocated type.
2282 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2283 // Enqueue the placement arguments.
2284 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2285 AddStmt(E->getPlacementArg(I-1));
2286}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002287void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002288 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2289 AddStmt(CE->getArg(I-1));
2290 AddStmt(CE->getCallee());
2291 AddStmt(CE->getArg(0));
2292}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002293void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2294 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002295 // Visit the name of the type being destroyed.
2296 AddTypeLoc(E->getDestroyedTypeInfo());
2297 // Visit the scope type that looks disturbingly like the nested-name-specifier
2298 // but isn't.
2299 AddTypeLoc(E->getScopeTypeInfo());
2300 // Visit the nested-name-specifier.
2301 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2302 AddNestedNameSpecifierLoc(QualifierLoc);
2303 // Visit base expression.
2304 AddStmt(E->getBase());
2305}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002306void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2307 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002308 AddTypeLoc(E->getTypeSourceInfo());
2309}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002310void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2311 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 EnqueueChildren(E);
2313 AddTypeLoc(E->getTypeSourceInfo());
2314}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002315void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002316 EnqueueChildren(E);
2317 if (E->isTypeOperand())
2318 AddTypeLoc(E->getTypeOperandSourceInfo());
2319}
2320
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002321void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2322 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 EnqueueChildren(E);
2324 AddTypeLoc(E->getTypeSourceInfo());
2325}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002326void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002327 EnqueueChildren(E);
2328 if (E->isTypeOperand())
2329 AddTypeLoc(E->getTypeOperandSourceInfo());
2330}
2331
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002332void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 EnqueueChildren(S);
2334 AddDecl(S->getExceptionDecl());
2335}
2336
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002337void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002338 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002339 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002340 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002341}
2342
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002343void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002344 if (DR->hasExplicitTemplateArgs())
2345 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002346 WL.push_back(DeclRefExprParts(DR, Parent));
2347}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002348void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2349 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002350 if (E->hasExplicitTemplateArgs())
2351 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002352 AddDeclarationNameInfo(E);
2353 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2354}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002355void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002356 unsigned size = WL.size();
2357 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002358 for (const auto *D : S->decls()) {
2359 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002360 isFirst = false;
2361 }
2362 if (size == WL.size())
2363 return;
2364 // Now reverse the entries we just added. This will match the DFS
2365 // ordering performed by the worklist.
2366 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2367 std::reverse(I, E);
2368}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002369void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002370 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002371 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002372 D = E->designators_rbegin(), DEnd = E->designators_rend();
2373 D != DEnd; ++D) {
2374 if (D->isFieldDesignator()) {
2375 if (FieldDecl *Field = D->getField())
2376 AddMemberRef(Field, D->getFieldLoc());
2377 continue;
2378 }
2379 if (D->isArrayDesignator()) {
2380 AddStmt(E->getArrayIndex(*D));
2381 continue;
2382 }
2383 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2384 AddStmt(E->getArrayRangeEnd(*D));
2385 AddStmt(E->getArrayRangeStart(*D));
2386 }
2387}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002388void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002389 EnqueueChildren(E);
2390 AddTypeLoc(E->getTypeInfoAsWritten());
2391}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002392void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002393 AddStmt(FS->getBody());
2394 AddStmt(FS->getInc());
2395 AddStmt(FS->getCond());
2396 AddDecl(FS->getConditionVariable());
2397 AddStmt(FS->getInit());
2398}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002399void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002400 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2401}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002402void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002403 AddStmt(If->getElse());
2404 AddStmt(If->getThen());
2405 AddStmt(If->getCond());
2406 AddDecl(If->getConditionVariable());
2407}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002408void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002409 // We care about the syntactic form of the initializer list, only.
2410 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2411 IE = Syntactic;
2412 EnqueueChildren(IE);
2413}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002414void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002415 WL.push_back(MemberExprParts(M, Parent));
2416
2417 // If the base of the member access expression is an implicit 'this', don't
2418 // visit it.
2419 // FIXME: If we ever want to show these implicit accesses, this will be
2420 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002421 if (M->isImplicitAccess())
2422 return;
2423
2424 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2425 // real field that that we are interested in.
2426 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2427 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2428 if (FD->isAnonymousStructOrUnion()) {
2429 AddStmt(SubME->getBase());
2430 return;
2431 }
2432 }
2433 }
2434
2435 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002436}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002437void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 AddTypeLoc(E->getEncodedTypeSourceInfo());
2439}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002440void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 EnqueueChildren(M);
2442 AddTypeLoc(M->getClassReceiverTypeInfo());
2443}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002444void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 // Visit the components of the offsetof expression.
2446 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 const OffsetOfNode &Node = E->getComponent(I-1);
2448 switch (Node.getKind()) {
2449 case OffsetOfNode::Array:
2450 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2451 break;
2452 case OffsetOfNode::Field:
2453 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2454 break;
2455 case OffsetOfNode::Identifier:
2456 case OffsetOfNode::Base:
2457 continue;
2458 }
2459 }
2460 // Visit the type into which we're computing the offset.
2461 AddTypeLoc(E->getTypeSourceInfo());
2462}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002463void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002464 if (E->hasExplicitTemplateArgs())
2465 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002466 WL.push_back(OverloadExprParts(E, Parent));
2467}
2468void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002469 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002470 EnqueueChildren(E);
2471 if (E->isArgumentType())
2472 AddTypeLoc(E->getArgumentTypeInfo());
2473}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002474void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002475 EnqueueChildren(S);
2476}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002477void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002478 AddStmt(S->getBody());
2479 AddStmt(S->getCond());
2480 AddDecl(S->getConditionVariable());
2481}
2482
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002483void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002484 AddStmt(W->getBody());
2485 AddStmt(W->getCond());
2486 AddDecl(W->getConditionVariable());
2487}
2488
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002489void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002490 for (unsigned I = E->getNumArgs(); I > 0; --I)
2491 AddTypeLoc(E->getArg(I-1));
2492}
2493
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002494void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002495 AddTypeLoc(E->getQueriedTypeSourceInfo());
2496}
2497
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002498void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002499 EnqueueChildren(E);
2500}
2501
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002502void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002503 VisitOverloadExpr(U);
2504 if (!U->isImplicitAccess())
2505 AddStmt(U->getBase());
2506}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002507void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002508 AddStmt(E->getSubExpr());
2509 AddTypeLoc(E->getWrittenTypeInfo());
2510}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002511void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002512 WL.push_back(SizeOfPackExprParts(E, Parent));
2513}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002514void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002515 // If the opaque value has a source expression, just transparently
2516 // visit that. This is useful for (e.g.) pseudo-object expressions.
2517 if (Expr *SourceExpr = E->getSourceExpr())
2518 return Visit(SourceExpr);
2519}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002520void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002521 AddStmt(E->getBody());
2522 WL.push_back(LambdaExprParts(E, Parent));
2523}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002524void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002525 // Treat the expression like its syntactic form.
2526 Visit(E->getSyntacticForm());
2527}
2528
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002529void EnqueueVisitor::VisitOMPExecutableDirective(
2530 const OMPExecutableDirective *D) {
2531 EnqueueChildren(D);
2532 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2533 E = D->clauses().end();
2534 I != E; ++I)
2535 EnqueueChildren(*I);
2536}
2537
Alexander Musman3aaab662014-08-19 11:27:13 +00002538void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2539 VisitOMPExecutableDirective(D);
2540}
2541
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002542void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2543 VisitOMPExecutableDirective(D);
2544}
2545
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002546void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002547 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002548}
2549
Alexey Bataevf29276e2014-06-18 04:14:57 +00002550void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002551 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002552}
2553
Alexander Musmanf82886e2014-09-18 05:12:34 +00002554void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2555 VisitOMPLoopDirective(D);
2556}
2557
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002558void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2559 VisitOMPExecutableDirective(D);
2560}
2561
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002562void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2563 VisitOMPExecutableDirective(D);
2564}
2565
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002566void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2567 VisitOMPExecutableDirective(D);
2568}
2569
Alexander Musman80c22892014-07-17 08:54:58 +00002570void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2571 VisitOMPExecutableDirective(D);
2572}
2573
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002574void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2575 VisitOMPExecutableDirective(D);
2576 AddDeclarationNameInfo(D);
2577}
2578
Alexey Bataev4acb8592014-07-07 13:01:15 +00002579void
2580EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002581 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002582}
2583
Alexander Musmane4e893b2014-09-23 09:33:00 +00002584void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2585 const OMPParallelForSimdDirective *D) {
2586 VisitOMPLoopDirective(D);
2587}
2588
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002589void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2590 const OMPParallelSectionsDirective *D) {
2591 VisitOMPExecutableDirective(D);
2592}
2593
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002594void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2595 VisitOMPExecutableDirective(D);
2596}
2597
Alexey Bataev68446b72014-07-18 07:47:19 +00002598void
2599EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2600 VisitOMPExecutableDirective(D);
2601}
2602
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002603void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2604 VisitOMPExecutableDirective(D);
2605}
2606
Alexey Bataev2df347a2014-07-18 10:17:07 +00002607void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2608 VisitOMPExecutableDirective(D);
2609}
2610
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002611void EnqueueVisitor::VisitOMPTaskgroupDirective(
2612 const OMPTaskgroupDirective *D) {
2613 VisitOMPExecutableDirective(D);
2614}
2615
Alexey Bataev6125da92014-07-21 11:26:11 +00002616void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2617 VisitOMPExecutableDirective(D);
2618}
2619
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002620void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2621 VisitOMPExecutableDirective(D);
2622}
2623
Alexey Bataev0162e452014-07-22 10:10:35 +00002624void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2625 VisitOMPExecutableDirective(D);
2626}
2627
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002628void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2629 VisitOMPExecutableDirective(D);
2630}
2631
Michael Wong65f367f2015-07-21 13:44:28 +00002632void EnqueueVisitor::VisitOMPTargetDataDirective(const
2633 OMPTargetDataDirective *D) {
2634 VisitOMPExecutableDirective(D);
2635}
2636
Samuel Antaodf67fc42016-01-19 19:15:56 +00002637void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2638 const OMPTargetEnterDataDirective *D) {
2639 VisitOMPExecutableDirective(D);
2640}
2641
Alexey Bataev13314bf2014-10-09 04:18:56 +00002642void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2643 VisitOMPExecutableDirective(D);
2644}
2645
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002646void EnqueueVisitor::VisitOMPCancellationPointDirective(
2647 const OMPCancellationPointDirective *D) {
2648 VisitOMPExecutableDirective(D);
2649}
2650
Alexey Bataev80909872015-07-02 11:25:17 +00002651void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2652 VisitOMPExecutableDirective(D);
2653}
2654
Alexey Bataev49f6e782015-12-01 04:18:41 +00002655void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2656 VisitOMPLoopDirective(D);
2657}
2658
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002659void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2660 const OMPTaskLoopSimdDirective *D) {
2661 VisitOMPLoopDirective(D);
2662}
2663
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002664void EnqueueVisitor::VisitOMPDistributeDirective(
2665 const OMPDistributeDirective *D) {
2666 VisitOMPLoopDirective(D);
2667}
2668
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002669void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002670 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2671}
2672
2673bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2674 if (RegionOfInterest.isValid()) {
2675 SourceRange Range = getRawCursorExtent(C);
2676 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2677 return false;
2678 }
2679 return true;
2680}
2681
2682bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2683 while (!WL.empty()) {
2684 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002685 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002686
2687 // Set the Parent field, then back to its old value once we're done.
2688 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2689
2690 switch (LI.getKind()) {
2691 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002692 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002693 if (!D)
2694 continue;
2695
2696 // For now, perform default visitation for Decls.
2697 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2698 cast<DeclVisit>(&LI)->isFirst())))
2699 return true;
2700
2701 continue;
2702 }
2703 case VisitorJob::ExplicitTemplateArgsVisitKind: {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002704 for (const TemplateArgumentLoc &Arg :
2705 *cast<ExplicitTemplateArgsVisit>(&LI)) {
2706 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00002707 return true;
2708 }
2709 continue;
2710 }
2711 case VisitorJob::TypeLocVisitKind: {
2712 // Perform default visitation for TypeLocs.
2713 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2714 return true;
2715 continue;
2716 }
2717 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002718 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002719 if (LabelStmt *stmt = LS->getStmt()) {
2720 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2721 TU))) {
2722 return true;
2723 }
2724 }
2725 continue;
2726 }
2727
2728 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2729 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2730 if (VisitNestedNameSpecifierLoc(V->get()))
2731 return true;
2732 continue;
2733 }
2734
2735 case VisitorJob::DeclarationNameInfoVisitKind: {
2736 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2737 ->get()))
2738 return true;
2739 continue;
2740 }
2741 case VisitorJob::MemberRefVisitKind: {
2742 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2743 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2744 return true;
2745 continue;
2746 }
2747 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002748 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002749 if (!S)
2750 continue;
2751
2752 // Update the current cursor.
2753 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2754 if (!IsInRegionOfInterest(Cursor))
2755 continue;
2756 switch (Visitor(Cursor, Parent, ClientData)) {
2757 case CXChildVisit_Break: return true;
2758 case CXChildVisit_Continue: break;
2759 case CXChildVisit_Recurse:
2760 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002761 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002762 EnqueueWorkList(WL, S);
2763 break;
2764 }
2765 continue;
2766 }
2767 case VisitorJob::MemberExprPartsKind: {
2768 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002769 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002770
2771 // Visit the nested-name-specifier
2772 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2773 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2774 return true;
2775
2776 // Visit the declaration name.
2777 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2778 return true;
2779
2780 // Visit the explicitly-specified template arguments, if any.
2781 if (M->hasExplicitTemplateArgs()) {
2782 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2783 *ArgEnd = Arg + M->getNumTemplateArgs();
2784 Arg != ArgEnd; ++Arg) {
2785 if (VisitTemplateArgumentLoc(*Arg))
2786 return true;
2787 }
2788 }
2789 continue;
2790 }
2791 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002792 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002793 // Visit nested-name-specifier, if present.
2794 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2795 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2796 return true;
2797 // Visit declaration name.
2798 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2799 return true;
2800 continue;
2801 }
2802 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002803 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002804 // Visit the nested-name-specifier.
2805 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2806 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2807 return true;
2808 // Visit the declaration name.
2809 if (VisitDeclarationNameInfo(O->getNameInfo()))
2810 return true;
2811 // Visit the overloaded declaration reference.
2812 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2813 return true;
2814 continue;
2815 }
2816 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002817 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002818 NamedDecl *Pack = E->getPack();
2819 if (isa<TemplateTypeParmDecl>(Pack)) {
2820 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2821 E->getPackLoc(), TU)))
2822 return true;
2823
2824 continue;
2825 }
2826
2827 if (isa<TemplateTemplateParmDecl>(Pack)) {
2828 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2829 E->getPackLoc(), TU)))
2830 return true;
2831
2832 continue;
2833 }
2834
2835 // Non-type template parameter packs and function parameter packs are
2836 // treated like DeclRefExpr cursors.
2837 continue;
2838 }
2839
2840 case VisitorJob::LambdaExprPartsKind: {
2841 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002842 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002843 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2844 CEnd = E->explicit_capture_end();
2845 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002846 // FIXME: Lambda init-captures.
2847 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002848 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002849
Guy Benyei11169dd2012-12-18 14:30:41 +00002850 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2851 C->getLocation(),
2852 TU)))
2853 return true;
2854 }
2855
2856 // Visit parameters and return type, if present.
2857 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2858 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2859 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2860 // Visit the whole type.
2861 if (Visit(TL))
2862 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002863 } else if (FunctionProtoTypeLoc Proto =
2864 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002865 if (E->hasExplicitParameters()) {
2866 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002867 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2868 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002869 return true;
2870 } else {
2871 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002872 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002873 return true;
2874 }
2875 }
2876 }
2877 break;
2878 }
2879
2880 case VisitorJob::PostChildrenVisitKind:
2881 if (PostChildrenVisitor(Parent, ClientData))
2882 return true;
2883 break;
2884 }
2885 }
2886 return false;
2887}
2888
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002889bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002890 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002891 if (!WorkListFreeList.empty()) {
2892 WL = WorkListFreeList.back();
2893 WL->clear();
2894 WorkListFreeList.pop_back();
2895 }
2896 else {
2897 WL = new VisitorWorkList();
2898 WorkListCache.push_back(WL);
2899 }
2900 EnqueueWorkList(*WL, S);
2901 bool result = RunVisitorWorkList(*WL);
2902 WorkListFreeList.push_back(WL);
2903 return result;
2904}
2905
2906namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002907typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00002908RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2909 const DeclarationNameInfo &NI, SourceRange QLoc,
2910 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002911 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2912 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2913 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2914
2915 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2916
2917 RefNamePieces Pieces;
2918
2919 if (WantQualifier && QLoc.isValid())
2920 Pieces.push_back(QLoc);
2921
2922 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2923 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00002924
2925 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
2926 Pieces.push_back(*TemplateArgsLoc);
2927
Guy Benyei11169dd2012-12-18 14:30:41 +00002928 if (Kind == DeclarationName::CXXOperatorName) {
2929 Pieces.push_back(SourceLocation::getFromRawEncoding(
2930 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2931 Pieces.push_back(SourceLocation::getFromRawEncoding(
2932 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2933 }
2934
2935 if (WantSinglePiece) {
2936 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2937 Pieces.clear();
2938 Pieces.push_back(R);
2939 }
2940
2941 return Pieces;
2942}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002943}
Guy Benyei11169dd2012-12-18 14:30:41 +00002944
2945//===----------------------------------------------------------------------===//
2946// Misc. API hooks.
2947//===----------------------------------------------------------------------===//
2948
Chad Rosier05c71aa2013-03-27 18:28:23 +00002949static void fatal_error_handler(void *user_data, const std::string& reason,
2950 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002951 // Write the result out to stderr avoiding errs() because raw_ostreams can
2952 // call report_fatal_error.
2953 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2954 ::abort();
2955}
2956
Chandler Carruth66660742014-06-27 16:37:27 +00002957namespace {
2958struct RegisterFatalErrorHandler {
2959 RegisterFatalErrorHandler() {
2960 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2961 }
2962};
2963}
2964
2965static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2966
Guy Benyei11169dd2012-12-18 14:30:41 +00002967extern "C" {
2968CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2969 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002970 // We use crash recovery to make some of our APIs more reliable, implicitly
2971 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002972 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2973 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002974
Chandler Carruth66660742014-06-27 16:37:27 +00002975 // Look through the managed static to trigger construction of the managed
2976 // static which registers our fatal error handler. This ensures it is only
2977 // registered once.
2978 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002979
Adrian Prantlbc068582015-07-08 01:00:30 +00002980 // Initialize targets for clang module support.
2981 llvm::InitializeAllTargets();
2982 llvm::InitializeAllTargetMCs();
2983 llvm::InitializeAllAsmPrinters();
2984 llvm::InitializeAllAsmParsers();
2985
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002986 CIndexer *CIdxr = new CIndexer();
2987
Guy Benyei11169dd2012-12-18 14:30:41 +00002988 if (excludeDeclarationsFromPCH)
2989 CIdxr->setOnlyLocalDecls();
2990 if (displayDiagnostics)
2991 CIdxr->setDisplayDiagnostics();
2992
2993 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2994 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2995 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2996 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2997 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2998 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2999
3000 return CIdxr;
3001}
3002
3003void clang_disposeIndex(CXIndex CIdx) {
3004 if (CIdx)
3005 delete static_cast<CIndexer *>(CIdx);
3006}
3007
3008void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3009 if (CIdx)
3010 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3011}
3012
3013unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3014 if (CIdx)
3015 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3016 return 0;
3017}
3018
3019void clang_toggleCrashRecovery(unsigned isEnabled) {
3020 if (isEnabled)
3021 llvm::CrashRecoveryContext::Enable();
3022 else
3023 llvm::CrashRecoveryContext::Disable();
3024}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003025
Guy Benyei11169dd2012-12-18 14:30:41 +00003026CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3027 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003028 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003029 enum CXErrorCode Result =
3030 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003031 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003032 assert((TU && Result == CXError_Success) ||
3033 (!TU && Result != CXError_Success));
3034 return TU;
3035}
3036
3037enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3038 const char *ast_filename,
3039 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003040 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003041 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003042
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003043 if (!CIdx || !ast_filename || !out_TU)
3044 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003045
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003046 LOG_FUNC_SECTION {
3047 *Log << ast_filename;
3048 }
3049
Guy Benyei11169dd2012-12-18 14:30:41 +00003050 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3051 FileSystemOptions FileSystemOpts;
3052
Justin Bognerd512c1e2014-10-15 00:33:06 +00003053 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3054 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003055 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003056 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00003057 FileSystemOpts, /*UseDebugInfo=*/false,
3058 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00003059 /*CaptureDiagnostics=*/true,
3060 /*AllowPCHWithCompilerErrors=*/true,
3061 /*UserFilesAreVolatile=*/true);
3062 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003063 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003064}
3065
3066unsigned clang_defaultEditingTranslationUnitOptions() {
3067 return CXTranslationUnit_PrecompiledPreamble |
3068 CXTranslationUnit_CacheCompletionResults;
3069}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003070
Guy Benyei11169dd2012-12-18 14:30:41 +00003071CXTranslationUnit
3072clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3073 const char *source_filename,
3074 int num_command_line_args,
3075 const char * const *command_line_args,
3076 unsigned num_unsaved_files,
3077 struct CXUnsavedFile *unsaved_files) {
3078 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3079 return clang_parseTranslationUnit(CIdx, source_filename,
3080 command_line_args, num_command_line_args,
3081 unsaved_files, num_unsaved_files,
3082 Options);
3083}
3084
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003085static CXErrorCode
3086clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3087 const char *const *command_line_args,
3088 int num_command_line_args,
3089 ArrayRef<CXUnsavedFile> unsaved_files,
3090 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003091 // Set up the initial return values.
3092 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003093 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003094
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003095 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003096 if (!CIdx || !out_TU)
3097 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003098
Guy Benyei11169dd2012-12-18 14:30:41 +00003099 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3100
3101 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3102 setThreadBackgroundPriority();
3103
3104 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003105 bool CreatePreambleOnFirstParse =
3106 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 // FIXME: Add a flag for modules.
3108 TranslationUnitKind TUKind
3109 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003110 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003111 = options & CXTranslationUnit_CacheCompletionResults;
3112 bool IncludeBriefCommentsInCodeCompletion
3113 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3114 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3115 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3116
3117 // Configure the diagnostics.
3118 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003119 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003120
3121 // Recover resources if we crash before exiting this function.
3122 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3123 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003124 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003125
Ahmed Charlesb8984322014-03-07 20:03:18 +00003126 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3127 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003128
3129 // Recover resources if we crash before exiting this function.
3130 llvm::CrashRecoveryContextCleanupRegistrar<
3131 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3132
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003133 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003134 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003135 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003136 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003137 }
3138
Ahmed Charlesb8984322014-03-07 20:03:18 +00003139 std::unique_ptr<std::vector<const char *>> Args(
3140 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003141
3142 // Recover resources if we crash before exiting this method.
3143 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3144 ArgsCleanup(Args.get());
3145
3146 // Since the Clang C library is primarily used by batch tools dealing with
3147 // (often very broken) source code, where spell-checking can have a
3148 // significant negative impact on performance (particularly when
3149 // precompiled headers are involved), we disable it by default.
3150 // Only do this if we haven't found a spell-checking-related argument.
3151 bool FoundSpellCheckingArgument = false;
3152 for (int I = 0; I != num_command_line_args; ++I) {
3153 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3154 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3155 FoundSpellCheckingArgument = true;
3156 break;
3157 }
3158 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 Args->insert(Args->end(), command_line_args,
3160 command_line_args + num_command_line_args);
3161
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003162 if (!FoundSpellCheckingArgument)
3163 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3164
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 // The 'source_filename' argument is optional. If the caller does not
3166 // specify it then it is assumed that the source file is specified
3167 // in the actual argument list.
3168 // Put the source file after command_line_args otherwise if '-x' flag is
3169 // present it will be unused.
3170 if (source_filename)
3171 Args->push_back(source_filename);
3172
3173 // Do we need the detailed preprocessing record?
3174 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3175 Args->push_back("-Xclang");
3176 Args->push_back("-detailed-preprocessing-record");
3177 }
3178
3179 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003180 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003181 // Unless the user specified that they want the preamble on the first parse
3182 // set it up to be created on the first reparse. This makes the first parse
3183 // faster, trading for a slower (first) reparse.
3184 unsigned PrecompilePreambleAfterNParses =
3185 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Ahmed Charlesb8984322014-03-07 20:03:18 +00003186 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003187 Args->data(), Args->data() + Args->size(),
3188 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003189 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3190 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003191 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3192 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003193 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003194 /*UserFilesAreVolatile=*/true, ForSerialization,
3195 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3196 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003197
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003198 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003199 if (!Unit && !ErrUnit)
3200 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003201
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 if (NumErrors != Diags->getClient()->getNumErrors()) {
3203 // Make sure to check that 'Unit' is non-NULL.
3204 if (CXXIdx->getDisplayDiagnostics())
3205 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3206 }
3207
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003208 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3209 return CXError_ASTReadError;
3210
3211 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3212 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003213}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003214
3215CXTranslationUnit
3216clang_parseTranslationUnit(CXIndex CIdx,
3217 const char *source_filename,
3218 const char *const *command_line_args,
3219 int num_command_line_args,
3220 struct CXUnsavedFile *unsaved_files,
3221 unsigned num_unsaved_files,
3222 unsigned options) {
3223 CXTranslationUnit TU;
3224 enum CXErrorCode Result = clang_parseTranslationUnit2(
3225 CIdx, source_filename, command_line_args, num_command_line_args,
3226 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003227 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003228 assert((TU && Result == CXError_Success) ||
3229 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003230 return TU;
3231}
3232
3233enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003234 CXIndex CIdx, const char *source_filename,
3235 const char *const *command_line_args, int num_command_line_args,
3236 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3237 unsigned options, CXTranslationUnit *out_TU) {
3238 SmallVector<const char *, 4> Args;
3239 Args.push_back("clang");
3240 Args.append(command_line_args, command_line_args + num_command_line_args);
3241 return clang_parseTranslationUnit2FullArgv(
3242 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3243 num_unsaved_files, options, out_TU);
3244}
3245
3246enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3247 CXIndex CIdx, const char *source_filename,
3248 const char *const *command_line_args, int num_command_line_args,
3249 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3250 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003251 LOG_FUNC_SECTION {
3252 *Log << source_filename << ": ";
3253 for (int i = 0; i != num_command_line_args; ++i)
3254 *Log << command_line_args[i] << " ";
3255 }
3256
Alp Toker9d85b182014-07-07 01:23:14 +00003257 if (num_unsaved_files && !unsaved_files)
3258 return CXError_InvalidArguments;
3259
Alp Toker5c532982014-07-07 22:42:03 +00003260 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003261 auto ParseTranslationUnitImpl = [=, &result] {
3262 result = clang_parseTranslationUnit_Impl(
3263 CIdx, source_filename, command_line_args, num_command_line_args,
3264 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3265 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 llvm::CrashRecoveryContext CRC;
3267
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003268 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3270 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3271 fprintf(stderr, " 'command_line_args' : [");
3272 for (int i = 0; i != num_command_line_args; ++i) {
3273 if (i)
3274 fprintf(stderr, ", ");
3275 fprintf(stderr, "'%s'", command_line_args[i]);
3276 }
3277 fprintf(stderr, "],\n");
3278 fprintf(stderr, " 'unsaved_files' : [");
3279 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3280 if (i)
3281 fprintf(stderr, ", ");
3282 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3283 unsaved_files[i].Length);
3284 }
3285 fprintf(stderr, "],\n");
3286 fprintf(stderr, " 'options' : %d,\n", options);
3287 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003288
3289 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003291 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003292 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 }
Alp Toker5c532982014-07-07 22:42:03 +00003294
3295 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003296}
3297
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003298CXString clang_Type_getObjCEncoding(CXType CT) {
3299 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3300 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3301 std::string encoding;
3302 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3303 encoding);
3304
3305 return cxstring::createDup(encoding);
3306}
3307
3308static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3309 if (C.kind == CXCursor_MacroDefinition) {
3310 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3311 return MDR->getName();
3312 } else if (C.kind == CXCursor_MacroExpansion) {
3313 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3314 return ME.getName();
3315 }
3316 return nullptr;
3317}
3318
3319unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3320 const IdentifierInfo *II = getMacroIdentifier(C);
3321 if (!II) {
3322 return false;
3323 }
3324 ASTUnit *ASTU = getCursorASTUnit(C);
3325 Preprocessor &PP = ASTU->getPreprocessor();
3326 if (const MacroInfo *MI = PP.getMacroInfo(II))
3327 return MI->isFunctionLike();
3328 return false;
3329}
3330
3331unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3332 const IdentifierInfo *II = getMacroIdentifier(C);
3333 if (!II) {
3334 return false;
3335 }
3336 ASTUnit *ASTU = getCursorASTUnit(C);
3337 Preprocessor &PP = ASTU->getPreprocessor();
3338 if (const MacroInfo *MI = PP.getMacroInfo(II))
3339 return MI->isBuiltinMacro();
3340 return false;
3341}
3342
3343unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3344 const Decl *D = getCursorDecl(C);
3345 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3346 if (!FD) {
3347 return false;
3348 }
3349 return FD->isInlined();
3350}
3351
3352static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3353 if (callExpr->getNumArgs() != 1) {
3354 return nullptr;
3355 }
3356
3357 StringLiteral *S = nullptr;
3358 auto *arg = callExpr->getArg(0);
3359 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3360 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3361 auto *subExpr = I->getSubExprAsWritten();
3362
3363 if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3364 return nullptr;
3365 }
3366
3367 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3368 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3369 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3370 } else {
3371 return nullptr;
3372 }
3373 return S;
3374}
3375
3376typedef struct {
3377 CXEvalResultKind EvalType;
3378 union {
3379 int intVal;
3380 double floatVal;
3381 char *stringVal;
3382 } EvalData;
3383} ExprEvalResult;
3384
3385void clang_EvalResult_dispose(CXEvalResult E) {
3386 ExprEvalResult *ER = (ExprEvalResult *)E;
3387 if (ER) {
3388 CXEvalResultKind evalType = ER->EvalType;
3389
3390 if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
3391 evalType != CXEval_Int && ER->EvalData.stringVal) {
3392 free((void *) ER->EvalData.stringVal);
3393 }
3394 free((void *)ER);
3395 }
3396}
3397
3398CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3399 if (!E) {
3400 return CXEval_UnExposed;
3401 }
3402 return ((ExprEvalResult *)E)->EvalType;
3403}
3404
3405int clang_EvalResult_getAsInt(CXEvalResult E) {
3406 if (!E) {
3407 return 0;
3408 }
3409 return ((ExprEvalResult *)E)->EvalData.intVal;
3410}
3411
3412double clang_EvalResult_getAsDouble(CXEvalResult E) {
3413 if (!E) {
3414 return 0;
3415 }
3416 return ((ExprEvalResult *)E)->EvalData.floatVal;
3417}
3418
3419const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3420 if (!E) {
3421 return nullptr;
3422 }
3423 return ((ExprEvalResult *)E)->EvalData.stringVal;
3424}
3425
3426static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3427 Expr::EvalResult ER;
3428 ASTContext &ctx = getCursorContext(C);
3429 if (!expr) {
3430 return nullptr;
3431 }
3432 expr = expr->IgnoreParens();
3433 bool res = expr->EvaluateAsRValue(ER, ctx);
3434 QualType rettype;
3435 CallExpr *callExpr;
3436 ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
3437 if (!result) {
3438 return nullptr;
3439 }
3440 result->EvalType = CXEval_UnExposed;
3441
3442 if (res) {
3443
3444 if (ER.Val.isInt()) {
3445 result->EvalType = CXEval_Int;
3446 result->EvalData.intVal = ER.Val.getInt().getExtValue();
3447 return result;
3448 } else if (ER.Val.isFloat()) {
3449
3450 llvm::SmallVector<char, 100> Buffer;
3451 ER.Val.getFloat().toString(Buffer);
3452 std::string floatStr(Buffer.data(), Buffer.size());
3453 result->EvalType = CXEval_Float;
3454 bool ignored;
3455 llvm::APFloat apFloat = ER.Val.getFloat();
3456 apFloat.convert(llvm::APFloat::IEEEdouble,
3457 llvm::APFloat::rmNearestTiesToEven, &ignored);
3458 result->EvalData.floatVal = apFloat.convertToDouble();
3459 return result;
3460
3461 } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3462
3463 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3464 auto *subExpr = I->getSubExprAsWritten();
3465 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3466 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3467
3468 const StringLiteral *StrE = nullptr;
3469 const ObjCStringLiteral *ObjCExpr;
3470 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3471
3472 if (ObjCExpr) {
3473 StrE = ObjCExpr->getString();
3474 result->EvalType = CXEval_ObjCStrLiteral;
3475 } else {
3476 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3477 result->EvalType = CXEval_StrLiteral;
3478 }
3479
3480 std::string strRef(StrE->getString().str());
3481 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3482 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3483 strRef.size());
3484 result->EvalData.stringVal[strRef.size()] = '\0';
3485 return result;
3486 }
3487
3488 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3489 expr->getStmtClass() == Stmt::StringLiteralClass) {
3490
3491 const StringLiteral *StrE = nullptr;
3492 const ObjCStringLiteral *ObjCExpr;
3493 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3494
3495 if (ObjCExpr) {
3496 StrE = ObjCExpr->getString();
3497 result->EvalType = CXEval_ObjCStrLiteral;
3498 } else {
3499 StrE = cast<StringLiteral>(expr);
3500 result->EvalType = CXEval_StrLiteral;
3501 }
3502
3503 std::string strRef(StrE->getString().str());
3504 result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
3505 strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
3506 strRef.size());
3507 result->EvalData.stringVal[strRef.size()] = '\0';
3508 return result;
3509
3510 } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3511
3512 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3513
3514 rettype = CC->getType();
3515 if (rettype.getAsString() == "CFStringRef" &&
3516 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3517
3518 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3519 StringLiteral* S = getCFSTR_value(callExpr);
3520 if (S) {
3521 std::string strLiteral(S->getString().str());
3522 result->EvalType = CXEval_CFStr;
3523
3524 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3525 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3526 strLiteral.size());
3527 result->EvalData.stringVal[strLiteral.size()] = '\0';
3528 return result;
3529 }
3530 }
3531
3532 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3533
3534 callExpr = static_cast<CallExpr *>(expr);
3535 rettype = callExpr->getCallReturnType(ctx);
3536
3537 if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
3538 return nullptr;
3539 }
3540 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3541 if(callExpr->getNumArgs() == 1 &&
3542 !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
3543
3544 return nullptr;
3545 }
3546 } else if(rettype.getAsString() == "CFStringRef") {
3547
3548 StringLiteral* S = getCFSTR_value(callExpr);
3549 if (S) {
3550 std::string strLiteral(S->getString().str());
3551 result->EvalType = CXEval_CFStr;
3552 result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
3553 strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
3554 strLiteral.size());
3555 result->EvalData.stringVal[strLiteral.size()] = '\0';
3556 return result;
3557 }
3558 }
3559
3560 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3561
3562 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3563 ValueDecl *V = D->getDecl();
3564 if (V->getKind() == Decl::Function) {
3565 std::string strName(V->getNameAsString());
3566 result->EvalType = CXEval_Other;
3567 result->EvalData.stringVal = (char *)malloc(strName.size()+1);
3568 strncpy((char*)result->EvalData.stringVal, strName.c_str(),
3569 strName.size());
3570 result->EvalData.stringVal[strName.size()] = '\0';
3571 return result;
3572 }
3573 }
3574
3575 }
3576
3577 clang_EvalResult_dispose((CXEvalResult *)result);
3578 return nullptr;
3579}
3580
3581CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3582 const Decl *D = getCursorDecl(C);
3583 if (D) {
3584 const Expr *expr = nullptr;
3585 if (auto *Var = dyn_cast<VarDecl>(D)) {
3586 expr = Var->getInit();
3587 } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3588 expr = Field->getInClassInitializer();
3589 }
3590 if (expr)
3591 return (CXEvalResult)evaluateExpr((Expr *)expr, C);
3592 return nullptr;
3593 }
3594
3595 const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3596 if (compoundStmt) {
3597 Expr *expr = nullptr;
3598 for (auto *bodyIterator : compoundStmt->body()) {
3599 if ((expr = dyn_cast<Expr>(bodyIterator))) {
3600 break;
3601 }
3602 }
3603 if (expr)
3604 return (CXEvalResult)evaluateExpr(expr, C);
3605 }
3606 return nullptr;
3607}
3608
3609unsigned clang_Cursor_hasAttrs(CXCursor C) {
3610 const Decl *D = getCursorDecl(C);
3611 if (!D) {
3612 return 0;
3613 }
3614
3615 if (D->hasAttrs()) {
3616 return 1;
3617 }
3618
3619 return 0;
3620}
Guy Benyei11169dd2012-12-18 14:30:41 +00003621unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3622 return CXSaveTranslationUnit_None;
3623}
3624
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003625static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3626 const char *FileName,
3627 unsigned options) {
3628 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3630 setThreadBackgroundPriority();
3631
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003632 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3633 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003634}
3635
3636int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3637 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003638 LOG_FUNC_SECTION {
3639 *Log << TU << ' ' << FileName;
3640 }
3641
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003642 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003643 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003645 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003646
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003647 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3649 if (!CXXUnit->hasSema())
3650 return CXSaveError_InvalidTU;
3651
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003652 CXSaveError result;
3653 auto SaveTranslationUnitImpl = [=, &result]() {
3654 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3655 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003656
3657 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3658 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003659 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003660
3661 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3662 PrintLibclangResourceUsage(TU);
3663
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003664 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 }
3666
3667 // We have an AST that has invalid nodes due to compiler errors.
3668 // Use a crash recovery thread for protection.
3669
3670 llvm::CrashRecoveryContext CRC;
3671
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003672 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3674 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3675 fprintf(stderr, " 'options' : %d,\n", options);
3676 fprintf(stderr, "}\n");
3677
3678 return CXSaveError_Unknown;
3679
3680 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3681 PrintLibclangResourceUsage(TU);
3682 }
3683
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003684 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003685}
3686
3687void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3688 if (CTUnit) {
3689 // If the translation unit has been marked as unsafe to free, just discard
3690 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003691 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3692 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 return;
3694
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003695 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003696 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3698 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003699 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 delete CTUnit;
3701 }
3702}
3703
3704unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3705 return CXReparse_None;
3706}
3707
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003708static CXErrorCode
3709clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3710 ArrayRef<CXUnsavedFile> unsaved_files,
3711 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003712 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003713 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003714 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003715 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003716 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003717
3718 // Reset the associated diagnostics.
3719 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003720 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003721
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003722 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3724 setThreadBackgroundPriority();
3725
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003726 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003728
3729 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3730 new std::vector<ASTUnit::RemappedFile>());
3731
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 // Recover resources if we crash before exiting this function.
3733 llvm::CrashRecoveryContextCleanupRegistrar<
3734 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003735
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003736 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003737 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003738 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003739 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003741
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003742 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3743 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003744 return CXError_Success;
3745 if (isASTReadError(CXXUnit))
3746 return CXError_ASTReadError;
3747 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003748}
3749
3750int clang_reparseTranslationUnit(CXTranslationUnit TU,
3751 unsigned num_unsaved_files,
3752 struct CXUnsavedFile *unsaved_files,
3753 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003754 LOG_FUNC_SECTION {
3755 *Log << TU;
3756 }
3757
Alp Toker9d85b182014-07-07 01:23:14 +00003758 if (num_unsaved_files && !unsaved_files)
3759 return CXError_InvalidArguments;
3760
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003761 CXErrorCode result;
3762 auto ReparseTranslationUnitImpl = [=, &result]() {
3763 result = clang_reparseTranslationUnit_Impl(
3764 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3765 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003766
3767 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003768 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003769 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 }
3771
3772 llvm::CrashRecoveryContext CRC;
3773
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003774 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003776 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003777 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3779 PrintLibclangResourceUsage(TU);
3780
Alp Toker5c532982014-07-07 22:42:03 +00003781 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003782}
3783
3784
3785CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003786 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003787 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003788 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003789 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003790
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003791 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003792 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003793}
3794
3795CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003796 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003797 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003798 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003799 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003800
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003801 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3803}
3804
3805} // end: extern "C"
3806
3807//===----------------------------------------------------------------------===//
3808// CXFile Operations.
3809//===----------------------------------------------------------------------===//
3810
3811extern "C" {
3812CXString clang_getFileName(CXFile SFile) {
3813 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003814 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003815
3816 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003818}
3819
3820time_t clang_getFileTime(CXFile SFile) {
3821 if (!SFile)
3822 return 0;
3823
3824 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3825 return FEnt->getModificationTime();
3826}
3827
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003828CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003829 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003830 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003831 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003832 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003833
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003834 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003835
3836 FileManager &FMgr = CXXUnit->getFileManager();
3837 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3838}
3839
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003840unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3841 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003842 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003843 LOG_BAD_TU(TU);
3844 return 0;
3845 }
3846
3847 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 return 0;
3849
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003850 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 FileEntry *FEnt = static_cast<FileEntry *>(file);
3852 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3853 .isFileMultipleIncludeGuarded(FEnt);
3854}
3855
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003856int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3857 if (!file || !outID)
3858 return 1;
3859
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003860 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003861 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3862 outID->data[0] = ID.getDevice();
3863 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003864 outID->data[2] = FEnt->getModificationTime();
3865 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003866}
3867
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003868int clang_File_isEqual(CXFile file1, CXFile file2) {
3869 if (file1 == file2)
3870 return true;
3871
3872 if (!file1 || !file2)
3873 return false;
3874
3875 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3876 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3877 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3878}
3879
Guy Benyei11169dd2012-12-18 14:30:41 +00003880} // end: extern "C"
3881
3882//===----------------------------------------------------------------------===//
3883// CXCursor Operations.
3884//===----------------------------------------------------------------------===//
3885
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003886static const Decl *getDeclFromExpr(const Stmt *E) {
3887 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 return getDeclFromExpr(CE->getSubExpr());
3889
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003890 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003892 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003894 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003896 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 if (PRE->isExplicitProperty())
3898 return PRE->getExplicitProperty();
3899 // It could be messaging both getter and setter as in:
3900 // ++myobj.myprop;
3901 // in which case prefer to associate the setter since it is less obvious
3902 // from inspecting the source that the setter is going to get called.
3903 if (PRE->isMessagingSetter())
3904 return PRE->getImplicitPropertySetter();
3905 return PRE->getImplicitPropertyGetter();
3906 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003907 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003909 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 if (Expr *Src = OVE->getSourceExpr())
3911 return getDeclFromExpr(Src);
3912
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003913 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003915 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 if (!CE->isElidable())
3917 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003918 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 return OME->getMethodDecl();
3920
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003921 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003923 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3925 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003926 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3928 isa<ParmVarDecl>(SizeOfPack->getPack()))
3929 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003930
3931 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003932}
3933
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003934static SourceLocation getLocationFromExpr(const Expr *E) {
3935 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 return getLocationFromExpr(CE->getSubExpr());
3937
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003938 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003939 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003940 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003942 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003943 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003944 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003946 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003948 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 return PropRef->getLocation();
3950
3951 return E->getLocStart();
3952}
3953
Aaron Ballmana85d3f82015-11-12 15:25:06 +00003954static std::string getMangledStructor(std::unique_ptr<MangleContext> &M,
3955 std::unique_ptr<llvm::DataLayout> &DL,
3956 const NamedDecl *ND,
3957 unsigned StructorType) {
3958 std::string FrontendBuf;
3959 llvm::raw_string_ostream FOS(FrontendBuf);
3960
3961 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND))
3962 M->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS);
3963 else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND))
3964 M->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS);
3965
3966 std::string BackendBuf;
3967 llvm::raw_string_ostream BOS(BackendBuf);
3968
3969 llvm::Mangler::getNameWithPrefix(BOS, llvm::Twine(FOS.str()), *DL);
3970
3971 return BOS.str();
3972}
3973
Guy Benyei11169dd2012-12-18 14:30:41 +00003974extern "C" {
3975
3976unsigned clang_visitChildren(CXCursor parent,
3977 CXCursorVisitor visitor,
3978 CXClientData client_data) {
3979 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3980 /*VisitPreprocessorLast=*/false);
3981 return CursorVis.VisitChildren(parent);
3982}
3983
3984#ifndef __has_feature
3985#define __has_feature(x) 0
3986#endif
3987#if __has_feature(blocks)
3988typedef enum CXChildVisitResult
3989 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3990
3991static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3992 CXClientData client_data) {
3993 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3994 return block(cursor, parent);
3995}
3996#else
3997// If we are compiled with a compiler that doesn't have native blocks support,
3998// define and call the block manually, so the
3999typedef struct _CXChildVisitResult
4000{
4001 void *isa;
4002 int flags;
4003 int reserved;
4004 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4005 CXCursor);
4006} *CXCursorVisitorBlock;
4007
4008static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4009 CXClientData client_data) {
4010 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4011 return block->invoke(block, cursor, parent);
4012}
4013#endif
4014
4015
4016unsigned clang_visitChildrenWithBlock(CXCursor parent,
4017 CXCursorVisitorBlock block) {
4018 return clang_visitChildren(parent, visitWithBlock, block);
4019}
4020
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004021static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004023 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004024
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004025 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004026 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004027 if (const ObjCPropertyImplDecl *PropImpl =
4028 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004030 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004031
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004032 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004034 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004035
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004036 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 }
4038
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004039 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004040 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004041
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004042 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4044 // and returns different names. NamedDecl returns the class name and
4045 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004047
4048 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004049 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004050
4051 SmallString<1024> S;
4052 llvm::raw_svector_ostream os(S);
4053 ND->printName(os);
4054
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004055 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004056}
4057
4058CXString clang_getCursorSpelling(CXCursor C) {
4059 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004060 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004061
4062 if (clang_isReference(C.kind)) {
4063 switch (C.kind) {
4064 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004065 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 }
4068 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004069 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 }
4072 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004073 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004075 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 }
4077 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004078 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004079 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 }
4081 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004082 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 assert(Type && "Missing type decl");
4084
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004085 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 getAsString());
4087 }
4088 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004089 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 assert(Template && "Missing template decl");
4091
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004092 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 }
4094
4095 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004096 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 assert(NS && "Missing namespace decl");
4098
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004099 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 }
4101
4102 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004103 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 assert(Field && "Missing member decl");
4105
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004106 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 }
4108
4109 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004110 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 assert(Label && "Missing label");
4112
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004113 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 }
4115
4116 case CXCursor_OverloadedDeclRef: {
4117 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004118 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4119 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004120 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004121 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004123 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004124 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 OverloadedTemplateStorage *Ovl
4126 = Storage.get<OverloadedTemplateStorage*>();
4127 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004128 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004129 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 }
4131
4132 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004133 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 assert(Var && "Missing variable decl");
4135
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004136 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 }
4138
4139 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 }
4142 }
4143
4144 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004145 const Expr *E = getCursorExpr(C);
4146
4147 if (C.kind == CXCursor_ObjCStringLiteral ||
4148 C.kind == CXCursor_StringLiteral) {
4149 const StringLiteral *SLit;
4150 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4151 SLit = OSL->getString();
4152 } else {
4153 SLit = cast<StringLiteral>(E);
4154 }
4155 SmallString<256> Buf;
4156 llvm::raw_svector_ostream OS(Buf);
4157 SLit->outputString(OS);
4158 return cxstring::createDup(OS.str());
4159 }
4160
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004161 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 if (D)
4163 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004164 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 }
4166
4167 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004168 const Stmt *S = getCursorStmt(C);
4169 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004171
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004172 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 }
4174
4175 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 ->getNameStart());
4178
4179 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 ->getNameStart());
4182
4183 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004184 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004185
4186 if (clang_isDeclaration(C.kind))
4187 return getDeclSpelling(getCursorDecl(C));
4188
4189 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004190 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004191 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 }
4193
4194 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004195 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004196 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 }
4198
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004199 if (C.kind == CXCursor_PackedAttr) {
4200 return cxstring::createRef("packed");
4201 }
4202
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004203 if (C.kind == CXCursor_VisibilityAttr) {
4204 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4205 switch (AA->getVisibility()) {
4206 case VisibilityAttr::VisibilityType::Default:
4207 return cxstring::createRef("default");
4208 case VisibilityAttr::VisibilityType::Hidden:
4209 return cxstring::createRef("hidden");
4210 case VisibilityAttr::VisibilityType::Protected:
4211 return cxstring::createRef("protected");
4212 }
4213 llvm_unreachable("unknown visibility type");
4214 }
4215
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004216 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004217}
4218
4219CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4220 unsigned pieceIndex,
4221 unsigned options) {
4222 if (clang_Cursor_isNull(C))
4223 return clang_getNullRange();
4224
4225 ASTContext &Ctx = getCursorContext(C);
4226
4227 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004228 const Stmt *S = getCursorStmt(C);
4229 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 if (pieceIndex > 0)
4231 return clang_getNullRange();
4232 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4233 }
4234
4235 return clang_getNullRange();
4236 }
4237
4238 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004239 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00004240 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4241 if (pieceIndex >= ME->getNumSelectorLocs())
4242 return clang_getNullRange();
4243 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4244 }
4245 }
4246
4247 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4248 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004249 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4251 if (pieceIndex >= MD->getNumSelectorLocs())
4252 return clang_getNullRange();
4253 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4254 }
4255 }
4256
4257 if (C.kind == CXCursor_ObjCCategoryDecl ||
4258 C.kind == CXCursor_ObjCCategoryImplDecl) {
4259 if (pieceIndex > 0)
4260 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004261 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4263 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004264 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4266 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4267 }
4268
4269 if (C.kind == CXCursor_ModuleImportDecl) {
4270 if (pieceIndex > 0)
4271 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004272 if (const ImportDecl *ImportD =
4273 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4275 if (!Locs.empty())
4276 return cxloc::translateSourceRange(Ctx,
4277 SourceRange(Locs.front(), Locs.back()));
4278 }
4279 return clang_getNullRange();
4280 }
4281
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004282 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4283 C.kind == CXCursor_ConversionFunction) {
4284 if (pieceIndex > 0)
4285 return clang_getNullRange();
4286 if (const FunctionDecl *FD =
4287 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4288 DeclarationNameInfo FunctionName = FD->getNameInfo();
4289 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4290 }
4291 return clang_getNullRange();
4292 }
4293
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 // FIXME: A CXCursor_InclusionDirective should give the location of the
4295 // filename, but we don't keep track of this.
4296
4297 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4298 // but we don't keep track of this.
4299
4300 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4301 // but we don't keep track of this.
4302
4303 // Default handling, give the location of the cursor.
4304
4305 if (pieceIndex > 0)
4306 return clang_getNullRange();
4307
4308 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4309 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4310 return cxloc::translateSourceRange(Ctx, Loc);
4311}
4312
Eli Bendersky44a206f2014-07-31 18:04:56 +00004313CXString clang_Cursor_getMangling(CXCursor C) {
4314 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4315 return cxstring::createEmpty();
4316
Eli Bendersky44a206f2014-07-31 18:04:56 +00004317 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004318 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004319 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4320 return cxstring::createEmpty();
4321
Eli Bendersky79759592014-08-01 15:01:10 +00004322 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00004323 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00004324 ASTContext &Ctx = ND->getASTContext();
4325 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004326
Eli Bendersky79759592014-08-01 15:01:10 +00004327 std::string FrontendBuf;
4328 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
Ehsan Akhgarif8d44de2015-10-08 00:01:20 +00004329 if (MC->shouldMangleDeclName(ND)) {
4330 MC->mangleName(ND, FrontendBufOS);
4331 } else {
4332 ND->printName(FrontendBufOS);
4333 }
Eli Bendersky44a206f2014-07-31 18:04:56 +00004334
Eli Bendersky79759592014-08-01 15:01:10 +00004335 // Now apply backend mangling.
4336 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00004337 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00004338
4339 std::string FinalBuf;
4340 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00004341 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
4342 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00004343
4344 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00004345}
4346
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004347CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4348 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4349 return nullptr;
4350
4351 const Decl *D = getCursorDecl(C);
4352 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4353 return nullptr;
4354
4355 const NamedDecl *ND = cast<NamedDecl>(D);
4356
4357 ASTContext &Ctx = ND->getASTContext();
4358 std::unique_ptr<MangleContext> M(Ctx.createMangleContext());
4359 std::unique_ptr<llvm::DataLayout> DL(
4360 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
4361
4362 std::vector<std::string> Manglings;
4363
4364 auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) {
4365 auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false,
4366 /*IsCSSMethod=*/true);
4367 auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv();
4368 return CC == DefaultCC;
4369 };
4370
4371 if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) {
4372 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Base));
4373
4374 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily())
4375 if (!CD->getParent()->isAbstract())
4376 Manglings.emplace_back(getMangledStructor(M, DL, CD, Ctor_Complete));
4377
4378 if (Ctx.getTargetInfo().getCXXABI().isMicrosoft())
4379 if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor())
4380 if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0))
4381 Manglings.emplace_back(getMangledStructor(M, DL, CD,
4382 Ctor_DefaultClosure));
4383 } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) {
4384 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Base));
4385 if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) {
4386 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Complete));
Saleem Abdulrasoold5af8ae2015-12-10 06:30:23 +00004387 if (DD->isVirtual())
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004388 Manglings.emplace_back(getMangledStructor(M, DL, DD, Dtor_Deleting));
4389 }
4390 }
4391
4392 return cxstring::createSet(Manglings);
4393}
4394
Guy Benyei11169dd2012-12-18 14:30:41 +00004395CXString clang_getCursorDisplayName(CXCursor C) {
4396 if (!clang_isDeclaration(C.kind))
4397 return clang_getCursorSpelling(C);
4398
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004399 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004401 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004402
4403 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004404 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 D = FunTmpl->getTemplatedDecl();
4406
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004407 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 SmallString<64> Str;
4409 llvm::raw_svector_ostream OS(Str);
4410 OS << *Function;
4411 if (Function->getPrimaryTemplate())
4412 OS << "<>";
4413 OS << "(";
4414 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4415 if (I)
4416 OS << ", ";
4417 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4418 }
4419
4420 if (Function->isVariadic()) {
4421 if (Function->getNumParams())
4422 OS << ", ";
4423 OS << "...";
4424 }
4425 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004426 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004427 }
4428
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004429 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 SmallString<64> Str;
4431 llvm::raw_svector_ostream OS(Str);
4432 OS << *ClassTemplate;
4433 OS << "<";
4434 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4435 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4436 if (I)
4437 OS << ", ";
4438
4439 NamedDecl *Param = Params->getParam(I);
4440 if (Param->getIdentifier()) {
4441 OS << Param->getIdentifier()->getName();
4442 continue;
4443 }
4444
4445 // There is no parameter name, which makes this tricky. Try to come up
4446 // with something useful that isn't too long.
4447 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4448 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4449 else if (NonTypeTemplateParmDecl *NTTP
4450 = dyn_cast<NonTypeTemplateParmDecl>(Param))
4451 OS << NTTP->getType().getAsString(Policy);
4452 else
4453 OS << "template<...> class";
4454 }
4455
4456 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004457 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 }
4459
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004460 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00004461 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4462 // If the type was explicitly written, use that.
4463 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004464 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00004465
Benjamin Kramer9170e912013-02-22 15:46:01 +00004466 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 llvm::raw_svector_ostream OS(Str);
4468 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00004469 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 ClassSpec->getTemplateArgs().data(),
4471 ClassSpec->getTemplateArgs().size(),
4472 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004473 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 }
4475
4476 return clang_getCursorSpelling(C);
4477}
4478
4479CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4480 switch (Kind) {
4481 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004482 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004484 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004486 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004488 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004490 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004492 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004494 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004496 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004498 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004500 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004502 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004504 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004506 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004508 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004510 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004512 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004514 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004516 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004518 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004520 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004522 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004524 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004526 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004528 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004530 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004532 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004534 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004536 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004538 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004540 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004542 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004544 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004550 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004552 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004554 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004556 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004558 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004559 case CXCursor_OMPArraySectionExpr:
4560 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004562 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004564 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004566 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004570 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004572 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004574 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004576 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004578 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004580 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004582 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004584 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004588 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004596 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004600 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004602 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004606 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004608 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004609 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004610 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004611 case CXCursor_ObjCSelfExpr:
4612 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004614 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004616 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004618 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004620 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004622 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004624 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004626 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004628 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004632 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004634 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004636 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004638 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004640 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004642 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004644 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004646 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004648 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004650 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004652 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004654 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004656 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004658 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004660 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004662 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004666 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004668 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004670 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004671 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004672 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004674 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004675 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004676 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004678 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004680 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004682 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004684 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004686 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004688 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004690 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004692 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004694 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004696 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004698 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004700 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004701 case CXCursor_SEHLeaveStmt:
4702 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004704 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004706 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004707 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004708 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004710 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004712 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004714 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004716 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004718 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004720 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004722 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004724 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004726 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004728 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004730 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004731 case CXCursor_PackedAttr:
4732 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004733 case CXCursor_PureAttr:
4734 return cxstring::createRef("attribute(pure)");
4735 case CXCursor_ConstAttr:
4736 return cxstring::createRef("attribute(const)");
4737 case CXCursor_NoDuplicateAttr:
4738 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004739 case CXCursor_CUDAConstantAttr:
4740 return cxstring::createRef("attribute(constant)");
4741 case CXCursor_CUDADeviceAttr:
4742 return cxstring::createRef("attribute(device)");
4743 case CXCursor_CUDAGlobalAttr:
4744 return cxstring::createRef("attribute(global)");
4745 case CXCursor_CUDAHostAttr:
4746 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004747 case CXCursor_CUDASharedAttr:
4748 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004749 case CXCursor_VisibilityAttr:
4750 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00004751 case CXCursor_DLLExport:
4752 return cxstring::createRef("attribute(dllexport)");
4753 case CXCursor_DLLImport:
4754 return cxstring::createRef("attribute(dllimport)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004756 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004758 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004759 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004760 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004762 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004764 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004766 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004768 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004770 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004772 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004774 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004776 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004778 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004780 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004782 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004784 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004786 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004788 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004790 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004792 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004793 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004794 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004795 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004796 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004798 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004800 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004802 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004803 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004804 return cxstring::createRef("OMPParallelDirective");
4805 case CXCursor_OMPSimdDirective:
4806 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004807 case CXCursor_OMPForDirective:
4808 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004809 case CXCursor_OMPForSimdDirective:
4810 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004811 case CXCursor_OMPSectionsDirective:
4812 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004813 case CXCursor_OMPSectionDirective:
4814 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004815 case CXCursor_OMPSingleDirective:
4816 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004817 case CXCursor_OMPMasterDirective:
4818 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004819 case CXCursor_OMPCriticalDirective:
4820 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004821 case CXCursor_OMPParallelForDirective:
4822 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004823 case CXCursor_OMPParallelForSimdDirective:
4824 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004825 case CXCursor_OMPParallelSectionsDirective:
4826 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004827 case CXCursor_OMPTaskDirective:
4828 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004829 case CXCursor_OMPTaskyieldDirective:
4830 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004831 case CXCursor_OMPBarrierDirective:
4832 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004833 case CXCursor_OMPTaskwaitDirective:
4834 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004835 case CXCursor_OMPTaskgroupDirective:
4836 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004837 case CXCursor_OMPFlushDirective:
4838 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004839 case CXCursor_OMPOrderedDirective:
4840 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004841 case CXCursor_OMPAtomicDirective:
4842 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004843 case CXCursor_OMPTargetDirective:
4844 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004845 case CXCursor_OMPTargetDataDirective:
4846 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00004847 case CXCursor_OMPTargetEnterDataDirective:
4848 return cxstring::createRef("OMPTargetEnterDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004849 case CXCursor_OMPTeamsDirective:
4850 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004851 case CXCursor_OMPCancellationPointDirective:
4852 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004853 case CXCursor_OMPCancelDirective:
4854 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00004855 case CXCursor_OMPTaskLoopDirective:
4856 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00004857 case CXCursor_OMPTaskLoopSimdDirective:
4858 return cxstring::createRef("OMPTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00004859 case CXCursor_OMPDistributeDirective:
4860 return cxstring::createRef("OMPDistributeDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004861 case CXCursor_OverloadCandidate:
4862 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00004863 case CXCursor_TypeAliasTemplateDecl:
4864 return cxstring::createRef("TypeAliasTemplateDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 }
4866
4867 llvm_unreachable("Unhandled CXCursorKind");
4868}
4869
4870struct GetCursorData {
4871 SourceLocation TokenBeginLoc;
4872 bool PointsAtMacroArgExpansion;
4873 bool VisitedObjCPropertyImplDecl;
4874 SourceLocation VisitedDeclaratorDeclStartLoc;
4875 CXCursor &BestCursor;
4876
4877 GetCursorData(SourceManager &SM,
4878 SourceLocation tokenBegin, CXCursor &outputCursor)
4879 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4880 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4881 VisitedObjCPropertyImplDecl = false;
4882 }
4883};
4884
4885static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4886 CXCursor parent,
4887 CXClientData client_data) {
4888 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4889 CXCursor *BestCursor = &Data->BestCursor;
4890
4891 // If we point inside a macro argument we should provide info of what the
4892 // token is so use the actual cursor, don't replace it with a macro expansion
4893 // cursor.
4894 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4895 return CXChildVisit_Recurse;
4896
4897 if (clang_isDeclaration(cursor.kind)) {
4898 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004899 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004900 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4901 if (MD->isImplicit())
4902 return CXChildVisit_Break;
4903
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004904 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004905 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4906 // Check that when we have multiple @class references in the same line,
4907 // that later ones do not override the previous ones.
4908 // If we have:
4909 // @class Foo, Bar;
4910 // source ranges for both start at '@', so 'Bar' will end up overriding
4911 // 'Foo' even though the cursor location was at 'Foo'.
4912 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4913 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004914 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4916 if (PrevID != ID &&
4917 !PrevID->isThisDeclarationADefinition() &&
4918 !ID->isThisDeclarationADefinition())
4919 return CXChildVisit_Break;
4920 }
4921
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004922 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4924 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4925 // Check that when we have multiple declarators in the same line,
4926 // that later ones do not override the previous ones.
4927 // If we have:
4928 // int Foo, Bar;
4929 // source ranges for both start at 'int', so 'Bar' will end up overriding
4930 // 'Foo' even though the cursor location was at 'Foo'.
4931 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4932 return CXChildVisit_Break;
4933 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4934
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004935 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004936 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4937 (void)PropImp;
4938 // Check that when we have multiple @synthesize in the same line,
4939 // that later ones do not override the previous ones.
4940 // If we have:
4941 // @synthesize Foo, Bar;
4942 // source ranges for both start at '@', so 'Bar' will end up overriding
4943 // 'Foo' even though the cursor location was at 'Foo'.
4944 if (Data->VisitedObjCPropertyImplDecl)
4945 return CXChildVisit_Break;
4946 Data->VisitedObjCPropertyImplDecl = true;
4947 }
4948 }
4949
4950 if (clang_isExpression(cursor.kind) &&
4951 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004952 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 // Avoid having the cursor of an expression replace the declaration cursor
4954 // when the expression source range overlaps the declaration range.
4955 // This can happen for C++ constructor expressions whose range generally
4956 // include the variable declaration, e.g.:
4957 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4958 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4959 D->getLocation() == Data->TokenBeginLoc)
4960 return CXChildVisit_Break;
4961 }
4962 }
4963
4964 // If our current best cursor is the construction of a temporary object,
4965 // don't replace that cursor with a type reference, because we want
4966 // clang_getCursor() to point at the constructor.
4967 if (clang_isExpression(BestCursor->kind) &&
4968 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4969 cursor.kind == CXCursor_TypeRef) {
4970 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4971 // as having the actual point on the type reference.
4972 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4973 return CXChildVisit_Recurse;
4974 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004975
4976 // If we already have an Objective-C superclass reference, don't
4977 // update it further.
4978 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4979 return CXChildVisit_Break;
4980
Guy Benyei11169dd2012-12-18 14:30:41 +00004981 *BestCursor = cursor;
4982 return CXChildVisit_Recurse;
4983}
4984
4985CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004986 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004987 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004988 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004989 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004990
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004991 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4993
4994 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4995 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4996
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004997 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 CXFile SearchFile;
4999 unsigned SearchLine, SearchColumn;
5000 CXFile ResultFile;
5001 unsigned ResultLine, ResultColumn;
5002 CXString SearchFileName, ResultFileName, KindSpelling, USR;
5003 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
5004 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005005
5006 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5007 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005008 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00005009 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005010 SearchFileName = clang_getFileName(SearchFile);
5011 ResultFileName = clang_getFileName(ResultFile);
5012 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5013 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005014 *Log << llvm::format("(%s:%d:%d) = %s",
5015 clang_getCString(SearchFileName), SearchLine, SearchColumn,
5016 clang_getCString(KindSpelling))
5017 << llvm::format("(%s:%d:%d):%s%s",
5018 clang_getCString(ResultFileName), ResultLine, ResultColumn,
5019 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005020 clang_disposeString(SearchFileName);
5021 clang_disposeString(ResultFileName);
5022 clang_disposeString(KindSpelling);
5023 clang_disposeString(USR);
5024
5025 CXCursor Definition = clang_getCursorDefinition(Result);
5026 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5027 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5028 CXString DefinitionKindSpelling
5029 = clang_getCursorKindSpelling(Definition.kind);
5030 CXFile DefinitionFile;
5031 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005032 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00005033 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005034 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005035 *Log << llvm::format(" -> %s(%s:%d:%d)",
5036 clang_getCString(DefinitionKindSpelling),
5037 clang_getCString(DefinitionFileName),
5038 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005039 clang_disposeString(DefinitionFileName);
5040 clang_disposeString(DefinitionKindSpelling);
5041 }
5042 }
5043
5044 return Result;
5045}
5046
5047CXCursor clang_getNullCursor(void) {
5048 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5049}
5050
5051unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005052 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5053 // can't set consistently. For example, when visiting a DeclStmt we will set
5054 // it but we don't set it on the result of clang_getCursorDefinition for
5055 // a reference of the same declaration.
5056 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5057 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5058 // to provide that kind of info.
5059 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005060 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005061 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005062 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005063
Guy Benyei11169dd2012-12-18 14:30:41 +00005064 return X == Y;
5065}
5066
5067unsigned clang_hashCursor(CXCursor C) {
5068 unsigned Index = 0;
5069 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5070 Index = 1;
5071
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005072 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00005073 std::make_pair(C.kind, C.data[Index]));
5074}
5075
5076unsigned clang_isInvalid(enum CXCursorKind K) {
5077 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5078}
5079
5080unsigned clang_isDeclaration(enum CXCursorKind K) {
5081 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5082 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5083}
5084
5085unsigned clang_isReference(enum CXCursorKind K) {
5086 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5087}
5088
5089unsigned clang_isExpression(enum CXCursorKind K) {
5090 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5091}
5092
5093unsigned clang_isStatement(enum CXCursorKind K) {
5094 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5095}
5096
5097unsigned clang_isAttribute(enum CXCursorKind K) {
5098 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5099}
5100
5101unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5102 return K == CXCursor_TranslationUnit;
5103}
5104
5105unsigned clang_isPreprocessing(enum CXCursorKind K) {
5106 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5107}
5108
5109unsigned clang_isUnexposed(enum CXCursorKind K) {
5110 switch (K) {
5111 case CXCursor_UnexposedDecl:
5112 case CXCursor_UnexposedExpr:
5113 case CXCursor_UnexposedStmt:
5114 case CXCursor_UnexposedAttr:
5115 return true;
5116 default:
5117 return false;
5118 }
5119}
5120
5121CXCursorKind clang_getCursorKind(CXCursor C) {
5122 return C.kind;
5123}
5124
5125CXSourceLocation clang_getCursorLocation(CXCursor C) {
5126 if (clang_isReference(C.kind)) {
5127 switch (C.kind) {
5128 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005129 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 = getCursorObjCSuperClassRef(C);
5131 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5132 }
5133
5134 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005135 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 = getCursorObjCProtocolRef(C);
5137 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5138 }
5139
5140 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005141 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 = getCursorObjCClassRef(C);
5143 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5144 }
5145
5146 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005147 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5149 }
5150
5151 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005152 std::pair<const TemplateDecl *, SourceLocation> P =
5153 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005154 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5155 }
5156
5157 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005158 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5160 }
5161
5162 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005163 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005164 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5165 }
5166
5167 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005168 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005169 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5170 }
5171
5172 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005173 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 if (!BaseSpec)
5175 return clang_getNullLocation();
5176
5177 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5178 return cxloc::translateSourceLocation(getCursorContext(C),
5179 TSInfo->getTypeLoc().getBeginLoc());
5180
5181 return cxloc::translateSourceLocation(getCursorContext(C),
5182 BaseSpec->getLocStart());
5183 }
5184
5185 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005186 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005187 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5188 }
5189
5190 case CXCursor_OverloadedDeclRef:
5191 return cxloc::translateSourceLocation(getCursorContext(C),
5192 getCursorOverloadedDeclRef(C).second);
5193
5194 default:
5195 // FIXME: Need a way to enumerate all non-reference cases.
5196 llvm_unreachable("Missed a reference kind");
5197 }
5198 }
5199
5200 if (clang_isExpression(C.kind))
5201 return cxloc::translateSourceLocation(getCursorContext(C),
5202 getLocationFromExpr(getCursorExpr(C)));
5203
5204 if (clang_isStatement(C.kind))
5205 return cxloc::translateSourceLocation(getCursorContext(C),
5206 getCursorStmt(C)->getLocStart());
5207
5208 if (C.kind == CXCursor_PreprocessingDirective) {
5209 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5210 return cxloc::translateSourceLocation(getCursorContext(C), L);
5211 }
5212
5213 if (C.kind == CXCursor_MacroExpansion) {
5214 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005215 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 return cxloc::translateSourceLocation(getCursorContext(C), L);
5217 }
5218
5219 if (C.kind == CXCursor_MacroDefinition) {
5220 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5221 return cxloc::translateSourceLocation(getCursorContext(C), L);
5222 }
5223
5224 if (C.kind == CXCursor_InclusionDirective) {
5225 SourceLocation L
5226 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5227 return cxloc::translateSourceLocation(getCursorContext(C), L);
5228 }
5229
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005230 if (clang_isAttribute(C.kind)) {
5231 SourceLocation L
5232 = cxcursor::getCursorAttr(C)->getLocation();
5233 return cxloc::translateSourceLocation(getCursorContext(C), L);
5234 }
5235
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 if (!clang_isDeclaration(C.kind))
5237 return clang_getNullLocation();
5238
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005239 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 if (!D)
5241 return clang_getNullLocation();
5242
5243 SourceLocation Loc = D->getLocation();
5244 // FIXME: Multiple variables declared in a single declaration
5245 // currently lack the information needed to correctly determine their
5246 // ranges when accounting for the type-specifier. We use context
5247 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5248 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005249 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 if (!cxcursor::isFirstInDeclGroup(C))
5251 Loc = VD->getLocation();
5252 }
5253
5254 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005255 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 Loc = MD->getSelectorStartLoc();
5257
5258 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5259}
5260
5261} // end extern "C"
5262
5263CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5264 assert(TU);
5265
5266 // Guard against an invalid SourceLocation, or we may assert in one
5267 // of the following calls.
5268 if (SLoc.isInvalid())
5269 return clang_getNullCursor();
5270
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005271 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005272
5273 // Translate the given source location to make it point at the beginning of
5274 // the token under the cursor.
5275 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5276 CXXUnit->getASTContext().getLangOpts());
5277
5278 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5279 if (SLoc.isValid()) {
5280 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5281 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5282 /*VisitPreprocessorLast=*/true,
5283 /*VisitIncludedEntities=*/false,
5284 SourceLocation(SLoc));
5285 CursorVis.visitFileRegion();
5286 }
5287
5288 return Result;
5289}
5290
5291static SourceRange getRawCursorExtent(CXCursor C) {
5292 if (clang_isReference(C.kind)) {
5293 switch (C.kind) {
5294 case CXCursor_ObjCSuperClassRef:
5295 return getCursorObjCSuperClassRef(C).second;
5296
5297 case CXCursor_ObjCProtocolRef:
5298 return getCursorObjCProtocolRef(C).second;
5299
5300 case CXCursor_ObjCClassRef:
5301 return getCursorObjCClassRef(C).second;
5302
5303 case CXCursor_TypeRef:
5304 return getCursorTypeRef(C).second;
5305
5306 case CXCursor_TemplateRef:
5307 return getCursorTemplateRef(C).second;
5308
5309 case CXCursor_NamespaceRef:
5310 return getCursorNamespaceRef(C).second;
5311
5312 case CXCursor_MemberRef:
5313 return getCursorMemberRef(C).second;
5314
5315 case CXCursor_CXXBaseSpecifier:
5316 return getCursorCXXBaseSpecifier(C)->getSourceRange();
5317
5318 case CXCursor_LabelRef:
5319 return getCursorLabelRef(C).second;
5320
5321 case CXCursor_OverloadedDeclRef:
5322 return getCursorOverloadedDeclRef(C).second;
5323
5324 case CXCursor_VariableRef:
5325 return getCursorVariableRef(C).second;
5326
5327 default:
5328 // FIXME: Need a way to enumerate all non-reference cases.
5329 llvm_unreachable("Missed a reference kind");
5330 }
5331 }
5332
5333 if (clang_isExpression(C.kind))
5334 return getCursorExpr(C)->getSourceRange();
5335
5336 if (clang_isStatement(C.kind))
5337 return getCursorStmt(C)->getSourceRange();
5338
5339 if (clang_isAttribute(C.kind))
5340 return getCursorAttr(C)->getRange();
5341
5342 if (C.kind == CXCursor_PreprocessingDirective)
5343 return cxcursor::getCursorPreprocessingDirective(C);
5344
5345 if (C.kind == CXCursor_MacroExpansion) {
5346 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005347 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 return TU->mapRangeFromPreamble(Range);
5349 }
5350
5351 if (C.kind == CXCursor_MacroDefinition) {
5352 ASTUnit *TU = getCursorASTUnit(C);
5353 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5354 return TU->mapRangeFromPreamble(Range);
5355 }
5356
5357 if (C.kind == CXCursor_InclusionDirective) {
5358 ASTUnit *TU = getCursorASTUnit(C);
5359 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5360 return TU->mapRangeFromPreamble(Range);
5361 }
5362
5363 if (C.kind == CXCursor_TranslationUnit) {
5364 ASTUnit *TU = getCursorASTUnit(C);
5365 FileID MainID = TU->getSourceManager().getMainFileID();
5366 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5367 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5368 return SourceRange(Start, End);
5369 }
5370
5371 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005372 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 if (!D)
5374 return SourceRange();
5375
5376 SourceRange R = D->getSourceRange();
5377 // FIXME: Multiple variables declared in a single declaration
5378 // currently lack the information needed to correctly determine their
5379 // ranges when accounting for the type-specifier. We use context
5380 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5381 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005382 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005383 if (!cxcursor::isFirstInDeclGroup(C))
5384 R.setBegin(VD->getLocation());
5385 }
5386 return R;
5387 }
5388 return SourceRange();
5389}
5390
5391/// \brief Retrieves the "raw" cursor extent, which is then extended to include
5392/// the decl-specifier-seq for declarations.
5393static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5394 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005395 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005396 if (!D)
5397 return SourceRange();
5398
5399 SourceRange R = D->getSourceRange();
5400
5401 // Adjust the start of the location for declarations preceded by
5402 // declaration specifiers.
5403 SourceLocation StartLoc;
5404 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5405 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5406 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005407 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5409 StartLoc = TI->getTypeLoc().getLocStart();
5410 }
5411
5412 if (StartLoc.isValid() && R.getBegin().isValid() &&
5413 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5414 R.setBegin(StartLoc);
5415
5416 // FIXME: Multiple variables declared in a single declaration
5417 // currently lack the information needed to correctly determine their
5418 // ranges when accounting for the type-specifier. We use context
5419 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5420 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005421 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 if (!cxcursor::isFirstInDeclGroup(C))
5423 R.setBegin(VD->getLocation());
5424 }
5425
5426 return R;
5427 }
5428
5429 return getRawCursorExtent(C);
5430}
5431
5432extern "C" {
5433
5434CXSourceRange clang_getCursorExtent(CXCursor C) {
5435 SourceRange R = getRawCursorExtent(C);
5436 if (R.isInvalid())
5437 return clang_getNullRange();
5438
5439 return cxloc::translateSourceRange(getCursorContext(C), R);
5440}
5441
5442CXCursor clang_getCursorReferenced(CXCursor C) {
5443 if (clang_isInvalid(C.kind))
5444 return clang_getNullCursor();
5445
5446 CXTranslationUnit tu = getCursorTU(C);
5447 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005448 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 if (!D)
5450 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005451 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005452 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005453 if (const ObjCPropertyImplDecl *PropImpl =
5454 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5456 return MakeCXCursor(Property, tu);
5457
5458 return C;
5459 }
5460
5461 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005462 const Expr *E = getCursorExpr(C);
5463 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 if (D) {
5465 CXCursor declCursor = MakeCXCursor(D, tu);
5466 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5467 declCursor);
5468 return declCursor;
5469 }
5470
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005471 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00005472 return MakeCursorOverloadedDeclRef(Ovl, tu);
5473
5474 return clang_getNullCursor();
5475 }
5476
5477 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005478 const Stmt *S = getCursorStmt(C);
5479 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00005480 if (LabelDecl *label = Goto->getLabel())
5481 if (LabelStmt *labelS = label->getStmt())
5482 return MakeCXCursor(labelS, getCursorDecl(C), tu);
5483
5484 return clang_getNullCursor();
5485 }
Richard Smith66a81862015-05-04 02:25:31 +00005486
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00005488 if (const MacroDefinitionRecord *Def =
5489 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005490 return MakeMacroDefinitionCursor(Def, tu);
5491 }
5492
5493 if (!clang_isReference(C.kind))
5494 return clang_getNullCursor();
5495
5496 switch (C.kind) {
5497 case CXCursor_ObjCSuperClassRef:
5498 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5499
5500 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005501 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5502 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005503 return MakeCXCursor(Def, tu);
5504
5505 return MakeCXCursor(Prot, tu);
5506 }
5507
5508 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005509 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5510 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 return MakeCXCursor(Def, tu);
5512
5513 return MakeCXCursor(Class, tu);
5514 }
5515
5516 case CXCursor_TypeRef:
5517 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5518
5519 case CXCursor_TemplateRef:
5520 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5521
5522 case CXCursor_NamespaceRef:
5523 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5524
5525 case CXCursor_MemberRef:
5526 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5527
5528 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005529 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005530 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5531 tu ));
5532 }
5533
5534 case CXCursor_LabelRef:
5535 // FIXME: We end up faking the "parent" declaration here because we
5536 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005537 return MakeCXCursor(getCursorLabelRef(C).first,
5538 cxtu::getASTUnit(tu)->getASTContext()
5539 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005540 tu);
5541
5542 case CXCursor_OverloadedDeclRef:
5543 return C;
5544
5545 case CXCursor_VariableRef:
5546 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5547
5548 default:
5549 // We would prefer to enumerate all non-reference cursor kinds here.
5550 llvm_unreachable("Unhandled reference cursor kind");
5551 }
5552}
5553
5554CXCursor clang_getCursorDefinition(CXCursor C) {
5555 if (clang_isInvalid(C.kind))
5556 return clang_getNullCursor();
5557
5558 CXTranslationUnit TU = getCursorTU(C);
5559
5560 bool WasReference = false;
5561 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5562 C = clang_getCursorReferenced(C);
5563 WasReference = true;
5564 }
5565
5566 if (C.kind == CXCursor_MacroExpansion)
5567 return clang_getCursorReferenced(C);
5568
5569 if (!clang_isDeclaration(C.kind))
5570 return clang_getNullCursor();
5571
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005572 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005573 if (!D)
5574 return clang_getNullCursor();
5575
5576 switch (D->getKind()) {
5577 // Declaration kinds that don't really separate the notions of
5578 // declaration and definition.
5579 case Decl::Namespace:
5580 case Decl::Typedef:
5581 case Decl::TypeAlias:
5582 case Decl::TypeAliasTemplate:
5583 case Decl::TemplateTypeParm:
5584 case Decl::EnumConstant:
5585 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005586 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005587 case Decl::IndirectField:
5588 case Decl::ObjCIvar:
5589 case Decl::ObjCAtDefsField:
5590 case Decl::ImplicitParam:
5591 case Decl::ParmVar:
5592 case Decl::NonTypeTemplateParm:
5593 case Decl::TemplateTemplateParm:
5594 case Decl::ObjCCategoryImpl:
5595 case Decl::ObjCImplementation:
5596 case Decl::AccessSpec:
5597 case Decl::LinkageSpec:
5598 case Decl::ObjCPropertyImpl:
5599 case Decl::FileScopeAsm:
5600 case Decl::StaticAssert:
5601 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005602 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005603 case Decl::Label: // FIXME: Is this right??
5604 case Decl::ClassScopeFunctionSpecialization:
5605 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005606 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005607 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00005608 case Decl::BuiltinTemplate:
Guy Benyei11169dd2012-12-18 14:30:41 +00005609 return C;
5610
5611 // Declaration kinds that don't make any sense here, but are
5612 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005613 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005614 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005615 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005616 break;
5617
5618 // Declaration kinds for which the definition is not resolvable.
5619 case Decl::UnresolvedUsingTypename:
5620 case Decl::UnresolvedUsingValue:
5621 break;
5622
5623 case Decl::UsingDirective:
5624 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5625 TU);
5626
5627 case Decl::NamespaceAlias:
5628 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5629
5630 case Decl::Enum:
5631 case Decl::Record:
5632 case Decl::CXXRecord:
5633 case Decl::ClassTemplateSpecialization:
5634 case Decl::ClassTemplatePartialSpecialization:
5635 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5636 return MakeCXCursor(Def, TU);
5637 return clang_getNullCursor();
5638
5639 case Decl::Function:
5640 case Decl::CXXMethod:
5641 case Decl::CXXConstructor:
5642 case Decl::CXXDestructor:
5643 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005644 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005646 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 return clang_getNullCursor();
5648 }
5649
Larisse Voufo39a1e502013-08-06 01:03:05 +00005650 case Decl::Var:
5651 case Decl::VarTemplateSpecialization:
5652 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005654 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 return MakeCXCursor(Def, TU);
5656 return clang_getNullCursor();
5657 }
5658
5659 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005660 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005661 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5662 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5663 return clang_getNullCursor();
5664 }
5665
5666 case Decl::ClassTemplate: {
5667 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5668 ->getDefinition())
5669 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5670 TU);
5671 return clang_getNullCursor();
5672 }
5673
Larisse Voufo39a1e502013-08-06 01:03:05 +00005674 case Decl::VarTemplate: {
5675 if (VarDecl *Def =
5676 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5677 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5678 return clang_getNullCursor();
5679 }
5680
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 case Decl::Using:
5682 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5683 D->getLocation(), TU);
5684
5685 case Decl::UsingShadow:
5686 return clang_getCursorDefinition(
5687 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5688 TU));
5689
5690 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005691 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005692 if (Method->isThisDeclarationADefinition())
5693 return C;
5694
5695 // Dig out the method definition in the associated
5696 // @implementation, if we have it.
5697 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005698 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5700 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5701 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5702 Method->isInstanceMethod()))
5703 if (Def->isThisDeclarationADefinition())
5704 return MakeCXCursor(Def, TU);
5705
5706 return clang_getNullCursor();
5707 }
5708
5709 case Decl::ObjCCategory:
5710 if (ObjCCategoryImplDecl *Impl
5711 = cast<ObjCCategoryDecl>(D)->getImplementation())
5712 return MakeCXCursor(Impl, TU);
5713 return clang_getNullCursor();
5714
5715 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005716 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005717 return MakeCXCursor(Def, TU);
5718 return clang_getNullCursor();
5719
5720 case Decl::ObjCInterface: {
5721 // There are two notions of a "definition" for an Objective-C
5722 // class: the interface and its implementation. When we resolved a
5723 // reference to an Objective-C class, produce the @interface as
5724 // the definition; when we were provided with the interface,
5725 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005726 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005727 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005728 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005729 return MakeCXCursor(Def, TU);
5730 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5731 return MakeCXCursor(Impl, TU);
5732 return clang_getNullCursor();
5733 }
5734
5735 case Decl::ObjCProperty:
5736 // FIXME: We don't really know where to find the
5737 // ObjCPropertyImplDecls that implement this property.
5738 return clang_getNullCursor();
5739
5740 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005741 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005742 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005743 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005744 return MakeCXCursor(Def, TU);
5745
5746 return clang_getNullCursor();
5747
5748 case Decl::Friend:
5749 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5750 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5751 return clang_getNullCursor();
5752
5753 case Decl::FriendTemplate:
5754 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5755 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5756 return clang_getNullCursor();
5757 }
5758
5759 return clang_getNullCursor();
5760}
5761
5762unsigned clang_isCursorDefinition(CXCursor C) {
5763 if (!clang_isDeclaration(C.kind))
5764 return 0;
5765
5766 return clang_getCursorDefinition(C) == C;
5767}
5768
5769CXCursor clang_getCanonicalCursor(CXCursor C) {
5770 if (!clang_isDeclaration(C.kind))
5771 return C;
5772
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005773 if (const Decl *D = getCursorDecl(C)) {
5774 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005775 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5776 return MakeCXCursor(CatD, getCursorTU(C));
5777
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005778 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5779 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005780 return MakeCXCursor(IFD, getCursorTU(C));
5781
5782 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5783 }
5784
5785 return C;
5786}
5787
5788int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5789 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5790}
5791
5792unsigned clang_getNumOverloadedDecls(CXCursor C) {
5793 if (C.kind != CXCursor_OverloadedDeclRef)
5794 return 0;
5795
5796 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005797 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005798 return E->getNumDecls();
5799
5800 if (OverloadedTemplateStorage *S
5801 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5802 return S->size();
5803
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005804 const Decl *D = Storage.get<const Decl *>();
5805 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005806 return Using->shadow_size();
5807
5808 return 0;
5809}
5810
5811CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5812 if (cursor.kind != CXCursor_OverloadedDeclRef)
5813 return clang_getNullCursor();
5814
5815 if (index >= clang_getNumOverloadedDecls(cursor))
5816 return clang_getNullCursor();
5817
5818 CXTranslationUnit TU = getCursorTU(cursor);
5819 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005820 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005821 return MakeCXCursor(E->decls_begin()[index], TU);
5822
5823 if (OverloadedTemplateStorage *S
5824 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5825 return MakeCXCursor(S->begin()[index], TU);
5826
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005827 const Decl *D = Storage.get<const Decl *>();
5828 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005829 // FIXME: This is, unfortunately, linear time.
5830 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5831 std::advance(Pos, index);
5832 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5833 }
5834
5835 return clang_getNullCursor();
5836}
5837
5838void clang_getDefinitionSpellingAndExtent(CXCursor C,
5839 const char **startBuf,
5840 const char **endBuf,
5841 unsigned *startLine,
5842 unsigned *startColumn,
5843 unsigned *endLine,
5844 unsigned *endColumn) {
5845 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005846 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005847 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5848
5849 SourceManager &SM = FD->getASTContext().getSourceManager();
5850 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5851 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5852 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5853 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5854 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5855 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5856}
5857
5858
5859CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5860 unsigned PieceIndex) {
5861 RefNamePieces Pieces;
5862
5863 switch (C.kind) {
5864 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005865 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005866 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5867 E->getQualifierLoc().getSourceRange());
5868 break;
5869
5870 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00005871 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5872 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5873 Pieces =
5874 buildPieces(NameFlags, false, E->getNameInfo(),
5875 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5876 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005877 break;
5878
5879 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005880 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005881 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005882 const Expr *Callee = OCE->getCallee();
5883 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005884 Callee = ICE->getSubExpr();
5885
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005886 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005887 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5888 DRE->getQualifierLoc().getSourceRange());
5889 }
5890 break;
5891
5892 default:
5893 break;
5894 }
5895
5896 if (Pieces.empty()) {
5897 if (PieceIndex == 0)
5898 return clang_getCursorExtent(C);
5899 } else if (PieceIndex < Pieces.size()) {
5900 SourceRange R = Pieces[PieceIndex];
5901 if (R.isValid())
5902 return cxloc::translateSourceRange(getCursorContext(C), R);
5903 }
5904
5905 return clang_getNullRange();
5906}
5907
5908void clang_enableStackTraces(void) {
5909 llvm::sys::PrintStackTraceOnErrorSignal();
5910}
5911
5912void clang_executeOnThread(void (*fn)(void*), void *user_data,
5913 unsigned stack_size) {
5914 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5915}
5916
5917} // end: extern "C"
5918
5919//===----------------------------------------------------------------------===//
5920// Token-based Operations.
5921//===----------------------------------------------------------------------===//
5922
5923/* CXToken layout:
5924 * int_data[0]: a CXTokenKind
5925 * int_data[1]: starting token location
5926 * int_data[2]: token length
5927 * int_data[3]: reserved
5928 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5929 * otherwise unused.
5930 */
5931extern "C" {
5932
5933CXTokenKind clang_getTokenKind(CXToken CXTok) {
5934 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5935}
5936
5937CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5938 switch (clang_getTokenKind(CXTok)) {
5939 case CXToken_Identifier:
5940 case CXToken_Keyword:
5941 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005942 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005943 ->getNameStart());
5944
5945 case CXToken_Literal: {
5946 // We have stashed the starting pointer in the ptr_data field. Use it.
5947 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005948 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005949 }
5950
5951 case CXToken_Punctuation:
5952 case CXToken_Comment:
5953 break;
5954 }
5955
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005956 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005957 LOG_BAD_TU(TU);
5958 return cxstring::createEmpty();
5959 }
5960
Guy Benyei11169dd2012-12-18 14:30:41 +00005961 // We have to find the starting buffer pointer the hard way, by
5962 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005963 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005964 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005965 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005966
5967 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5968 std::pair<FileID, unsigned> LocInfo
5969 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5970 bool Invalid = false;
5971 StringRef Buffer
5972 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5973 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005974 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005975
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005976 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005977}
5978
5979CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005980 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005981 LOG_BAD_TU(TU);
5982 return clang_getNullLocation();
5983 }
5984
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005985 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005986 if (!CXXUnit)
5987 return clang_getNullLocation();
5988
5989 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5990 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5991}
5992
5993CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005994 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005995 LOG_BAD_TU(TU);
5996 return clang_getNullRange();
5997 }
5998
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005999 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006000 if (!CXXUnit)
6001 return clang_getNullRange();
6002
6003 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
6004 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6005}
6006
6007static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6008 SmallVectorImpl<CXToken> &CXTokens) {
6009 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6010 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006011 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006013 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006014
6015 // Cannot tokenize across files.
6016 if (BeginLocInfo.first != EndLocInfo.first)
6017 return;
6018
6019 // Create a lexer
6020 bool Invalid = false;
6021 StringRef Buffer
6022 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6023 if (Invalid)
6024 return;
6025
6026 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6027 CXXUnit->getASTContext().getLangOpts(),
6028 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6029 Lex.SetCommentRetentionState(true);
6030
6031 // Lex tokens until we hit the end of the range.
6032 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6033 Token Tok;
6034 bool previousWasAt = false;
6035 do {
6036 // Lex the next token
6037 Lex.LexFromRawLexer(Tok);
6038 if (Tok.is(tok::eof))
6039 break;
6040
6041 // Initialize the CXToken.
6042 CXToken CXTok;
6043
6044 // - Common fields
6045 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6046 CXTok.int_data[2] = Tok.getLength();
6047 CXTok.int_data[3] = 0;
6048
6049 // - Kind-specific fields
6050 if (Tok.isLiteral()) {
6051 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006052 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006053 } else if (Tok.is(tok::raw_identifier)) {
6054 // Lookup the identifier to determine whether we have a keyword.
6055 IdentifierInfo *II
6056 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6057
6058 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6059 CXTok.int_data[0] = CXToken_Keyword;
6060 }
6061 else {
6062 CXTok.int_data[0] = Tok.is(tok::identifier)
6063 ? CXToken_Identifier
6064 : CXToken_Keyword;
6065 }
6066 CXTok.ptr_data = II;
6067 } else if (Tok.is(tok::comment)) {
6068 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006069 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006070 } else {
6071 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006072 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006073 }
6074 CXTokens.push_back(CXTok);
6075 previousWasAt = Tok.is(tok::at);
6076 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6077}
6078
6079void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6080 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006081 LOG_FUNC_SECTION {
6082 *Log << TU << ' ' << Range;
6083 }
6084
Guy Benyei11169dd2012-12-18 14:30:41 +00006085 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006086 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006087 if (NumTokens)
6088 *NumTokens = 0;
6089
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006090 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006091 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006092 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006093 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006094
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006095 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006096 if (!CXXUnit || !Tokens || !NumTokens)
6097 return;
6098
6099 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6100
6101 SourceRange R = cxloc::translateCXSourceRange(Range);
6102 if (R.isInvalid())
6103 return;
6104
6105 SmallVector<CXToken, 32> CXTokens;
6106 getTokens(CXXUnit, R, CXTokens);
6107
6108 if (CXTokens.empty())
6109 return;
6110
6111 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6112 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6113 *NumTokens = CXTokens.size();
6114}
6115
6116void clang_disposeTokens(CXTranslationUnit TU,
6117 CXToken *Tokens, unsigned NumTokens) {
6118 free(Tokens);
6119}
6120
6121} // end: extern "C"
6122
6123//===----------------------------------------------------------------------===//
6124// Token annotation APIs.
6125//===----------------------------------------------------------------------===//
6126
Guy Benyei11169dd2012-12-18 14:30:41 +00006127static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6128 CXCursor parent,
6129 CXClientData client_data);
6130static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6131 CXClientData client_data);
6132
6133namespace {
6134class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006135 CXToken *Tokens;
6136 CXCursor *Cursors;
6137 unsigned NumTokens;
6138 unsigned TokIdx;
6139 unsigned PreprocessingTokIdx;
6140 CursorVisitor AnnotateVis;
6141 SourceManager &SrcMgr;
6142 bool HasContextSensitiveKeywords;
6143
6144 struct PostChildrenInfo {
6145 CXCursor Cursor;
6146 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006147 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006148 unsigned BeforeChildrenTokenIdx;
6149 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006150 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006151
6152 CXToken &getTok(unsigned Idx) {
6153 assert(Idx < NumTokens);
6154 return Tokens[Idx];
6155 }
6156 const CXToken &getTok(unsigned Idx) const {
6157 assert(Idx < NumTokens);
6158 return Tokens[Idx];
6159 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006160 bool MoreTokens() const { return TokIdx < NumTokens; }
6161 unsigned NextToken() const { return TokIdx; }
6162 void AdvanceToken() { ++TokIdx; }
6163 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006164 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 }
6166 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006167 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006168 }
6169 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006170 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006171 }
6172
6173 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006174 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006175 SourceRange);
6176
6177public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006178 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006179 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006180 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00006181 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006182 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00006183 AnnotateTokensVisitor, this,
6184 /*VisitPreprocessorLast=*/true,
6185 /*VisitIncludedEntities=*/false,
6186 RegionOfInterest,
6187 /*VisitDeclsOnly=*/false,
6188 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006189 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 HasContextSensitiveKeywords(false) { }
6191
6192 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6193 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6194 bool postVisitChildren(CXCursor cursor);
6195 void AnnotateTokens();
6196
6197 /// \brief Determine whether the annotator saw any cursors that have
6198 /// context-sensitive keywords.
6199 bool hasContextSensitiveKeywords() const {
6200 return HasContextSensitiveKeywords;
6201 }
6202
6203 ~AnnotateTokensWorker() {
6204 assert(PostChildrenInfos.empty());
6205 }
6206};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00006207}
Guy Benyei11169dd2012-12-18 14:30:41 +00006208
6209void AnnotateTokensWorker::AnnotateTokens() {
6210 // Walk the AST within the region of interest, annotating tokens
6211 // along the way.
6212 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006213}
Guy Benyei11169dd2012-12-18 14:30:41 +00006214
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006215static inline void updateCursorAnnotation(CXCursor &Cursor,
6216 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006217 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006218 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006219 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00006220}
6221
6222/// \brief It annotates and advances tokens with a cursor until the comparison
6223//// between the cursor location and the source range is the same as
6224/// \arg compResult.
6225///
6226/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6227/// Pass RangeOverlap to annotate tokens inside a range.
6228void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6229 RangeComparisonResult compResult,
6230 SourceRange range) {
6231 while (MoreTokens()) {
6232 const unsigned I = NextToken();
6233 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006234 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6235 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00006236
6237 SourceLocation TokLoc = GetTokenLoc(I);
6238 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006239 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006240 AdvanceToken();
6241 continue;
6242 }
6243 break;
6244 }
6245}
6246
6247/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006248/// \returns true if it advanced beyond all macro tokens, false otherwise.
6249bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00006250 CXCursor updateC,
6251 RangeComparisonResult compResult,
6252 SourceRange range) {
6253 assert(MoreTokens());
6254 assert(isFunctionMacroToken(NextToken()) &&
6255 "Should be called only for macro arg tokens");
6256
6257 // This works differently than annotateAndAdvanceTokens; because expanded
6258 // macro arguments can have arbitrary translation-unit source order, we do not
6259 // advance the token index one by one until a token fails the range test.
6260 // We only advance once past all of the macro arg tokens if all of them
6261 // pass the range test. If one of them fails we keep the token index pointing
6262 // at the start of the macro arg tokens so that the failing token will be
6263 // annotated by a subsequent annotation try.
6264
6265 bool atLeastOneCompFail = false;
6266
6267 unsigned I = NextToken();
6268 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6269 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6270 if (TokLoc.isFileID())
6271 continue; // not macro arg token, it's parens or comma.
6272 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6273 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6274 Cursors[I] = updateC;
6275 } else
6276 atLeastOneCompFail = true;
6277 }
6278
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006279 if (atLeastOneCompFail)
6280 return false;
6281
6282 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6283 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00006284}
6285
6286enum CXChildVisitResult
6287AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006288 SourceRange cursorRange = getRawCursorExtent(cursor);
6289 if (cursorRange.isInvalid())
6290 return CXChildVisit_Recurse;
6291
6292 if (!HasContextSensitiveKeywords) {
6293 // Objective-C properties can have context-sensitive keywords.
6294 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006295 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006296 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6297 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6298 }
6299 // Objective-C methods can have context-sensitive keywords.
6300 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6301 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006302 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006303 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6304 if (Method->getObjCDeclQualifier())
6305 HasContextSensitiveKeywords = true;
6306 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00006307 for (const auto *P : Method->params()) {
6308 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006309 HasContextSensitiveKeywords = true;
6310 break;
6311 }
6312 }
6313 }
6314 }
6315 }
6316 // C++ methods can have context-sensitive keywords.
6317 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006318 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00006319 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6320 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6321 HasContextSensitiveKeywords = true;
6322 }
6323 }
6324 // C++ classes can have context-sensitive keywords.
6325 else if (cursor.kind == CXCursor_StructDecl ||
6326 cursor.kind == CXCursor_ClassDecl ||
6327 cursor.kind == CXCursor_ClassTemplate ||
6328 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006329 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006330 if (D->hasAttr<FinalAttr>())
6331 HasContextSensitiveKeywords = true;
6332 }
6333 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00006334
6335 // Don't override a property annotation with its getter/setter method.
6336 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6337 parent.kind == CXCursor_ObjCPropertyDecl)
6338 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00006339
6340 if (clang_isPreprocessing(cursor.kind)) {
6341 // Items in the preprocessing record are kept separate from items in
6342 // declarations, so we keep a separate token index.
6343 unsigned SavedTokIdx = TokIdx;
6344 TokIdx = PreprocessingTokIdx;
6345
6346 // Skip tokens up until we catch up to the beginning of the preprocessing
6347 // entry.
6348 while (MoreTokens()) {
6349 const unsigned I = NextToken();
6350 SourceLocation TokLoc = GetTokenLoc(I);
6351 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6352 case RangeBefore:
6353 AdvanceToken();
6354 continue;
6355 case RangeAfter:
6356 case RangeOverlap:
6357 break;
6358 }
6359 break;
6360 }
6361
6362 // Look at all of the tokens within this range.
6363 while (MoreTokens()) {
6364 const unsigned I = NextToken();
6365 SourceLocation TokLoc = GetTokenLoc(I);
6366 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6367 case RangeBefore:
6368 llvm_unreachable("Infeasible");
6369 case RangeAfter:
6370 break;
6371 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006372 // For macro expansions, just note where the beginning of the macro
6373 // expansion occurs.
6374 if (cursor.kind == CXCursor_MacroExpansion) {
6375 if (TokLoc == cursorRange.getBegin())
6376 Cursors[I] = cursor;
6377 AdvanceToken();
6378 break;
6379 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006380 // We may have already annotated macro names inside macro definitions.
6381 if (Cursors[I].kind != CXCursor_MacroExpansion)
6382 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00006383 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006384 continue;
6385 }
6386 break;
6387 }
6388
6389 // Save the preprocessing token index; restore the non-preprocessing
6390 // token index.
6391 PreprocessingTokIdx = TokIdx;
6392 TokIdx = SavedTokIdx;
6393 return CXChildVisit_Recurse;
6394 }
6395
6396 if (cursorRange.isInvalid())
6397 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006398
6399 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00006400 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006401 const enum CXCursorKind K = clang_getCursorKind(parent);
6402 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006403 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6404 // Attributes are annotated out-of-order, skip tokens until we reach it.
6405 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00006406 ? clang_getNullCursor() : parent;
6407
6408 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6409
6410 // Avoid having the cursor of an expression "overwrite" the annotation of the
6411 // variable declaration that it belongs to.
6412 // This can happen for C++ constructor expressions whose range generally
6413 // include the variable declaration, e.g.:
6414 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006415 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006416 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00006417 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006418 const unsigned I = NextToken();
6419 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6420 E->getLocStart() == D->getLocation() &&
6421 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006422 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00006423 AdvanceToken();
6424 }
6425 }
6426 }
6427
6428 // Before recursing into the children keep some state that we are going
6429 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6430 // extra work after the child nodes are visited.
6431 // Note that we don't call VisitChildren here to avoid traversing statements
6432 // code-recursively which can blow the stack.
6433
6434 PostChildrenInfo Info;
6435 Info.Cursor = cursor;
6436 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006437 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006438 Info.BeforeChildrenTokenIdx = NextToken();
6439 PostChildrenInfos.push_back(Info);
6440
6441 return CXChildVisit_Recurse;
6442}
6443
6444bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6445 if (PostChildrenInfos.empty())
6446 return false;
6447 const PostChildrenInfo &Info = PostChildrenInfos.back();
6448 if (!clang_equalCursors(Info.Cursor, cursor))
6449 return false;
6450
6451 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6452 const unsigned AfterChildren = NextToken();
6453 SourceRange cursorRange = Info.CursorRange;
6454
6455 // Scan the tokens that are at the end of the cursor, but are not captured
6456 // but the child cursors.
6457 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6458
6459 // Scan the tokens that are at the beginning of the cursor, but are not
6460 // capture by the child cursors.
6461 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6462 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6463 break;
6464
6465 Cursors[I] = cursor;
6466 }
6467
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006468 // Attributes are annotated out-of-order, rewind TokIdx to when we first
6469 // encountered the attribute cursor.
6470 if (clang_isAttribute(cursor.kind))
6471 TokIdx = Info.BeforeReachingCursorIdx;
6472
Guy Benyei11169dd2012-12-18 14:30:41 +00006473 PostChildrenInfos.pop_back();
6474 return false;
6475}
6476
6477static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6478 CXCursor parent,
6479 CXClientData client_data) {
6480 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6481}
6482
6483static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6484 CXClientData client_data) {
6485 return static_cast<AnnotateTokensWorker*>(client_data)->
6486 postVisitChildren(cursor);
6487}
6488
6489namespace {
6490
6491/// \brief Uses the macro expansions in the preprocessing record to find
6492/// and mark tokens that are macro arguments. This info is used by the
6493/// AnnotateTokensWorker.
6494class MarkMacroArgTokensVisitor {
6495 SourceManager &SM;
6496 CXToken *Tokens;
6497 unsigned NumTokens;
6498 unsigned CurIdx;
6499
6500public:
6501 MarkMacroArgTokensVisitor(SourceManager &SM,
6502 CXToken *tokens, unsigned numTokens)
6503 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6504
6505 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6506 if (cursor.kind != CXCursor_MacroExpansion)
6507 return CXChildVisit_Continue;
6508
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006509 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006510 if (macroRange.getBegin() == macroRange.getEnd())
6511 return CXChildVisit_Continue; // it's not a function macro.
6512
6513 for (; CurIdx < NumTokens; ++CurIdx) {
6514 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6515 macroRange.getBegin()))
6516 break;
6517 }
6518
6519 if (CurIdx == NumTokens)
6520 return CXChildVisit_Break;
6521
6522 for (; CurIdx < NumTokens; ++CurIdx) {
6523 SourceLocation tokLoc = getTokenLoc(CurIdx);
6524 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6525 break;
6526
6527 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6528 }
6529
6530 if (CurIdx == NumTokens)
6531 return CXChildVisit_Break;
6532
6533 return CXChildVisit_Continue;
6534 }
6535
6536private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006537 CXToken &getTok(unsigned Idx) {
6538 assert(Idx < NumTokens);
6539 return Tokens[Idx];
6540 }
6541 const CXToken &getTok(unsigned Idx) const {
6542 assert(Idx < NumTokens);
6543 return Tokens[Idx];
6544 }
6545
Guy Benyei11169dd2012-12-18 14:30:41 +00006546 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006547 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006548 }
6549
6550 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6551 // The third field is reserved and currently not used. Use it here
6552 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006553 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006554 }
6555};
6556
6557} // end anonymous namespace
6558
6559static CXChildVisitResult
6560MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6561 CXClientData client_data) {
6562 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6563 parent);
6564}
6565
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006566/// \brief Used by \c annotatePreprocessorTokens.
6567/// \returns true if lexing was finished, false otherwise.
6568static bool lexNext(Lexer &Lex, Token &Tok,
6569 unsigned &NextIdx, unsigned NumTokens) {
6570 if (NextIdx >= NumTokens)
6571 return true;
6572
6573 ++NextIdx;
6574 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00006575 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006576}
6577
Guy Benyei11169dd2012-12-18 14:30:41 +00006578static void annotatePreprocessorTokens(CXTranslationUnit TU,
6579 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006580 CXCursor *Cursors,
6581 CXToken *Tokens,
6582 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006583 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006584
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006585 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006586 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6587 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006588 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006589 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006590 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006591
6592 if (BeginLocInfo.first != EndLocInfo.first)
6593 return;
6594
6595 StringRef Buffer;
6596 bool Invalid = false;
6597 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6598 if (Buffer.empty() || Invalid)
6599 return;
6600
6601 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6602 CXXUnit->getASTContext().getLangOpts(),
6603 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6604 Buffer.end());
6605 Lex.SetCommentRetentionState(true);
6606
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006607 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006608 // Lex tokens in raw mode until we hit the end of the range, to avoid
6609 // entering #includes or expanding macros.
6610 while (true) {
6611 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006612 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6613 break;
6614 unsigned TokIdx = NextIdx-1;
6615 assert(Tok.getLocation() ==
6616 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006617
6618 reprocess:
6619 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006620 // We have found a preprocessing directive. Annotate the tokens
6621 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006622 //
6623 // FIXME: Some simple tests here could identify macro definitions and
6624 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006625
6626 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006627 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6628 break;
6629
Craig Topper69186e72014-06-08 08:38:04 +00006630 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006631 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006632 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6633 break;
6634
6635 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006636 IdentifierInfo &II =
6637 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006638 SourceLocation MappedTokLoc =
6639 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6640 MI = getMacroInfo(II, MappedTokLoc, TU);
6641 }
6642 }
6643
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006644 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006645 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006646 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6647 finished = true;
6648 break;
6649 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006650 // If we are in a macro definition, check if the token was ever a
6651 // macro name and annotate it if that's the case.
6652 if (MI) {
6653 SourceLocation SaveLoc = Tok.getLocation();
6654 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006655 MacroDefinitionRecord *MacroDef =
6656 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006657 Tok.setLocation(SaveLoc);
6658 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006659 Cursors[NextIdx - 1] =
6660 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006661 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006662 } while (!Tok.isAtStartOfLine());
6663
6664 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6665 assert(TokIdx <= LastIdx);
6666 SourceLocation EndLoc =
6667 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6668 CXCursor Cursor =
6669 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6670
6671 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006672 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006673
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006674 if (finished)
6675 break;
6676 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006677 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006678 }
6679}
6680
6681// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006682static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6683 CXToken *Tokens, unsigned NumTokens,
6684 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006685 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006686 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6687 setThreadBackgroundPriority();
6688
6689 // Determine the region of interest, which contains all of the tokens.
6690 SourceRange RegionOfInterest;
6691 RegionOfInterest.setBegin(
6692 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6693 RegionOfInterest.setEnd(
6694 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6695 Tokens[NumTokens-1])));
6696
Guy Benyei11169dd2012-12-18 14:30:41 +00006697 // Relex the tokens within the source range to look for preprocessing
6698 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006699 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006700
6701 // If begin location points inside a macro argument, set it to the expansion
6702 // location so we can have the full context when annotating semantically.
6703 {
6704 SourceManager &SM = CXXUnit->getSourceManager();
6705 SourceLocation Loc =
6706 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6707 if (Loc.isMacroID())
6708 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6709 }
6710
Guy Benyei11169dd2012-12-18 14:30:41 +00006711 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6712 // Search and mark tokens that are macro argument expansions.
6713 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6714 Tokens, NumTokens);
6715 CursorVisitor MacroArgMarker(TU,
6716 MarkMacroArgTokensVisitorDelegate, &Visitor,
6717 /*VisitPreprocessorLast=*/true,
6718 /*VisitIncludedEntities=*/false,
6719 RegionOfInterest);
6720 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6721 }
6722
6723 // Annotate all of the source locations in the region of interest that map to
6724 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006725 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006726
6727 // FIXME: We use a ridiculous stack size here because the data-recursion
6728 // algorithm uses a large stack frame than the non-data recursive version,
6729 // and AnnotationTokensWorker currently transforms the data-recursion
6730 // algorithm back into a traditional recursion by explicitly calling
6731 // VisitChildren(). We will need to remove this explicit recursive call.
6732 W.AnnotateTokens();
6733
6734 // If we ran into any entities that involve context-sensitive keywords,
6735 // take another pass through the tokens to mark them as such.
6736 if (W.hasContextSensitiveKeywords()) {
6737 for (unsigned I = 0; I != NumTokens; ++I) {
6738 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6739 continue;
6740
6741 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6742 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006743 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006744 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6745 if (Property->getPropertyAttributesAsWritten() != 0 &&
6746 llvm::StringSwitch<bool>(II->getName())
6747 .Case("readonly", true)
6748 .Case("assign", true)
6749 .Case("unsafe_unretained", true)
6750 .Case("readwrite", true)
6751 .Case("retain", true)
6752 .Case("copy", true)
6753 .Case("nonatomic", true)
6754 .Case("atomic", true)
6755 .Case("getter", true)
6756 .Case("setter", true)
6757 .Case("strong", true)
6758 .Case("weak", true)
6759 .Default(false))
6760 Tokens[I].int_data[0] = CXToken_Keyword;
6761 }
6762 continue;
6763 }
6764
6765 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6766 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6767 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6768 if (llvm::StringSwitch<bool>(II->getName())
6769 .Case("in", true)
6770 .Case("out", true)
6771 .Case("inout", true)
6772 .Case("oneway", true)
6773 .Case("bycopy", true)
6774 .Case("byref", true)
6775 .Default(false))
6776 Tokens[I].int_data[0] = CXToken_Keyword;
6777 continue;
6778 }
6779
6780 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6781 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6782 Tokens[I].int_data[0] = CXToken_Keyword;
6783 continue;
6784 }
6785 }
6786 }
6787}
6788
6789extern "C" {
6790
6791void clang_annotateTokens(CXTranslationUnit TU,
6792 CXToken *Tokens, unsigned NumTokens,
6793 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006794 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006795 LOG_BAD_TU(TU);
6796 return;
6797 }
6798 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006799 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006800 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006801 }
6802
6803 LOG_FUNC_SECTION {
6804 *Log << TU << ' ';
6805 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6806 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6807 *Log << clang_getRange(bloc, eloc);
6808 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006809
6810 // Any token we don't specifically annotate will have a NULL cursor.
6811 CXCursor C = clang_getNullCursor();
6812 for (unsigned I = 0; I != NumTokens; ++I)
6813 Cursors[I] = C;
6814
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006815 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006816 if (!CXXUnit)
6817 return;
6818
6819 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006820
6821 auto AnnotateTokensImpl = [=]() {
6822 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6823 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006824 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006825 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006826 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6827 }
6828}
6829
6830} // end: extern "C"
6831
6832//===----------------------------------------------------------------------===//
6833// Operations for querying linkage of a cursor.
6834//===----------------------------------------------------------------------===//
6835
6836extern "C" {
6837CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6838 if (!clang_isDeclaration(cursor.kind))
6839 return CXLinkage_Invalid;
6840
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006841 const Decl *D = cxcursor::getCursorDecl(cursor);
6842 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006843 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006844 case NoLinkage:
6845 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006846 case InternalLinkage: return CXLinkage_Internal;
6847 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6848 case ExternalLinkage: return CXLinkage_External;
6849 };
6850
6851 return CXLinkage_Invalid;
6852}
6853} // end: extern "C"
6854
6855//===----------------------------------------------------------------------===//
Ehsan Akhgari93697fa2015-11-23 19:56:46 +00006856// Operations for querying visibility of a cursor.
6857//===----------------------------------------------------------------------===//
6858
6859extern "C" {
6860CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6861 if (!clang_isDeclaration(cursor.kind))
6862 return CXVisibility_Invalid;
6863
6864 const Decl *D = cxcursor::getCursorDecl(cursor);
6865 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6866 switch (ND->getVisibility()) {
6867 case HiddenVisibility: return CXVisibility_Hidden;
6868 case ProtectedVisibility: return CXVisibility_Protected;
6869 case DefaultVisibility: return CXVisibility_Default;
6870 };
6871
6872 return CXVisibility_Invalid;
6873}
6874} // end: extern "C"
6875
6876//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00006877// Operations for querying language of a cursor.
6878//===----------------------------------------------------------------------===//
6879
6880static CXLanguageKind getDeclLanguage(const Decl *D) {
6881 if (!D)
6882 return CXLanguage_C;
6883
6884 switch (D->getKind()) {
6885 default:
6886 break;
6887 case Decl::ImplicitParam:
6888 case Decl::ObjCAtDefsField:
6889 case Decl::ObjCCategory:
6890 case Decl::ObjCCategoryImpl:
6891 case Decl::ObjCCompatibleAlias:
6892 case Decl::ObjCImplementation:
6893 case Decl::ObjCInterface:
6894 case Decl::ObjCIvar:
6895 case Decl::ObjCMethod:
6896 case Decl::ObjCProperty:
6897 case Decl::ObjCPropertyImpl:
6898 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006899 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006900 return CXLanguage_ObjC;
6901 case Decl::CXXConstructor:
6902 case Decl::CXXConversion:
6903 case Decl::CXXDestructor:
6904 case Decl::CXXMethod:
6905 case Decl::CXXRecord:
6906 case Decl::ClassTemplate:
6907 case Decl::ClassTemplatePartialSpecialization:
6908 case Decl::ClassTemplateSpecialization:
6909 case Decl::Friend:
6910 case Decl::FriendTemplate:
6911 case Decl::FunctionTemplate:
6912 case Decl::LinkageSpec:
6913 case Decl::Namespace:
6914 case Decl::NamespaceAlias:
6915 case Decl::NonTypeTemplateParm:
6916 case Decl::StaticAssert:
6917 case Decl::TemplateTemplateParm:
6918 case Decl::TemplateTypeParm:
6919 case Decl::UnresolvedUsingTypename:
6920 case Decl::UnresolvedUsingValue:
6921 case Decl::Using:
6922 case Decl::UsingDirective:
6923 case Decl::UsingShadow:
6924 return CXLanguage_CPlusPlus;
6925 }
6926
6927 return CXLanguage_C;
6928}
6929
6930extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006931
6932static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6933 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006934 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006935
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006936 switch (D->getAvailability()) {
6937 case AR_Available:
6938 case AR_NotYetIntroduced:
6939 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006940 return getCursorAvailabilityForDecl(
6941 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006942 return CXAvailability_Available;
6943
6944 case AR_Deprecated:
6945 return CXAvailability_Deprecated;
6946
6947 case AR_Unavailable:
6948 return CXAvailability_NotAvailable;
6949 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006950
6951 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006952}
6953
Guy Benyei11169dd2012-12-18 14:30:41 +00006954enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6955 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006956 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6957 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006958
6959 return CXAvailability_Available;
6960}
6961
6962static CXVersion convertVersion(VersionTuple In) {
6963 CXVersion Out = { -1, -1, -1 };
6964 if (In.empty())
6965 return Out;
6966
6967 Out.Major = In.getMajor();
6968
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006969 Optional<unsigned> Minor = In.getMinor();
6970 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006971 Out.Minor = *Minor;
6972 else
6973 return Out;
6974
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006975 Optional<unsigned> Subminor = In.getSubminor();
6976 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006977 Out.Subminor = *Subminor;
6978
6979 return Out;
6980}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006981
6982static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6983 int *always_deprecated,
6984 CXString *deprecated_message,
6985 int *always_unavailable,
6986 CXString *unavailable_message,
6987 CXPlatformAvailability *availability,
6988 int availability_size) {
6989 bool HadAvailAttr = false;
6990 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006991 for (auto A : D->attrs()) {
6992 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006993 HadAvailAttr = true;
6994 if (always_deprecated)
6995 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006996 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006997 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006998 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006999 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007000 continue;
7001 }
7002
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007003 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007004 HadAvailAttr = true;
7005 if (always_unavailable)
7006 *always_unavailable = 1;
7007 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007008 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007009 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7010 }
7011 continue;
7012 }
7013
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007014 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007015 HadAvailAttr = true;
7016 if (N < availability_size) {
7017 availability[N].Platform
7018 = cxstring::createDup(Avail->getPlatform()->getName());
7019 availability[N].Introduced = convertVersion(Avail->getIntroduced());
7020 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7021 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7022 availability[N].Unavailable = Avail->getUnavailable();
7023 availability[N].Message = cxstring::createDup(Avail->getMessage());
7024 }
7025 ++N;
7026 }
7027 }
7028
7029 if (!HadAvailAttr)
7030 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7031 return getCursorPlatformAvailabilityForDecl(
7032 cast<Decl>(EnumConst->getDeclContext()),
7033 always_deprecated,
7034 deprecated_message,
7035 always_unavailable,
7036 unavailable_message,
7037 availability,
7038 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007039
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007040 return N;
7041}
7042
Guy Benyei11169dd2012-12-18 14:30:41 +00007043int clang_getCursorPlatformAvailability(CXCursor cursor,
7044 int *always_deprecated,
7045 CXString *deprecated_message,
7046 int *always_unavailable,
7047 CXString *unavailable_message,
7048 CXPlatformAvailability *availability,
7049 int availability_size) {
7050 if (always_deprecated)
7051 *always_deprecated = 0;
7052 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007053 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007054 if (always_unavailable)
7055 *always_unavailable = 0;
7056 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007057 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007058
Guy Benyei11169dd2012-12-18 14:30:41 +00007059 if (!clang_isDeclaration(cursor.kind))
7060 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007061
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007062 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007063 if (!D)
7064 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007065
7066 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7067 deprecated_message,
7068 always_unavailable,
7069 unavailable_message,
7070 availability,
7071 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00007072}
7073
7074void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7075 clang_disposeString(availability->Platform);
7076 clang_disposeString(availability->Message);
7077}
7078
7079CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7080 if (clang_isDeclaration(cursor.kind))
7081 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7082
7083 return CXLanguage_Invalid;
7084}
7085
7086 /// \brief If the given cursor is the "templated" declaration
7087 /// descibing a class or function template, return the class or
7088 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007089static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007090 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00007091 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007092
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007093 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007094 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7095 return FunTmpl;
7096
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007097 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00007098 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7099 return ClassTmpl;
7100
7101 return D;
7102}
7103
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007104
7105enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7106 StorageClass sc = SC_None;
7107 const Decl *D = getCursorDecl(C);
7108 if (D) {
7109 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7110 sc = FD->getStorageClass();
7111 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7112 sc = VD->getStorageClass();
7113 } else {
7114 return CX_SC_Invalid;
7115 }
7116 } else {
7117 return CX_SC_Invalid;
7118 }
7119 switch (sc) {
7120 case SC_None:
7121 return CX_SC_None;
7122 case SC_Extern:
7123 return CX_SC_Extern;
7124 case SC_Static:
7125 return CX_SC_Static;
7126 case SC_PrivateExtern:
7127 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007128 case SC_Auto:
7129 return CX_SC_Auto;
7130 case SC_Register:
7131 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007132 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00007133 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00007134}
7135
Guy Benyei11169dd2012-12-18 14:30:41 +00007136CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7137 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007138 if (const Decl *D = getCursorDecl(cursor)) {
7139 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007140 if (!DC)
7141 return clang_getNullCursor();
7142
7143 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7144 getCursorTU(cursor));
7145 }
7146 }
7147
7148 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007149 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007150 return MakeCXCursor(D, getCursorTU(cursor));
7151 }
7152
7153 return clang_getNullCursor();
7154}
7155
7156CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7157 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007158 if (const Decl *D = getCursorDecl(cursor)) {
7159 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00007160 if (!DC)
7161 return clang_getNullCursor();
7162
7163 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7164 getCursorTU(cursor));
7165 }
7166 }
7167
7168 // FIXME: Note that we can't easily compute the lexical context of a
7169 // statement or expression, so we return nothing.
7170 return clang_getNullCursor();
7171}
7172
7173CXFile clang_getIncludedFile(CXCursor cursor) {
7174 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00007175 return nullptr;
7176
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007177 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00007178 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00007179}
7180
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00007181unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7182 if (C.kind != CXCursor_ObjCPropertyDecl)
7183 return CXObjCPropertyAttr_noattr;
7184
7185 unsigned Result = CXObjCPropertyAttr_noattr;
7186 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7187 ObjCPropertyDecl::PropertyAttributeKind Attr =
7188 PD->getPropertyAttributesAsWritten();
7189
7190#define SET_CXOBJCPROP_ATTR(A) \
7191 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7192 Result |= CXObjCPropertyAttr_##A
7193 SET_CXOBJCPROP_ATTR(readonly);
7194 SET_CXOBJCPROP_ATTR(getter);
7195 SET_CXOBJCPROP_ATTR(assign);
7196 SET_CXOBJCPROP_ATTR(readwrite);
7197 SET_CXOBJCPROP_ATTR(retain);
7198 SET_CXOBJCPROP_ATTR(copy);
7199 SET_CXOBJCPROP_ATTR(nonatomic);
7200 SET_CXOBJCPROP_ATTR(setter);
7201 SET_CXOBJCPROP_ATTR(atomic);
7202 SET_CXOBJCPROP_ATTR(weak);
7203 SET_CXOBJCPROP_ATTR(strong);
7204 SET_CXOBJCPROP_ATTR(unsafe_unretained);
7205#undef SET_CXOBJCPROP_ATTR
7206
7207 return Result;
7208}
7209
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00007210unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7211 if (!clang_isDeclaration(C.kind))
7212 return CXObjCDeclQualifier_None;
7213
7214 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7215 const Decl *D = getCursorDecl(C);
7216 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7217 QT = MD->getObjCDeclQualifier();
7218 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7219 QT = PD->getObjCDeclQualifier();
7220 if (QT == Decl::OBJC_TQ_None)
7221 return CXObjCDeclQualifier_None;
7222
7223 unsigned Result = CXObjCDeclQualifier_None;
7224 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7225 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7226 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7227 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7228 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7229 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7230
7231 return Result;
7232}
7233
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00007234unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7235 if (!clang_isDeclaration(C.kind))
7236 return 0;
7237
7238 const Decl *D = getCursorDecl(C);
7239 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7240 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7241 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7242 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7243
7244 return 0;
7245}
7246
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00007247unsigned clang_Cursor_isVariadic(CXCursor C) {
7248 if (!clang_isDeclaration(C.kind))
7249 return 0;
7250
7251 const Decl *D = getCursorDecl(C);
7252 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7253 return FD->isVariadic();
7254 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7255 return MD->isVariadic();
7256
7257 return 0;
7258}
7259
Guy Benyei11169dd2012-12-18 14:30:41 +00007260CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7261 if (!clang_isDeclaration(C.kind))
7262 return clang_getNullRange();
7263
7264 const Decl *D = getCursorDecl(C);
7265 ASTContext &Context = getCursorContext(C);
7266 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7267 if (!RC)
7268 return clang_getNullRange();
7269
7270 return cxloc::translateSourceRange(Context, RC->getSourceRange());
7271}
7272
7273CXString clang_Cursor_getRawCommentText(CXCursor C) {
7274 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007275 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007276
7277 const Decl *D = getCursorDecl(C);
7278 ASTContext &Context = getCursorContext(C);
7279 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7280 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7281 StringRef();
7282
7283 // Don't duplicate the string because RawText points directly into source
7284 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007285 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007286}
7287
7288CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7289 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007290 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007291
7292 const Decl *D = getCursorDecl(C);
7293 const ASTContext &Context = getCursorContext(C);
7294 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7295
7296 if (RC) {
7297 StringRef BriefText = RC->getBriefText(Context);
7298
7299 // Don't duplicate the string because RawComment ensures that this memory
7300 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007301 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00007302 }
7303
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00007304 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00007305}
7306
Guy Benyei11169dd2012-12-18 14:30:41 +00007307CXModule clang_Cursor_getModule(CXCursor C) {
7308 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007309 if (const ImportDecl *ImportD =
7310 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00007311 return ImportD->getImportedModule();
7312 }
7313
Craig Topper69186e72014-06-08 08:38:04 +00007314 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007315}
7316
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007317CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7318 if (isNotUsableTU(TU)) {
7319 LOG_BAD_TU(TU);
7320 return nullptr;
7321 }
7322 if (!File)
7323 return nullptr;
7324 FileEntry *FE = static_cast<FileEntry *>(File);
7325
7326 ASTUnit &Unit = *cxtu::getASTUnit(TU);
7327 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7328 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7329
Richard Smithfeb54b62014-10-23 02:01:19 +00007330 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00007331}
7332
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007333CXFile clang_Module_getASTFile(CXModule CXMod) {
7334 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007335 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00007336 Module *Mod = static_cast<Module*>(CXMod);
7337 return const_cast<FileEntry *>(Mod->getASTFile());
7338}
7339
Guy Benyei11169dd2012-12-18 14:30:41 +00007340CXModule clang_Module_getParent(CXModule CXMod) {
7341 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007342 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007343 Module *Mod = static_cast<Module*>(CXMod);
7344 return Mod->Parent;
7345}
7346
7347CXString clang_Module_getName(CXModule CXMod) {
7348 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007349 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007350 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007351 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00007352}
7353
7354CXString clang_Module_getFullName(CXModule CXMod) {
7355 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007356 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007357 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007358 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00007359}
7360
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00007361int clang_Module_isSystem(CXModule CXMod) {
7362 if (!CXMod)
7363 return 0;
7364 Module *Mod = static_cast<Module*>(CXMod);
7365 return Mod->IsSystem;
7366}
7367
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007368unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7369 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007370 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007371 LOG_BAD_TU(TU);
7372 return 0;
7373 }
7374 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00007375 return 0;
7376 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007377 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7378 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7379 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00007380}
7381
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007382CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7383 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007384 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007385 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007386 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007387 }
7388 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00007389 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007390 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007391 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00007392
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00007393 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7394 if (Index < TopHeaders.size())
7395 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007396
Craig Topper69186e72014-06-08 08:38:04 +00007397 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007398}
7399
7400} // end: extern "C"
7401
7402//===----------------------------------------------------------------------===//
7403// C++ AST instrospection.
7404//===----------------------------------------------------------------------===//
7405
7406extern "C" {
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00007407unsigned clang_CXXField_isMutable(CXCursor C) {
7408 if (!clang_isDeclaration(C.kind))
7409 return 0;
7410
7411 if (const auto D = cxcursor::getCursorDecl(C))
7412 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7413 return FD->isMutable() ? 1 : 0;
7414 return 0;
7415}
7416
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007417unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7418 if (!clang_isDeclaration(C.kind))
7419 return 0;
7420
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007421 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007422 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007423 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00007424 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7425}
7426
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007427unsigned clang_CXXMethod_isConst(CXCursor C) {
7428 if (!clang_isDeclaration(C.kind))
7429 return 0;
7430
7431 const Decl *D = cxcursor::getCursorDecl(C);
7432 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007433 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00007434 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7435}
7436
Guy Benyei11169dd2012-12-18 14:30:41 +00007437unsigned clang_CXXMethod_isStatic(CXCursor C) {
7438 if (!clang_isDeclaration(C.kind))
7439 return 0;
7440
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007441 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007442 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007443 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007444 return (Method && Method->isStatic()) ? 1 : 0;
7445}
7446
7447unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7448 if (!clang_isDeclaration(C.kind))
7449 return 0;
7450
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007451 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00007452 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00007453 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00007454 return (Method && Method->isVirtual()) ? 1 : 0;
7455}
7456} // end: extern "C"
7457
7458//===----------------------------------------------------------------------===//
7459// Attribute introspection.
7460//===----------------------------------------------------------------------===//
7461
7462extern "C" {
7463CXType clang_getIBOutletCollectionType(CXCursor C) {
7464 if (C.kind != CXCursor_IBOutletCollectionAttr)
7465 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7466
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00007467 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00007468 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7469
7470 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7471}
7472} // end: extern "C"
7473
7474//===----------------------------------------------------------------------===//
7475// Inspecting memory usage.
7476//===----------------------------------------------------------------------===//
7477
7478typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7479
7480static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7481 enum CXTUResourceUsageKind k,
7482 unsigned long amount) {
7483 CXTUResourceUsageEntry entry = { k, amount };
7484 entries.push_back(entry);
7485}
7486
7487extern "C" {
7488
7489const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7490 const char *str = "";
7491 switch (kind) {
7492 case CXTUResourceUsage_AST:
7493 str = "ASTContext: expressions, declarations, and types";
7494 break;
7495 case CXTUResourceUsage_Identifiers:
7496 str = "ASTContext: identifiers";
7497 break;
7498 case CXTUResourceUsage_Selectors:
7499 str = "ASTContext: selectors";
7500 break;
7501 case CXTUResourceUsage_GlobalCompletionResults:
7502 str = "Code completion: cached global results";
7503 break;
7504 case CXTUResourceUsage_SourceManagerContentCache:
7505 str = "SourceManager: content cache allocator";
7506 break;
7507 case CXTUResourceUsage_AST_SideTables:
7508 str = "ASTContext: side tables";
7509 break;
7510 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7511 str = "SourceManager: malloc'ed memory buffers";
7512 break;
7513 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7514 str = "SourceManager: mmap'ed memory buffers";
7515 break;
7516 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7517 str = "ExternalASTSource: malloc'ed memory buffers";
7518 break;
7519 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7520 str = "ExternalASTSource: mmap'ed memory buffers";
7521 break;
7522 case CXTUResourceUsage_Preprocessor:
7523 str = "Preprocessor: malloc'ed memory";
7524 break;
7525 case CXTUResourceUsage_PreprocessingRecord:
7526 str = "Preprocessor: PreprocessingRecord";
7527 break;
7528 case CXTUResourceUsage_SourceManager_DataStructures:
7529 str = "SourceManager: data structures and tables";
7530 break;
7531 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7532 str = "Preprocessor: header search tables";
7533 break;
7534 }
7535 return str;
7536}
7537
7538CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007539 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007540 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007541 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007542 return usage;
7543 }
7544
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007545 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007546 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007547 ASTContext &astContext = astUnit->getASTContext();
7548
7549 // How much memory is used by AST nodes and types?
7550 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7551 (unsigned long) astContext.getASTAllocatedMemory());
7552
7553 // How much memory is used by identifiers?
7554 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7555 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7556
7557 // How much memory is used for selectors?
7558 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7559 (unsigned long) astContext.Selectors.getTotalMemory());
7560
7561 // How much memory is used by ASTContext's side tables?
7562 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7563 (unsigned long) astContext.getSideTableAllocatedMemory());
7564
7565 // How much memory is used for caching global code completion results?
7566 unsigned long completionBytes = 0;
7567 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007568 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007569 completionBytes = completionAllocator->getTotalMemory();
7570 }
7571 createCXTUResourceUsageEntry(*entries,
7572 CXTUResourceUsage_GlobalCompletionResults,
7573 completionBytes);
7574
7575 // How much memory is being used by SourceManager's content cache?
7576 createCXTUResourceUsageEntry(*entries,
7577 CXTUResourceUsage_SourceManagerContentCache,
7578 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7579
7580 // How much memory is being used by the MemoryBuffer's in SourceManager?
7581 const SourceManager::MemoryBufferSizes &srcBufs =
7582 astUnit->getSourceManager().getMemoryBufferSizes();
7583
7584 createCXTUResourceUsageEntry(*entries,
7585 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7586 (unsigned long) srcBufs.malloc_bytes);
7587 createCXTUResourceUsageEntry(*entries,
7588 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7589 (unsigned long) srcBufs.mmap_bytes);
7590 createCXTUResourceUsageEntry(*entries,
7591 CXTUResourceUsage_SourceManager_DataStructures,
7592 (unsigned long) astContext.getSourceManager()
7593 .getDataStructureSizes());
7594
7595 // How much memory is being used by the ExternalASTSource?
7596 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7597 const ExternalASTSource::MemoryBufferSizes &sizes =
7598 esrc->getMemoryBufferSizes();
7599
7600 createCXTUResourceUsageEntry(*entries,
7601 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7602 (unsigned long) sizes.malloc_bytes);
7603 createCXTUResourceUsageEntry(*entries,
7604 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7605 (unsigned long) sizes.mmap_bytes);
7606 }
7607
7608 // How much memory is being used by the Preprocessor?
7609 Preprocessor &pp = astUnit->getPreprocessor();
7610 createCXTUResourceUsageEntry(*entries,
7611 CXTUResourceUsage_Preprocessor,
7612 pp.getTotalMemory());
7613
7614 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7615 createCXTUResourceUsageEntry(*entries,
7616 CXTUResourceUsage_PreprocessingRecord,
7617 pRec->getTotalMemory());
7618 }
7619
7620 createCXTUResourceUsageEntry(*entries,
7621 CXTUResourceUsage_Preprocessor_HeaderSearch,
7622 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007623
Guy Benyei11169dd2012-12-18 14:30:41 +00007624 CXTUResourceUsage usage = { (void*) entries.get(),
7625 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007626 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007627 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007628 return usage;
7629}
7630
7631void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7632 if (usage.data)
7633 delete (MemUsageEntries*) usage.data;
7634}
7635
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007636CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7637 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007638 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007639 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007640
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007641 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007642 LOG_BAD_TU(TU);
7643 return skipped;
7644 }
7645
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007646 if (!file)
7647 return skipped;
7648
7649 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7650 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7651 if (!ppRec)
7652 return skipped;
7653
7654 ASTContext &Ctx = astUnit->getASTContext();
7655 SourceManager &sm = Ctx.getSourceManager();
7656 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7657 FileID wantedFileID = sm.translateFile(fileEntry);
7658
7659 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7660 std::vector<SourceRange> wantedRanges;
7661 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7662 i != ei; ++i) {
7663 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7664 wantedRanges.push_back(*i);
7665 }
7666
7667 skipped->count = wantedRanges.size();
7668 skipped->ranges = new CXSourceRange[skipped->count];
7669 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7670 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7671
7672 return skipped;
7673}
7674
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007675void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7676 if (ranges) {
7677 delete[] ranges->ranges;
7678 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007679 }
7680}
7681
Guy Benyei11169dd2012-12-18 14:30:41 +00007682} // end extern "C"
7683
7684void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7685 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7686 for (unsigned I = 0; I != Usage.numEntries; ++I)
7687 fprintf(stderr, " %s: %lu\n",
7688 clang_getTUResourceUsageName(Usage.entries[I].kind),
7689 Usage.entries[I].amount);
7690
7691 clang_disposeCXTUResourceUsage(Usage);
7692}
7693
7694//===----------------------------------------------------------------------===//
7695// Misc. utility functions.
7696//===----------------------------------------------------------------------===//
7697
7698/// Default to using an 8 MB stack size on "safety" threads.
7699static unsigned SafetyStackThreadSize = 8 << 20;
7700
7701namespace clang {
7702
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007703bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007704 unsigned Size) {
7705 if (!Size)
7706 Size = GetSafetyThreadStackSize();
7707 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007708 return CRC.RunSafelyOnThread(Fn, Size);
7709 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007710}
7711
7712unsigned GetSafetyThreadStackSize() {
7713 return SafetyStackThreadSize;
7714}
7715
7716void SetSafetyThreadStackSize(unsigned Value) {
7717 SafetyStackThreadSize = Value;
7718}
7719
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007720}
Guy Benyei11169dd2012-12-18 14:30:41 +00007721
7722void clang::setThreadBackgroundPriority() {
7723 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7724 return;
7725
Alp Toker1a86ad22014-07-06 06:24:00 +00007726#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007727 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7728#endif
7729}
7730
7731void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7732 if (!Unit)
7733 return;
7734
7735 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7736 DEnd = Unit->stored_diag_end();
7737 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007738 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007739 CXString Msg = clang_formatDiagnostic(&Diag,
7740 clang_defaultDiagnosticDisplayOptions());
7741 fprintf(stderr, "%s\n", clang_getCString(Msg));
7742 clang_disposeString(Msg);
7743 }
7744#ifdef LLVM_ON_WIN32
7745 // On Windows, force a flush, since there may be multiple copies of
7746 // stderr and stdout in the file system, all with different buffers
7747 // but writing to the same device.
7748 fflush(stderr);
7749#endif
7750}
7751
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007752MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7753 SourceLocation MacroDefLoc,
7754 CXTranslationUnit TU){
7755 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007756 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007757 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007758 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007759
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007760 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007761 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007762 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007763 if (MD) {
7764 for (MacroDirective::DefInfo
7765 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7766 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7767 return Def.getMacroInfo();
7768 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007769 }
7770
Craig Topper69186e72014-06-08 08:38:04 +00007771 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007772}
7773
Richard Smith66a81862015-05-04 02:25:31 +00007774const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007775 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007776 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007777 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007778 const IdentifierInfo *II = MacroDef->getName();
7779 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007780 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007781
7782 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7783}
7784
Richard Smith66a81862015-05-04 02:25:31 +00007785MacroDefinitionRecord *
7786cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7787 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007788 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007789 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007790 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007791 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007792
7793 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007794 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007795 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7796 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007797 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007798
7799 // Check that the token is inside the definition and not its argument list.
7800 SourceManager &SM = Unit->getSourceManager();
7801 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007802 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007803 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007804 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007805
7806 Preprocessor &PP = Unit->getPreprocessor();
7807 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7808 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007809 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007810
Alp Toker2d57cea2014-05-17 04:53:25 +00007811 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007812 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007813 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007814
7815 // Check that the identifier is not one of the macro arguments.
7816 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007817 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007818
Richard Smith20e883e2015-04-29 23:20:19 +00007819 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007820 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007821 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007822
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007823 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007824}
7825
Richard Smith66a81862015-05-04 02:25:31 +00007826MacroDefinitionRecord *
7827cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7828 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007829 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007830 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007831
7832 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007833 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007834 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007835 Preprocessor &PP = Unit->getPreprocessor();
7836 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007837 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007838 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7839 Token Tok;
7840 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007841 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007842
7843 return checkForMacroInMacroDefinition(MI, Tok, TU);
7844}
7845
Guy Benyei11169dd2012-12-18 14:30:41 +00007846extern "C" {
7847
7848CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007849 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007850}
7851
7852} // end: extern "C"
7853
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007854Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7855 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007856 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007857 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007858 if (Unit->isMainFileAST())
7859 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007860 return *this;
7861 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007862 } else {
7863 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007864 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007865 return *this;
7866}
7867
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007868Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7869 *this << FE->getName();
7870 return *this;
7871}
7872
7873Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7874 CXString cursorName = clang_getCursorDisplayName(cursor);
7875 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7876 clang_disposeString(cursorName);
7877 return *this;
7878}
7879
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007880Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7881 CXFile File;
7882 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007883 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007884 CXString FileName = clang_getFileName(File);
7885 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7886 clang_disposeString(FileName);
7887 return *this;
7888}
7889
7890Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7891 CXSourceLocation BLoc = clang_getRangeStart(range);
7892 CXSourceLocation ELoc = clang_getRangeEnd(range);
7893
7894 CXFile BFile;
7895 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007896 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007897
7898 CXFile EFile;
7899 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007900 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007901
7902 CXString BFileName = clang_getFileName(BFile);
7903 if (BFile == EFile) {
7904 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7905 BLine, BColumn, ELine, EColumn);
7906 } else {
7907 CXString EFileName = clang_getFileName(EFile);
7908 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7909 BLine, BColumn)
7910 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7911 ELine, EColumn);
7912 clang_disposeString(EFileName);
7913 }
7914 clang_disposeString(BFileName);
7915 return *this;
7916}
7917
7918Logger &cxindex::Logger::operator<<(CXString Str) {
7919 *this << clang_getCString(Str);
7920 return *this;
7921}
7922
7923Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7924 LogOS << Fmt;
7925 return *this;
7926}
7927
Chandler Carruth37ad2582014-06-27 15:14:39 +00007928static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7929
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007930cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007931 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007932
7933 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7934
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007935 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007936 OS << "[libclang:" << Name << ':';
7937
Alp Toker1a86ad22014-07-06 06:24:00 +00007938#ifdef USE_DARWIN_THREADS
7939 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007940 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7941 OS << tid << ':';
7942#endif
7943
7944 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7945 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007946 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007947
7948 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007949 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007950 OS << "--------------------------------------------------\n";
7951 }
7952}